blob: 4a9d04e85493c56c5bb4aece296a29c800ed604d [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
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200202 if (len < 3)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200203 goto kill_it;
204
205 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200206 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200207 return; /* OK no problem */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200208
209 /* We have a clear heartbleed attack (CVE-2014-0160), the
210 * advertised payload is larger than the advertised packet
211 * length, so we have garbage in the buffer between the
212 * payload and the end of the buffer (p+len). We can't know
213 * if the SSL stack is patched, and we don't know if we can
214 * safely wipe out the area between p+3+len and payload.
215 * So instead, we prevent the response from being sent by
216 * setting the max_send_fragment to 0 and we report an SSL
217 * error, which will kill this connection. It will be reported
218 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200219 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
220 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200221 kill_it:
222 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200223 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
224 return;
225 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200226#endif
227}
228
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200229#ifdef OPENSSL_NPN_NEGOTIATED
230/* This callback is used so that the server advertises the list of
231 * negociable protocols for NPN.
232 */
233static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
234 unsigned int *len, void *arg)
235{
236 struct bind_conf *conf = arg;
237
238 *data = (const unsigned char *)conf->npn_str;
239 *len = conf->npn_len;
240 return SSL_TLSEXT_ERR_OK;
241}
242#endif
243
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100244#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200245/* This callback is used so that the server advertises the list of
246 * negociable protocols for ALPN.
247 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100248static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
249 unsigned char *outlen,
250 const unsigned char *server,
251 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200252{
253 struct bind_conf *conf = arg;
254
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100255 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
256 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
257 return SSL_TLSEXT_ERR_NOACK;
258 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200259 return SSL_TLSEXT_ERR_OK;
260}
261#endif
262
Emeric Brunfc0421f2012-09-07 17:30:07 +0200263#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
264/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
265 * warning when no match is found, which implies the default (first) cert
266 * will keep being used.
267 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200268static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200269{
270 const char *servername;
271 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200272 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200273 int i;
274 (void)al; /* shut gcc stupid warning */
275
276 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100277 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200278 return (s->strict_sni ?
279 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200280 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100281 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200282
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100283 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200284 if (!servername[i])
285 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100286 trash.str[i] = tolower(servername[i]);
287 if (!wildp && (trash.str[i] == '.'))
288 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200289 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100290 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200291
292 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100293 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200294
295 /* lookup a not neg filter */
296 for (n = node; n; n = ebmb_next_dup(n)) {
297 if (!container_of(n, struct sni_ctx, name)->neg) {
298 node = n;
299 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100300 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200301 }
302 if (!node && wildp) {
303 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200304 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200305 }
306 if (!node || container_of(node, struct sni_ctx, name)->neg) {
307 return (s->strict_sni ?
308 SSL_TLSEXT_ERR_ALERT_FATAL :
309 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200310 }
311
312 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200313 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200314 return SSL_TLSEXT_ERR_OK;
315}
316#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
317
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200318#ifndef OPENSSL_NO_DH
319/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
320 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +0200321int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200322{
323 int ret = -1;
324 BIO *in;
325 DH *dh = NULL;
Willy Tarreau6e774b42014-04-25 21:35:23 +0200326 /* If not present, use parameters generated using 'openssl dhparam 1024 -C':
327 * -----BEGIN DH PARAMETERS-----
328 * MIGHAoGBAJJAJDXDoS5E03MNjnjK36eOL1tRqVa/9NuOVlI+lpXmPjJQbP65EvKn
329 * fSLnG7VMhoCJO4KtG88zf393ltP7loGB2bofcDSr+x+XsxBM8yA/Zj6BmQt+CQ9s
330 * TF7hoOV+wXTT6ErZ5y5qx9pq6hLfKXwTGFT78hrE6HnCO7xgtPdTAgEC
331 * -----END DH PARAMETERS-----
332 */
333 static const unsigned char dh1024_p[] = {
334 0x92, 0x40, 0x24, 0x35, 0xC3, 0xA1, 0x2E, 0x44, 0xD3, 0x73, 0x0D, 0x8E,
335 0x78, 0xCA, 0xDF, 0xA7, 0x8E, 0x2F, 0x5B, 0x51, 0xA9, 0x56, 0xBF, 0xF4,
336 0xDB, 0x8E, 0x56, 0x52, 0x3E, 0x96, 0x95, 0xE6, 0x3E, 0x32, 0x50, 0x6C,
337 0xFE, 0xB9, 0x12, 0xF2, 0xA7, 0x7D, 0x22, 0xE7, 0x1B, 0xB5, 0x4C, 0x86,
338 0x80, 0x89, 0x3B, 0x82, 0xAD, 0x1B, 0xCF, 0x33, 0x7F, 0x7F, 0x77, 0x96,
339 0xD3, 0xFB, 0x96, 0x81, 0x81, 0xD9, 0xBA, 0x1F, 0x70, 0x34, 0xAB, 0xFB,
340 0x1F, 0x97, 0xB3, 0x10, 0x4C, 0xF3, 0x20, 0x3F, 0x66, 0x3E, 0x81, 0x99,
341 0x0B, 0x7E, 0x09, 0x0F, 0x6C, 0x4C, 0x5E, 0xE1, 0xA0, 0xE5, 0x7E, 0xC1,
342 0x74, 0xD3, 0xE8, 0x4A, 0xD9, 0xE7, 0x2E, 0x6A, 0xC7, 0xDA, 0x6A, 0xEA,
343 0x12, 0xDF, 0x29, 0x7C, 0x13, 0x18, 0x54, 0xFB, 0xF2, 0x1A, 0xC4, 0xE8,
344 0x79, 0xC2, 0x3B, 0xBC, 0x60, 0xB4, 0xF7, 0x53,
345 };
346 static const unsigned char dh1024_g[] = {
347 0x02,
348 };
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200349
350 in = BIO_new(BIO_s_file());
351 if (in == NULL)
352 goto end;
353
354 if (BIO_read_filename(in, file) <= 0)
355 goto end;
356
357 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Willy Tarreau6e774b42014-04-25 21:35:23 +0200358 if (!dh) {
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200359 /* Clear openssl global errors stack */
360 ERR_clear_error();
361
Willy Tarreau6e774b42014-04-25 21:35:23 +0200362 dh = DH_new();
363 if (dh == NULL)
364 goto end;
365
366 dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
367 if (dh->p == NULL)
368 goto end;
369
370 dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
371 if (dh->g == NULL)
372 goto end;
373
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200374 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200375 }
Willy Tarreau6e774b42014-04-25 21:35:23 +0200376 else
377 ret = 1;
378
379 SSL_CTX_set_tmp_dh(ctx, dh);
Emeric Brun644cde02012-12-14 11:21:13 +0100380
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200381end:
382 if (dh)
383 DH_free(dh);
384
385 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200386 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200387
388 return ret;
389}
390#endif
391
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200392static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100393{
394 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200395 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100396
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200397 if (*name == '!') {
398 neg = 1;
399 name++;
400 }
401 if (*name == '*') {
402 wild = 1;
403 name++;
404 }
405 /* !* filter is a nop */
406 if (neg && wild)
407 return order;
408 if (*name) {
409 int j, len;
410 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100411 sc = malloc(sizeof(struct sni_ctx) + len + 1);
412 for (j = 0; j < len; j++)
413 sc->name.key[j] = tolower(name[j]);
414 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100415 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200416 sc->order = order++;
417 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100418 if (wild)
419 ebst_insert(&s->sni_w_ctx, &sc->name);
420 else
421 ebst_insert(&s->sni_ctx, &sc->name);
422 }
423 return order;
424}
425
Emeric Brunfc0421f2012-09-07 17:30:07 +0200426/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
427 * an early error happens and the caller must call SSL_CTX_free() by itelf.
428 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200429static 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 +0200430{
431 BIO *in;
432 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200433 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200434 int ret = -1;
435 int order = 0;
436 X509_NAME *xname;
437 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200438#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
439 STACK_OF(GENERAL_NAME) *names;
440#endif
441
442 in = BIO_new(BIO_s_file());
443 if (in == NULL)
444 goto end;
445
446 if (BIO_read_filename(in, file) <= 0)
447 goto end;
448
449 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
450 if (x == NULL)
451 goto end;
452
Emeric Brun50bcecc2013-04-22 13:05:23 +0200453 if (fcount) {
454 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200455 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100456 }
457 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200458#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100459 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
460 if (names) {
461 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
462 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
463 if (name->type == GEN_DNS) {
464 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200465 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100466 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200467 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200468 }
469 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100470 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200471 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200472#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100473 xname = X509_get_subject_name(x);
474 i = -1;
475 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
476 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
477 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200478 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100479 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200480 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200481 }
482 }
483
484 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
485 if (!SSL_CTX_use_certificate(ctx, x))
486 goto end;
487
488 if (ctx->extra_certs != NULL) {
489 sk_X509_pop_free(ctx->extra_certs, X509_free);
490 ctx->extra_certs = NULL;
491 }
492
493 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
494 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
495 X509_free(ca);
496 goto end;
497 }
498 }
499
500 err = ERR_get_error();
501 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
502 /* we successfully reached the last cert in the file */
503 ret = 1;
504 }
505 ERR_clear_error();
506
507end:
508 if (x)
509 X509_free(x);
510
511 if (in)
512 BIO_free(in);
513
514 return ret;
515}
516
Emeric Brun50bcecc2013-04-22 13:05:23 +0200517static 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 +0200518{
519 int ret;
520 SSL_CTX *ctx;
521
522 ctx = SSL_CTX_new(SSLv23_server_method());
523 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200524 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
525 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200526 return 1;
527 }
528
529 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200530 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
531 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200532 SSL_CTX_free(ctx);
533 return 1;
534 }
535
Emeric Brun50bcecc2013-04-22 13:05:23 +0200536 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200537 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200538 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
539 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200540 if (ret < 0) /* serious error, must do that ourselves */
541 SSL_CTX_free(ctx);
542 return 1;
543 }
Emeric Brun61694ab2012-10-26 13:35:33 +0200544
545 if (SSL_CTX_check_private_key(ctx) <= 0) {
546 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
547 err && *err ? *err : "", path);
548 return 1;
549 }
550
Emeric Brunfc0421f2012-09-07 17:30:07 +0200551 /* we must not free the SSL_CTX anymore below, since it's already in
552 * the tree, so it will be discovered and cleaned in time.
553 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200554#ifndef OPENSSL_NO_DH
555 ret = ssl_sock_load_dh_params(ctx, path);
556 if (ret < 0) {
557 if (err)
558 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
559 *err ? *err : "", path);
560 return 1;
561 }
562#endif
563
Emeric Brunfc0421f2012-09-07 17:30:07 +0200564#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200565 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200566 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
567 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +0200568 return 1;
569 }
570#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200571 if (!bind_conf->default_ctx)
572 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200573
574 return 0;
575}
576
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200577int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200578{
579 struct dirent *de;
580 DIR *dir;
581 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +0100582 char *end;
583 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200584 int cfgerr = 0;
585
586 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +0200587 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200588
589 /* strip trailing slashes, including first one */
590 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
591 *end = 0;
592
Emeric Brunfc0421f2012-09-07 17:30:07 +0200593 while ((de = readdir(dir))) {
Willy Tarreauee2663b2012-12-06 11:36:59 +0100594 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200595 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200596 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
597 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +0200598 cfgerr++;
599 continue;
600 }
601 if (!S_ISREG(buf.st_mode))
602 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200603 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200604 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200605 closedir(dir);
606 return cfgerr;
607}
608
Thierry Fournier383085f2013-01-24 14:15:43 +0100609/* Make sure openssl opens /dev/urandom before the chroot. The work is only
610 * done once. Zero is returned if the operation fails. No error is returned
611 * if the random is said as not implemented, because we expect that openssl
612 * will use another method once needed.
613 */
614static int ssl_initialize_random()
615{
616 unsigned char random;
617 static int random_initialized = 0;
618
619 if (!random_initialized && RAND_bytes(&random, 1) != 0)
620 random_initialized = 1;
621
622 return random_initialized;
623}
624
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100625int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
626{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200627 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100628 FILE *f;
629 int linenum = 0;
630 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100631
Willy Tarreauad1731d2013-04-02 17:35:58 +0200632 if ((f = fopen(file, "r")) == NULL) {
633 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100634 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200635 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100636
637 while (fgets(thisline, sizeof(thisline), f) != NULL) {
638 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200639 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100640 char *end;
641 char *args[MAX_LINE_ARGS + 1];
642 char *line = thisline;
643
644 linenum++;
645 end = line + strlen(line);
646 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
647 /* Check if we reached the limit and the last char is not \n.
648 * Watch out for the last line without the terminating '\n'!
649 */
Willy Tarreauad1731d2013-04-02 17:35:58 +0200650 memprintf(err, "line %d too long in file '%s', limit is %d characters",
651 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100652 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200653 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100654 }
655
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100656 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200657 newarg = 1;
658 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100659 if (*line == '#' || *line == '\n' || *line == '\r') {
660 /* end of string, end of loop */
661 *line = 0;
662 break;
663 }
664 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +0200665 newarg = 1;
666 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100667 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200668 else if (newarg) {
669 if (arg == MAX_LINE_ARGS) {
670 memprintf(err, "too many args on line %d in file '%s'.",
671 linenum, file);
672 cfgerr = 1;
673 break;
674 }
675 newarg = 0;
676 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100677 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200678 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100679 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200680 if (cfgerr)
681 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200682
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100683 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +0200684 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100685 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100686
Emeric Brun50bcecc2013-04-22 13:05:23 +0200687 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +0200688 if (cfgerr) {
689 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100690 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200691 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100692 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100693 fclose(f);
694 return cfgerr;
695}
696
Emeric Brunfc0421f2012-09-07 17:30:07 +0200697#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
698#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
699#endif
700
701#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
702#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +0100703#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +0200704#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200705#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
706#define SSL_OP_SINGLE_ECDH_USE 0
707#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +0200708#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
709#define SSL_OP_NO_TICKET 0
710#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200711#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
712#define SSL_OP_NO_COMPRESSION 0
713#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +0200714#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
715#define SSL_OP_NO_TLSv1_1 0
716#endif
717#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
718#define SSL_OP_NO_TLSv1_2 0
719#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200720#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
721#define SSL_OP_SINGLE_DH_USE 0
722#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200723#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
724#define SSL_OP_SINGLE_ECDH_USE 0
725#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200726#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
727#define SSL_MODE_RELEASE_BUFFERS 0
728#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200729int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200730{
731 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +0100732 int verify = SSL_VERIFY_NONE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200733 int ssloptions =
734 SSL_OP_ALL | /* all known workarounds for bugs */
735 SSL_OP_NO_SSLv2 |
736 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200737 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +0200738 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +0200739 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
740 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200741 int sslmode =
742 SSL_MODE_ENABLE_PARTIAL_WRITE |
743 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
744 SSL_MODE_RELEASE_BUFFERS;
745
Thierry Fournier383085f2013-01-24 14:15:43 +0100746 /* Make sure openssl opens /dev/urandom before the chroot */
747 if (!ssl_initialize_random()) {
748 Alert("OpenSSL random data generator initialization failed.\n");
749 cfgerr++;
750 }
751
Emeric Brun89675492012-10-05 13:48:26 +0200752 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200753 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +0200754 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200755 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +0200756 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200757 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +0200758 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200759 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +0200760 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +0200761 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +0200762 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
763 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
764 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
765 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
766#if SSL_OP_NO_TLSv1_1
767 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
768 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
769#endif
770#if SSL_OP_NO_TLSv1_2
771 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
772 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
773#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200774
775 SSL_CTX_set_options(ctx, ssloptions);
776 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +0100777 switch (bind_conf->verify) {
778 case SSL_SOCK_VERIFY_NONE:
779 verify = SSL_VERIFY_NONE;
780 break;
781 case SSL_SOCK_VERIFY_OPTIONAL:
782 verify = SSL_VERIFY_PEER;
783 break;
784 case SSL_SOCK_VERIFY_REQUIRED:
785 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
786 break;
787 }
788 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
789 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +0200790 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200791 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200792 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200793 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200794 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200795 cfgerr++;
796 }
797 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200798 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +0200799 }
Emeric Brun850efd52014-01-29 12:24:34 +0100800 else {
801 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
802 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
803 cfgerr++;
804 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200805#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +0200806 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200807 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
808
Emeric Brunfb510ea2012-10-05 12:00:26 +0200809 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200810 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200811 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200812 cfgerr++;
813 }
Emeric Brun561e5742012-10-02 15:20:55 +0200814 else {
815 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
816 }
Emeric Brund94b3fe2012-09-20 18:23:56 +0200817 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200818#endif
Emeric Brun644cde02012-12-14 11:21:13 +0100819 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +0200820 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200821
Emeric Brun4f65bff2012-11-16 15:11:00 +0100822 if (global.tune.ssllifetime)
823 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
824
Emeric Brunfc0421f2012-09-07 17:30:07 +0200825 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200826 if (bind_conf->ciphers &&
827 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200828 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 +0200829 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200830 cfgerr++;
831 }
832
833 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Emeric Brun29f037d2014-04-25 19:05:36 +0200834 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
835
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200836#ifdef OPENSSL_NPN_NEGOTIATED
837 if (bind_conf->npn_str)
838 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
839#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100840#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200841 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100842 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +0200843#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200844
Emeric Brunfc0421f2012-09-07 17:30:07 +0200845#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
846 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200847 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200848#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200849#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +0100850 {
Emeric Brun2b58d042012-09-20 17:10:03 +0200851 int i;
852 EC_KEY *ecdh;
853
Emeric Brun6924ef82013-03-06 14:08:53 +0100854 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +0200855 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
856 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 +0100857 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
858 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +0200859 cfgerr++;
860 }
861 else {
862 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
863 EC_KEY_free(ecdh);
864 }
865 }
866#endif
867
Emeric Brunfc0421f2012-09-07 17:30:07 +0200868 return cfgerr;
869}
870
Evan Broderbe554312013-06-27 00:05:25 -0700871static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
872{
873 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
874 size_t prefixlen, suffixlen;
875
876 /* Trivial case */
877 if (strcmp(pattern, hostname) == 0)
878 return 1;
879
Evan Broderbe554312013-06-27 00:05:25 -0700880 /* The rest of this logic is based on RFC 6125, section 6.4.3
881 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
882
Emeric Bruna848dae2013-10-08 11:27:28 +0200883 pattern_wildcard = NULL;
884 pattern_left_label_end = pattern;
885 while (*pattern_left_label_end != '.') {
886 switch (*pattern_left_label_end) {
887 case 0:
888 /* End of label not found */
889 return 0;
890 case '*':
891 /* If there is more than one wildcards */
892 if (pattern_wildcard)
893 return 0;
894 pattern_wildcard = pattern_left_label_end;
895 break;
896 }
897 pattern_left_label_end++;
898 }
899
900 /* If it's not trivial and there is no wildcard, it can't
901 * match */
902 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -0700903 return 0;
904
905 /* Make sure all labels match except the leftmost */
906 hostname_left_label_end = strchr(hostname, '.');
907 if (!hostname_left_label_end
908 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
909 return 0;
910
911 /* Make sure the leftmost label of the hostname is long enough
912 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +0200913 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -0700914 return 0;
915
916 /* Finally compare the string on either side of the
917 * wildcard */
918 prefixlen = pattern_wildcard - pattern;
919 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +0200920 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
921 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -0700922 return 0;
923
924 return 1;
925}
926
927static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
928{
929 SSL *ssl;
930 struct connection *conn;
931 char *servername;
932
933 int depth;
934 X509 *cert;
935 STACK_OF(GENERAL_NAME) *alt_names;
936 int i;
937 X509_NAME *cert_subject;
938 char *str;
939
940 if (ok == 0)
941 return ok;
942
943 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
944 conn = (struct connection *)SSL_get_app_data(ssl);
945
946 servername = objt_server(conn->target)->ssl_ctx.verify_host;
947
948 /* We only need to verify the CN on the actual server cert,
949 * not the indirect CAs */
950 depth = X509_STORE_CTX_get_error_depth(ctx);
951 if (depth != 0)
952 return ok;
953
954 /* At this point, the cert is *not* OK unless we can find a
955 * hostname match */
956 ok = 0;
957
958 cert = X509_STORE_CTX_get_current_cert(ctx);
959 /* It seems like this might happen if verify peer isn't set */
960 if (!cert)
961 return ok;
962
963 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
964 if (alt_names) {
965 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
966 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
967 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200968#if OPENSSL_VERSION_NUMBER < 0x00907000L
969 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
970#else
Evan Broderbe554312013-06-27 00:05:25 -0700971 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200972#endif
Evan Broderbe554312013-06-27 00:05:25 -0700973 ok = ssl_sock_srv_hostcheck(str, servername);
974 OPENSSL_free(str);
975 }
976 }
977 }
Emeric Brun4ad50a42013-09-17 15:19:54 +0200978 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -0700979 }
980
981 cert_subject = X509_get_subject_name(cert);
982 i = -1;
983 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
984 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
985 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
986 ok = ssl_sock_srv_hostcheck(str, servername);
987 OPENSSL_free(str);
988 }
989 }
990
991 return ok;
992}
993
Emeric Brun94324a42012-10-11 14:00:19 +0200994/* prepare ssl context from servers options. Returns an error count */
995int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
996{
997 int cfgerr = 0;
998 int options =
999 SSL_OP_ALL | /* all known workarounds for bugs */
1000 SSL_OP_NO_SSLv2 |
1001 SSL_OP_NO_COMPRESSION;
1002 int mode =
1003 SSL_MODE_ENABLE_PARTIAL_WRITE |
1004 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1005 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001006 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001007
Thierry Fournier383085f2013-01-24 14:15:43 +01001008 /* Make sure openssl opens /dev/urandom before the chroot */
1009 if (!ssl_initialize_random()) {
1010 Alert("OpenSSL random data generator initialization failed.\n");
1011 cfgerr++;
1012 }
1013
Emeric Brun94324a42012-10-11 14:00:19 +02001014 /* Initiate SSL context for current server */
1015 srv->ssl_ctx.reused_sess = NULL;
1016 if (srv->use_ssl)
1017 srv->xprt = &ssl_sock;
1018 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001019 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001020
1021 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1022 if (!srv->ssl_ctx.ctx) {
1023 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1024 proxy_type_str(curproxy), curproxy->id,
1025 srv->id);
1026 cfgerr++;
1027 return cfgerr;
1028 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001029 if (srv->ssl_ctx.client_crt) {
1030 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1031 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1032 proxy_type_str(curproxy), curproxy->id,
1033 srv->id, srv->ssl_ctx.client_crt);
1034 cfgerr++;
1035 }
1036 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1037 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1038 proxy_type_str(curproxy), curproxy->id,
1039 srv->id, srv->ssl_ctx.client_crt);
1040 cfgerr++;
1041 }
1042 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1043 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1044 proxy_type_str(curproxy), curproxy->id,
1045 srv->id, srv->ssl_ctx.client_crt);
1046 cfgerr++;
1047 }
1048 }
Emeric Brun94324a42012-10-11 14:00:19 +02001049
1050 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1051 options |= SSL_OP_NO_SSLv3;
1052 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1053 options |= SSL_OP_NO_TLSv1;
1054 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1055 options |= SSL_OP_NO_TLSv1_1;
1056 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1057 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001058 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1059 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001060 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1061 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1062 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1063 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1064#if SSL_OP_NO_TLSv1_1
1065 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1066 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1067#endif
1068#if SSL_OP_NO_TLSv1_2
1069 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1070 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1071#endif
1072
1073 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1074 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001075
1076 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1077 verify = SSL_VERIFY_PEER;
1078
1079 switch (srv->ssl_ctx.verify) {
1080 case SSL_SOCK_VERIFY_NONE:
1081 verify = SSL_VERIFY_NONE;
1082 break;
1083 case SSL_SOCK_VERIFY_REQUIRED:
1084 verify = SSL_VERIFY_PEER;
1085 break;
1086 }
Evan Broderbe554312013-06-27 00:05:25 -07001087 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001088 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001089 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001090 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001091 if (srv->ssl_ctx.ca_file) {
1092 /* load CAfile to verify */
1093 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001094 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001095 curproxy->id, srv->id,
1096 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1097 cfgerr++;
1098 }
1099 }
Emeric Brun850efd52014-01-29 12:24:34 +01001100 else {
1101 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001102 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 +01001103 curproxy->id, srv->id,
1104 srv->conf.file, srv->conf.line);
1105 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001106 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001107 curproxy->id, srv->id,
1108 srv->conf.file, srv->conf.line);
1109 cfgerr++;
1110 }
Emeric Brunef42d922012-10-11 16:11:36 +02001111#ifdef X509_V_FLAG_CRL_CHECK
1112 if (srv->ssl_ctx.crl_file) {
1113 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1114
1115 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001116 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001117 curproxy->id, srv->id,
1118 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1119 cfgerr++;
1120 }
1121 else {
1122 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1123 }
1124 }
1125#endif
1126 }
1127
Emeric Brun4f65bff2012-11-16 15:11:00 +01001128 if (global.tune.ssllifetime)
1129 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1130
Emeric Brun94324a42012-10-11 14:00:19 +02001131 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1132 if (srv->ssl_ctx.ciphers &&
1133 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1134 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1135 curproxy->id, srv->id,
1136 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1137 cfgerr++;
1138 }
1139
1140 return cfgerr;
1141}
1142
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001143/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001144 * be NULL, in which case nothing is done. Returns the number of errors
1145 * encountered.
1146 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001147int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001148{
1149 struct ebmb_node *node;
1150 struct sni_ctx *sni;
1151 int err = 0;
1152
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001153 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001154 return 0;
1155
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001156 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001157 while (node) {
1158 sni = ebmb_entry(node, struct sni_ctx, name);
1159 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001160 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001161 node = ebmb_next(node);
1162 }
1163
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001164 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001165 while (node) {
1166 sni = ebmb_entry(node, struct sni_ctx, name);
1167 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001168 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001169 node = ebmb_next(node);
1170 }
1171 return err;
1172}
1173
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001174/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001175 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1176 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001177void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001178{
1179 struct ebmb_node *node, *back;
1180 struct sni_ctx *sni;
1181
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001182 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001183 return;
1184
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001185 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001186 while (node) {
1187 sni = ebmb_entry(node, struct sni_ctx, name);
1188 back = ebmb_next(node);
1189 ebmb_delete(node);
1190 if (!sni->order) /* only free the CTX on its first occurrence */
1191 SSL_CTX_free(sni->ctx);
1192 free(sni);
1193 node = back;
1194 }
1195
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001196 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001197 while (node) {
1198 sni = ebmb_entry(node, struct sni_ctx, name);
1199 back = ebmb_next(node);
1200 ebmb_delete(node);
1201 if (!sni->order) /* only free the CTX on its first occurrence */
1202 SSL_CTX_free(sni->ctx);
1203 free(sni);
1204 node = back;
1205 }
1206
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001207 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001208}
1209
Emeric Brun46591952012-05-18 15:47:34 +02001210/*
1211 * This function is called if SSL * context is not yet allocated. The function
1212 * is designed to be called before any other data-layer operation and sets the
1213 * handshake flag on the connection. It is safe to call it multiple times.
1214 * It returns 0 on success and -1 in error case.
1215 */
1216static int ssl_sock_init(struct connection *conn)
1217{
1218 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001219 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001220 return 0;
1221
Willy Tarreau3c728722014-01-23 13:50:42 +01001222 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001223 return 0;
1224
Willy Tarreau20879a02012-12-03 16:32:10 +01001225 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1226 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001227 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001228 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001229
Emeric Brun46591952012-05-18 15:47:34 +02001230 /* If it is in client mode initiate SSL session
1231 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001232 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001233 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001234 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001235 if (!conn->xprt_ctx) {
1236 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001237 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001238 }
Emeric Brun46591952012-05-18 15:47:34 +02001239
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001240 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001241 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1242 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001243
1244 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001245 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001246
Evan Broderbe554312013-06-27 00:05:25 -07001247 /* set connection pointer */
1248 SSL_set_app_data(conn->xprt_ctx, conn);
1249
Emeric Brun46591952012-05-18 15:47:34 +02001250 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001251 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001252
1253 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001254 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001255 return 0;
1256 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001257 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001258 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001259 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001260 if (!conn->xprt_ctx) {
1261 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001262 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001263 }
Emeric Brun46591952012-05-18 15:47:34 +02001264
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001265 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001266
1267 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001268 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001269
Emeric Brune1f38db2012-09-03 20:36:47 +02001270 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001271 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02001272
Emeric Brun46591952012-05-18 15:47:34 +02001273 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001274 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001275
1276 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001277 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001278 return 0;
1279 }
1280 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01001281 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02001282 return -1;
1283}
1284
1285
1286/* This is the callback which is used when an SSL handshake is pending. It
1287 * updates the FD status if it wants some polling before being called again.
1288 * It returns 0 if it fails in a fatal way or needs to poll to go further,
1289 * otherwise it returns non-zero and removes itself from the connection's
1290 * flags (the bit is provided in <flag> by the caller).
1291 */
1292int ssl_sock_handshake(struct connection *conn, unsigned int flag)
1293{
1294 int ret;
1295
Willy Tarreau3c728722014-01-23 13:50:42 +01001296 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001297 return 0;
1298
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001299 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001300 goto out_error;
1301
Emeric Brun674b7432012-11-08 19:21:55 +01001302 /* If we use SSL_do_handshake to process a reneg initiated by
1303 * the remote peer, it sometimes returns SSL_ERROR_SSL.
1304 * Usually SSL_write and SSL_read are used and process implicitly
1305 * the reneg handshake.
1306 * Here we use SSL_peek as a workaround for reneg.
1307 */
1308 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
1309 char c;
1310
1311 ret = SSL_peek(conn->xprt_ctx, &c, 1);
1312 if (ret <= 0) {
1313 /* handshake may have not been completed, let's find why */
1314 ret = SSL_get_error(conn->xprt_ctx, ret);
1315 if (ret == SSL_ERROR_WANT_WRITE) {
1316 /* SSL handshake needs to write, L4 connection may not be ready */
1317 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001318 __conn_sock_want_send(conn);
1319 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001320 return 0;
1321 }
1322 else if (ret == SSL_ERROR_WANT_READ) {
1323 /* handshake may have been completed but we have
1324 * no more data to read.
1325 */
1326 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
1327 ret = 1;
1328 goto reneg_ok;
1329 }
1330 /* SSL handshake needs to read, L4 connection is ready */
1331 if (conn->flags & CO_FL_WAIT_L4_CONN)
1332 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1333 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001334 __conn_sock_want_recv(conn);
1335 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001336 return 0;
1337 }
1338 else if (ret == SSL_ERROR_SYSCALL) {
1339 /* if errno is null, then connection was successfully established */
1340 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1341 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001342 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02001343 if (!((SSL *)conn->xprt_ctx)->packet_length) {
1344 if (!errno) {
1345 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1346 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1347 else
1348 conn->err_code = CO_ER_SSL_EMPTY;
1349 }
1350 else {
1351 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1352 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1353 else
1354 conn->err_code = CO_ER_SSL_ABORT;
1355 }
1356 }
1357 else {
1358 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1359 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01001360 else
Emeric Brun29f037d2014-04-25 19:05:36 +02001361 conn->err_code = CO_ER_SSL_HANDSHAKE;
1362 }
Willy Tarreau20879a02012-12-03 16:32:10 +01001363 }
Emeric Brun674b7432012-11-08 19:21:55 +01001364 goto out_error;
1365 }
1366 else {
1367 /* Fail on all other handshake errors */
1368 /* Note: OpenSSL may leave unread bytes in the socket's
1369 * buffer, causing an RST to be emitted upon close() on
1370 * TCP sockets. We first try to drain possibly pending
1371 * data to avoid this as much as possible.
1372 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001373 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001374 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001375 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
1376 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01001377 goto out_error;
1378 }
1379 }
1380 /* read some data: consider handshake completed */
1381 goto reneg_ok;
1382 }
1383
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001384 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001385 if (ret != 1) {
1386 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001387 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001388
1389 if (ret == SSL_ERROR_WANT_WRITE) {
1390 /* SSL handshake needs to write, L4 connection may not be ready */
1391 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001392 __conn_sock_want_send(conn);
1393 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001394 return 0;
1395 }
1396 else if (ret == SSL_ERROR_WANT_READ) {
1397 /* SSL handshake needs to read, L4 connection is ready */
1398 if (conn->flags & CO_FL_WAIT_L4_CONN)
1399 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1400 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001401 __conn_sock_want_recv(conn);
1402 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001403 return 0;
1404 }
Willy Tarreau89230192012-09-28 20:22:13 +02001405 else if (ret == SSL_ERROR_SYSCALL) {
1406 /* if errno is null, then connection was successfully established */
1407 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1408 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001409
Emeric Brun29f037d2014-04-25 19:05:36 +02001410 if (!((SSL *)conn->xprt_ctx)->packet_length) {
1411 if (!errno) {
1412 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1413 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1414 else
1415 conn->err_code = CO_ER_SSL_EMPTY;
1416 }
1417 else {
1418 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1419 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1420 else
1421 conn->err_code = CO_ER_SSL_ABORT;
1422 }
1423 }
1424 else {
1425 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1426 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01001427 else
Emeric Brun29f037d2014-04-25 19:05:36 +02001428 conn->err_code = CO_ER_SSL_HANDSHAKE;
1429 }
Willy Tarreau89230192012-09-28 20:22:13 +02001430 goto out_error;
1431 }
Emeric Brun46591952012-05-18 15:47:34 +02001432 else {
1433 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02001434 /* Note: OpenSSL may leave unread bytes in the socket's
1435 * buffer, causing an RST to be emitted upon close() on
1436 * TCP sockets. We first try to drain possibly pending
1437 * data to avoid this as much as possible.
1438 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001439 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001440 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001441 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
1442 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001443 goto out_error;
1444 }
1445 }
1446
Emeric Brun674b7432012-11-08 19:21:55 +01001447reneg_ok:
1448
Emeric Brun46591952012-05-18 15:47:34 +02001449 /* Handshake succeeded */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001450 if (objt_server(conn->target)) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001451 if (!SSL_session_reused(conn->xprt_ctx)) {
Emeric Brun46591952012-05-18 15:47:34 +02001452 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001453 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1454 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001455
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001456 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001457 }
1458 }
1459
1460 /* The connection is now established at both layers, it's time to leave */
1461 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
1462 return 1;
1463
1464 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001465 /* Clear openssl global errors stack */
1466 ERR_clear_error();
1467
Emeric Brun9fa89732012-10-04 17:09:56 +02001468 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001469 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
1470 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
1471 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02001472 }
1473
Emeric Brun46591952012-05-18 15:47:34 +02001474 /* Fail on all other handshake errors */
1475 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001476 if (!conn->err_code)
1477 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001478 return 0;
1479}
1480
1481/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01001482 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02001483 * buffer wraps, in which case a second call may be performed. The connection's
1484 * flags are updated with whatever special event is detected (error, read0,
1485 * empty). The caller is responsible for taking care of those events and
1486 * avoiding the call if inappropriate. The function does not call the
1487 * connection's polling update function, so the caller is responsible for this.
1488 */
1489static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
1490{
1491 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01001492 int try;
Emeric Brun46591952012-05-18 15:47:34 +02001493
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001494 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001495 goto out_error;
1496
1497 if (conn->flags & CO_FL_HANDSHAKE)
1498 /* a handshake was requested */
1499 return 0;
1500
Willy Tarreauabf08d92014-01-14 11:31:27 +01001501 /* let's realign the buffer to optimize I/O */
1502 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02001503 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02001504
1505 /* read the largest possible block. For this, we perform only one call
1506 * to recv() unless the buffer wraps and we exactly fill the first hunk,
1507 * in which case we accept to do it once again. A new attempt is made on
1508 * EINTR too.
1509 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01001510 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01001511 /* first check if we have some room after p+i */
1512 try = buf->data + buf->size - (buf->p + buf->i);
1513 /* otherwise continue between data and p-o */
1514 if (try <= 0) {
1515 try = buf->p - (buf->data + buf->o);
1516 if (try <= 0)
1517 break;
1518 }
1519 if (try > count)
1520 try = count;
1521
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001522 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02001523 if (conn->flags & CO_FL_ERROR) {
1524 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001525 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001526 }
Emeric Brun46591952012-05-18 15:47:34 +02001527 if (ret > 0) {
1528 buf->i += ret;
1529 done += ret;
1530 if (ret < try)
1531 break;
1532 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02001533 }
1534 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01001535 ret = SSL_get_error(conn->xprt_ctx, ret);
1536 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01001537 /* error on protocol or underlying transport */
1538 if ((ret != SSL_ERROR_SYSCALL)
1539 || (errno && (errno != EAGAIN)))
1540 conn->flags |= CO_FL_ERROR;
1541
Emeric Brun644cde02012-12-14 11:21:13 +01001542 /* Clear openssl global errors stack */
1543 ERR_clear_error();
1544 }
Emeric Brun46591952012-05-18 15:47:34 +02001545 goto read0;
1546 }
1547 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001548 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001549 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001550 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02001551 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001552 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001553 break;
1554 }
1555 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001556 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1557 /* handshake is running, and it may need to re-enable read */
1558 conn->flags |= CO_FL_SSL_WAIT_HS;
1559 __conn_sock_want_recv(conn);
1560 break;
1561 }
Emeric Brun46591952012-05-18 15:47:34 +02001562 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001563 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001564 break;
1565 }
1566 /* otherwise it's a real error */
1567 goto out_error;
1568 }
1569 }
1570 return done;
1571
1572 read0:
1573 conn_sock_read0(conn);
1574 return done;
1575 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001576 /* Clear openssl global errors stack */
1577 ERR_clear_error();
1578
Emeric Brun46591952012-05-18 15:47:34 +02001579 conn->flags |= CO_FL_ERROR;
1580 return done;
1581}
1582
1583
1584/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01001585 * <flags> may contain some CO_SFL_* flags to hint the system about other
1586 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02001587 * Only one call to send() is performed, unless the buffer wraps, in which case
1588 * a second call may be performed. The connection's flags are updated with
1589 * whatever special event is detected (error, empty). The caller is responsible
1590 * for taking care of those events and avoiding the call if inappropriate. The
1591 * function does not call the connection's polling update function, so the caller
1592 * is responsible for this.
1593 */
1594static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
1595{
1596 int ret, try, done;
1597
1598 done = 0;
1599
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001600 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001601 goto out_error;
1602
1603 if (conn->flags & CO_FL_HANDSHAKE)
1604 /* a handshake was requested */
1605 return 0;
1606
1607 /* send the largest possible block. For this we perform only one call
1608 * to send() unless the buffer wraps and we exactly fill the first hunk,
1609 * in which case we accept to do it once again.
1610 */
1611 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07001612 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01001613
Willy Tarreau7bed9452014-02-02 02:00:24 +01001614 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01001615 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
1616 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01001617 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01001618 }
1619 else {
1620 /* we need to keep the information about the fact that
1621 * we're not limiting the upcoming send(), because if it
1622 * fails, we'll have to retry with at least as many data.
1623 */
1624 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
1625 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01001626
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001627 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01001628
Emeric Brune1f38db2012-09-03 20:36:47 +02001629 if (conn->flags & CO_FL_ERROR) {
1630 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001631 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001632 }
Emeric Brun46591952012-05-18 15:47:34 +02001633 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01001634 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
1635
Emeric Brun46591952012-05-18 15:47:34 +02001636 buf->o -= ret;
1637 done += ret;
1638
Willy Tarreau5fb38032012-12-16 19:39:09 +01001639 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02001640 /* optimize data alignment in the buffer */
1641 buf->p = buf->data;
1642
1643 /* if the system buffer is full, don't insist */
1644 if (ret < try)
1645 break;
1646 }
1647 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001648 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001649 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001650 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1651 /* handshake is running, and it may need to re-enable write */
1652 conn->flags |= CO_FL_SSL_WAIT_HS;
1653 __conn_sock_want_send(conn);
1654 break;
1655 }
Emeric Brun46591952012-05-18 15:47:34 +02001656 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001657 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001658 break;
1659 }
1660 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001661 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02001662 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001663 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001664 break;
1665 }
1666 goto out_error;
1667 }
1668 }
1669 return done;
1670
1671 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001672 /* Clear openssl global errors stack */
1673 ERR_clear_error();
1674
Emeric Brun46591952012-05-18 15:47:34 +02001675 conn->flags |= CO_FL_ERROR;
1676 return done;
1677}
1678
Emeric Brun46591952012-05-18 15:47:34 +02001679static void ssl_sock_close(struct connection *conn) {
1680
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001681 if (conn->xprt_ctx) {
1682 SSL_free(conn->xprt_ctx);
1683 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02001684 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02001685 }
Emeric Brun46591952012-05-18 15:47:34 +02001686}
1687
1688/* This function tries to perform a clean shutdown on an SSL connection, and in
1689 * any case, flags the connection as reusable if no handshake was in progress.
1690 */
1691static void ssl_sock_shutw(struct connection *conn, int clean)
1692{
1693 if (conn->flags & CO_FL_HANDSHAKE)
1694 return;
1695 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01001696 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
1697 /* Clear openssl global errors stack */
1698 ERR_clear_error();
1699 }
Emeric Brun46591952012-05-18 15:47:34 +02001700
1701 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001702 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02001703}
1704
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02001705/* used for logging, may be changed for a sample fetch later */
1706const char *ssl_sock_get_cipher_name(struct connection *conn)
1707{
1708 if (!conn->xprt && !conn->xprt_ctx)
1709 return NULL;
1710 return SSL_get_cipher_name(conn->xprt_ctx);
1711}
1712
1713/* used for logging, may be changed for a sample fetch later */
1714const char *ssl_sock_get_proto_version(struct connection *conn)
1715{
1716 if (!conn->xprt && !conn->xprt_ctx)
1717 return NULL;
1718 return SSL_get_version(conn->xprt_ctx);
1719}
1720
Willy Tarreau8d598402012-10-22 17:58:39 +02001721/* Extract a serial from a cert, and copy it to a chunk.
1722 * Returns 1 if serial is found and copied, 0 if no serial found and
1723 * -1 if output is not large enough.
1724 */
1725static int
1726ssl_sock_get_serial(X509 *crt, struct chunk *out)
1727{
1728 ASN1_INTEGER *serial;
1729
1730 serial = X509_get_serialNumber(crt);
1731 if (!serial)
1732 return 0;
1733
1734 if (out->size < serial->length)
1735 return -1;
1736
1737 memcpy(out->str, serial->data, serial->length);
1738 out->len = serial->length;
1739 return 1;
1740}
1741
Emeric Brunce5ad802012-10-22 14:11:22 +02001742
1743/* Copy Date in ASN1_UTCTIME format in struct chunk out.
1744 * Returns 1 if serial is found and copied, 0 if no valid time found
1745 * and -1 if output is not large enough.
1746 */
1747static int
1748ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
1749{
1750 if (tm->type == V_ASN1_GENERALIZEDTIME) {
1751 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
1752
1753 if (gentm->length < 12)
1754 return 0;
1755 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
1756 return 0;
1757 if (out->size < gentm->length-2)
1758 return -1;
1759
1760 memcpy(out->str, gentm->data+2, gentm->length-2);
1761 out->len = gentm->length-2;
1762 return 1;
1763 }
1764 else if (tm->type == V_ASN1_UTCTIME) {
1765 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
1766
1767 if (utctm->length < 10)
1768 return 0;
1769 if (utctm->data[0] >= 0x35)
1770 return 0;
1771 if (out->size < utctm->length)
1772 return -1;
1773
1774 memcpy(out->str, utctm->data, utctm->length);
1775 out->len = utctm->length;
1776 return 1;
1777 }
1778
1779 return 0;
1780}
1781
Emeric Brun87855892012-10-17 17:39:35 +02001782/* Extract an entry from a X509_NAME and copy its value to an output chunk.
1783 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
1784 */
1785static int
1786ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
1787{
1788 X509_NAME_ENTRY *ne;
1789 int i, j, n;
1790 int cur = 0;
1791 const char *s;
1792 char tmp[128];
1793
1794 out->len = 0;
1795 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1796 if (pos < 0)
1797 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
1798 else
1799 j = i;
1800
1801 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
1802 n = OBJ_obj2nid(ne->object);
1803 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1804 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1805 s = tmp;
1806 }
1807
1808 if (chunk_strcasecmp(entry, s) != 0)
1809 continue;
1810
1811 if (pos < 0)
1812 cur--;
1813 else
1814 cur++;
1815
1816 if (cur != pos)
1817 continue;
1818
1819 if (ne->value->length > out->size)
1820 return -1;
1821
1822 memcpy(out->str, ne->value->data, ne->value->length);
1823 out->len = ne->value->length;
1824 return 1;
1825 }
1826
1827 return 0;
1828
1829}
1830
1831/* Extract and format full DN from a X509_NAME and copy result into a chunk
1832 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
1833 */
1834static int
1835ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
1836{
1837 X509_NAME_ENTRY *ne;
1838 int i, n, ln;
1839 int l = 0;
1840 const char *s;
1841 char *p;
1842 char tmp[128];
1843
1844 out->len = 0;
1845 p = out->str;
1846 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1847 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
1848 n = OBJ_obj2nid(ne->object);
1849 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1850 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1851 s = tmp;
1852 }
1853 ln = strlen(s);
1854
1855 l += 1 + ln + 1 + ne->value->length;
1856 if (l > out->size)
1857 return -1;
1858 out->len = l;
1859
1860 *(p++)='/';
1861 memcpy(p, s, ln);
1862 p += ln;
1863 *(p++)='=';
1864 memcpy(p, ne->value->data, ne->value->length);
1865 p += ne->value->length;
1866 }
1867
1868 if (!out->len)
1869 return 0;
1870
1871 return 1;
1872}
1873
Willy Tarreau7875d092012-09-10 08:20:03 +02001874/***** Below are some sample fetching functions for ACL/patterns *****/
1875
Emeric Brune64aef12012-09-21 13:15:06 +02001876/* boolean, returns true if client cert was present */
1877static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02001878smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001879 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02001880{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001881 struct connection *conn;
1882
1883 if (!l4)
1884 return 0;
1885
1886 conn = objt_conn(l4->si[0].end);
1887 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02001888 return 0;
1889
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001890 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02001891 smp->flags |= SMP_F_MAY_CHANGE;
1892 return 0;
1893 }
1894
1895 smp->flags = 0;
1896 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001897 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001898
1899 return 1;
1900}
1901
Willy Tarreau8d598402012-10-22 17:58:39 +02001902/* bin, returns serial in a binary chunk */
1903static int
1904smp_fetch_ssl_c_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001905 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02001906{
1907 X509 *crt = NULL;
1908 int ret = 0;
1909 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001910 struct connection *conn;
1911
1912 if (!l4)
1913 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001914
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001915 conn = objt_conn(l4->si[0].end);
1916 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02001917 return 0;
1918
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001919 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02001920 smp->flags |= SMP_F_MAY_CHANGE;
1921 return 0;
1922 }
1923
1924 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001925 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02001926 if (!crt)
1927 goto out;
1928
Willy Tarreau47ca5452012-12-23 20:22:19 +01001929 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02001930 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
1931 goto out;
1932
1933 smp->data.str = *smp_trash;
1934 smp->type = SMP_T_BIN;
1935 ret = 1;
1936out:
1937 if (crt)
1938 X509_free(crt);
1939 return ret;
1940}
Emeric Brune64aef12012-09-21 13:15:06 +02001941
James Votha051b4a2013-05-14 20:37:59 +02001942/* bin, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk */
1943static int
1944smp_fetch_ssl_c_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001945 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02001946{
1947 X509 *crt = NULL;
1948 const EVP_MD *digest;
1949 int ret = 0;
1950 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001951 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02001952
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001953 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02001954 return 0;
1955
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001956 conn = objt_conn(l4->si[0].end);
1957 if (!conn || conn->xprt != &ssl_sock)
1958 return 0;
1959
1960 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02001961 smp->flags |= SMP_F_MAY_CHANGE;
1962 return 0;
1963 }
1964
1965 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001966 crt = SSL_get_peer_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02001967 if (!crt)
1968 goto out;
1969
1970 smp_trash = get_trash_chunk();
1971 digest = EVP_sha1();
1972 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
1973
1974 smp->data.str = *smp_trash;
1975 smp->type = SMP_T_BIN;
1976 ret = 1;
1977out:
1978 if (crt)
1979 X509_free(crt);
1980 return ret;
1981}
1982
Emeric Brunce5ad802012-10-22 14:11:22 +02001983/*str, returns notafter date in ASN1_UTCTIME format */
1984static int
1985smp_fetch_ssl_c_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001986 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02001987{
1988 X509 *crt = NULL;
1989 int ret = 0;
1990 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001991 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02001992
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001993 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02001994 return 0;
1995
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001996 conn = objt_conn(l4->si[0].end);
1997 if (!conn || conn->xprt != &ssl_sock)
1998 return 0;
1999
2000 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002001 smp->flags |= SMP_F_MAY_CHANGE;
2002 return 0;
2003 }
2004
2005 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002006 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002007 if (!crt)
2008 goto out;
2009
Willy Tarreau47ca5452012-12-23 20:22:19 +01002010 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002011 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2012 goto out;
2013
2014 smp->data.str = *smp_trash;
2015 smp->type = SMP_T_STR;
2016 ret = 1;
2017out:
2018 if (crt)
2019 X509_free(crt);
2020 return ret;
2021}
2022
Emeric Brun87855892012-10-17 17:39:35 +02002023/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2024static int
2025smp_fetch_ssl_c_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002026 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002027{
2028 X509 *crt = NULL;
2029 X509_NAME *name;
2030 int ret = 0;
2031 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002032 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002033
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002034 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002035 return 0;
2036
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002037 conn = objt_conn(l4->si[0].end);
2038 if (!conn || conn->xprt != &ssl_sock)
2039 return 0;
2040
2041 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002042 smp->flags |= SMP_F_MAY_CHANGE;
2043 return 0;
2044 }
2045
2046 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002047 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002048 if (!crt)
2049 goto out;
2050
2051 name = X509_get_issuer_name(crt);
2052 if (!name)
2053 goto out;
2054
Willy Tarreau47ca5452012-12-23 20:22:19 +01002055 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002056 if (args && args[0].type == ARGT_STR) {
2057 int pos = 1;
2058
2059 if (args[1].type == ARGT_SINT)
2060 pos = args[1].data.sint;
2061 else if (args[1].type == ARGT_UINT)
2062 pos =(int)args[1].data.uint;
2063
2064 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2065 goto out;
2066 }
2067 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2068 goto out;
2069
2070 smp->type = SMP_T_STR;
2071 smp->data.str = *smp_trash;
2072 ret = 1;
2073out:
2074 if (crt)
2075 X509_free(crt);
2076 return ret;
2077}
2078
Emeric Brunce5ad802012-10-22 14:11:22 +02002079/*str, returns notbefore date in ASN1_UTCTIME format */
2080static int
2081smp_fetch_ssl_c_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002082 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002083{
2084 X509 *crt = NULL;
2085 int ret = 0;
2086 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002087 struct connection *conn;
2088
2089 if (!l4)
2090 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002091
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002092 conn = objt_conn(l4->si[0].end);
2093 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002094 return 0;
2095
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002096 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002097 smp->flags |= SMP_F_MAY_CHANGE;
2098 return 0;
2099 }
2100
2101 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002102 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002103 if (!crt)
2104 goto out;
2105
Willy Tarreau47ca5452012-12-23 20:22:19 +01002106 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002107 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2108 goto out;
2109
2110 smp->data.str = *smp_trash;
2111 smp->type = SMP_T_STR;
2112 ret = 1;
2113out:
2114 if (crt)
2115 X509_free(crt);
2116 return ret;
2117}
2118
Emeric Brun87855892012-10-17 17:39:35 +02002119/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2120static int
2121smp_fetch_ssl_c_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002122 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002123{
2124 X509 *crt = NULL;
2125 X509_NAME *name;
2126 int ret = 0;
2127 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002128 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002129
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002130 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002131 return 0;
2132
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002133 conn = objt_conn(l4->si[0].end);
2134 if (!conn || conn->xprt != &ssl_sock)
2135 return 0;
2136
2137 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002138 smp->flags |= SMP_F_MAY_CHANGE;
2139 return 0;
2140 }
2141
2142 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002143 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002144 if (!crt)
2145 goto out;
2146
2147 name = X509_get_subject_name(crt);
2148 if (!name)
2149 goto out;
2150
Willy Tarreau47ca5452012-12-23 20:22:19 +01002151 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002152 if (args && args[0].type == ARGT_STR) {
2153 int pos = 1;
2154
2155 if (args[1].type == ARGT_SINT)
2156 pos = args[1].data.sint;
2157 else if (args[1].type == ARGT_UINT)
2158 pos =(int)args[1].data.uint;
2159
2160 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2161 goto out;
2162 }
2163 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2164 goto out;
2165
2166 smp->type = SMP_T_STR;
2167 smp->data.str = *smp_trash;
2168 ret = 1;
2169out:
2170 if (crt)
2171 X509_free(crt);
2172 return ret;
2173}
Emeric Brun9143d372012-12-20 15:44:16 +01002174
2175/* integer, returns true if current session use a client certificate */
2176static int
2177smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002178 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01002179{
2180 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002181 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01002182
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002183 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01002184 return 0;
2185
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002186 conn = objt_conn(l4->si[0].end);
2187 if (!conn || conn->xprt != &ssl_sock)
2188 return 0;
2189
2190 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01002191 smp->flags |= SMP_F_MAY_CHANGE;
2192 return 0;
2193 }
2194
2195 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002196 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01002197 if (crt) {
2198 X509_free(crt);
2199 }
2200
2201 smp->type = SMP_T_BOOL;
2202 smp->data.uint = (crt != NULL);
2203 return 1;
2204}
2205
Emeric Bruna7359fd2012-10-17 15:03:11 +02002206/* integer, returns the client certificate version */
2207static int
2208smp_fetch_ssl_c_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002209 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002210{
2211 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002212 struct connection *conn;
2213
2214 if (!l4)
2215 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002216
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002217 conn = objt_conn(l4->si[0].end);
2218 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002219 return 0;
2220
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002221 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002222 smp->flags |= SMP_F_MAY_CHANGE;
2223 return 0;
2224 }
2225
2226 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002227 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002228 if (!crt)
2229 return 0;
2230
2231 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2232 X509_free(crt);
2233 smp->type = SMP_T_UINT;
2234
2235 return 1;
2236}
2237
Emeric Brun7f56e742012-10-19 18:15:40 +02002238/* str, returns the client certificate sig alg */
2239static int
2240smp_fetch_ssl_c_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002241 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002242{
2243 X509 *crt;
2244 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002245 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002246
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002247 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002248 return 0;
2249
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002250 conn = objt_conn(l4->si[0].end);
2251 if (!conn || conn->xprt != &ssl_sock)
2252 return 0;
2253
2254 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002255 smp->flags |= SMP_F_MAY_CHANGE;
2256 return 0;
2257 }
2258
2259 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002260 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002261 if (!crt)
2262 return 0;
2263
2264 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2265
2266 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002267 if (!smp->data.str.str) {
2268 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002269 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002270 }
Emeric Brun7f56e742012-10-19 18:15:40 +02002271
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002272 smp->type = SMP_T_STR;
2273 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002274 smp->data.str.len = strlen(smp->data.str.str);
2275 X509_free(crt);
2276
2277 return 1;
2278}
2279
Emeric Brun521a0112012-10-22 12:22:55 +02002280/* str, returns the client certificate key alg */
2281static int
2282smp_fetch_ssl_c_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002283 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002284{
2285 X509 *crt;
2286 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002287 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02002288
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002289 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02002290 return 0;
2291
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002292 conn = objt_conn(l4->si[0].end);
2293 if (!conn || conn->xprt != &ssl_sock)
2294 return 0;
2295
2296 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002297 smp->flags |= SMP_F_MAY_CHANGE;
2298 return 0;
2299 }
2300
2301 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002302 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002303 if (!crt)
2304 return 0;
2305
2306 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2307
2308 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002309 if (!smp->data.str.str) {
2310 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002311 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002312 }
Emeric Brun521a0112012-10-22 12:22:55 +02002313
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002314 smp->type = SMP_T_STR;
2315 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002316 smp->data.str.len = strlen(smp->data.str.str);
2317 X509_free(crt);
2318
2319 return 1;
2320}
2321
Emeric Brun2525b6b2012-10-18 15:59:43 +02002322/* boolean, returns true if front conn. transport layer is SSL */
Willy Tarreau7875d092012-09-10 08:20:03 +02002323static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002324smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002325 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002326{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002327 struct connection *conn = objt_conn(l4->si[0].end);
2328
Willy Tarreau7875d092012-09-10 08:20:03 +02002329 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002330 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02002331 return 1;
2332}
2333
Emeric Brun2525b6b2012-10-18 15:59:43 +02002334/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02002335static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002336smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002337 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002338{
2339#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002340 struct connection *conn = objt_conn(l4->si[0].end);
2341
Willy Tarreau7875d092012-09-10 08:20:03 +02002342 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002343 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
2344 conn->xprt_ctx &&
2345 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02002346 return 1;
2347#else
2348 return 0;
2349#endif
2350}
2351
Willy Tarreau8d598402012-10-22 17:58:39 +02002352/* bin, returns serial in a binary chunk */
2353static int
2354smp_fetch_ssl_f_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002355 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002356{
2357 X509 *crt = NULL;
2358 int ret = 0;
2359 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002360 struct connection *conn;
2361
2362 if (!l4)
2363 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002364
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002365 conn = objt_conn(l4->si[0].end);
2366 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002367 return 0;
2368
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002369 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002370 smp->flags |= SMP_F_MAY_CHANGE;
2371 return 0;
2372 }
2373
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002374 crt = SSL_get_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02002375 if (!crt)
2376 goto out;
2377
Willy Tarreau47ca5452012-12-23 20:22:19 +01002378 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002379 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2380 goto out;
2381
2382 smp->data.str = *smp_trash;
2383 smp->type = SMP_T_BIN;
2384 ret = 1;
2385out:
2386 return ret;
2387}
Emeric Brunce5ad802012-10-22 14:11:22 +02002388/*str, returns notafter date in ASN1_UTCTIME format */
2389static int
2390smp_fetch_ssl_f_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002391 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002392{
2393 X509 *crt = NULL;
2394 int ret = 0;
2395 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002396 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002397
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002398 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002399 return 0;
2400
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002401 conn = objt_conn(l4->si[0].end);
2402 if (!conn || conn->xprt != &ssl_sock)
2403 return 0;
2404
2405 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002406 smp->flags |= SMP_F_MAY_CHANGE;
2407 return 0;
2408 }
2409
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002410 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002411 if (!crt)
2412 goto out;
2413
Willy Tarreau47ca5452012-12-23 20:22:19 +01002414 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002415 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2416 goto out;
2417
2418 smp->data.str = *smp_trash;
2419 smp->type = SMP_T_STR;
2420 ret = 1;
2421out:
2422 return ret;
2423}
2424
2425/*str, returns notbefore date in ASN1_UTCTIME format */
2426static int
2427smp_fetch_ssl_f_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002428 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002429{
2430 X509 *crt = NULL;
2431 int ret = 0;
2432 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002433 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002434
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002435 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002436 return 0;
2437
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002438 conn = objt_conn(l4->si[0].end);
2439 if (!conn || conn->xprt != &ssl_sock)
2440 return 0;
2441
2442 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002443 smp->flags |= SMP_F_MAY_CHANGE;
2444 return 0;
2445 }
2446
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002447 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002448 if (!crt)
2449 goto out;
2450
Willy Tarreau47ca5452012-12-23 20:22:19 +01002451 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002452 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2453 goto out;
2454
2455 smp->data.str = *smp_trash;
2456 smp->type = SMP_T_STR;
2457 ret = 1;
2458out:
2459 return ret;
2460}
Willy Tarreau8d598402012-10-22 17:58:39 +02002461
Emeric Bruna7359fd2012-10-17 15:03:11 +02002462/* integer, returns the frontend certificate version */
2463static int
2464smp_fetch_ssl_f_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002465 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002466{
2467 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002468 struct connection *conn;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002469
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002470 if (!l4)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002471 return 0;
2472
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002473 conn = objt_conn(l4->si[0].end);
2474 if (!conn || conn->xprt != &ssl_sock)
2475 return 0;
2476
2477 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002478 smp->flags |= SMP_F_MAY_CHANGE;
2479 return 0;
2480 }
2481
2482 /* SSL_get_certificate returns a ptr on an SSL * internal sub struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002483 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002484 if (!crt)
2485 return 0;
2486
2487 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2488 smp->type = SMP_T_UINT;
2489
2490 return 1;
2491}
2492
Emeric Brun7f56e742012-10-19 18:15:40 +02002493/* str, returns the client certificate sig alg */
2494static int
2495smp_fetch_ssl_f_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002496 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002497{
2498 X509 *crt;
2499 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002500 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002501
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002502 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002503 return 0;
2504
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002505 conn = objt_conn(l4->si[0].end);
2506 if (!conn || conn->xprt != &ssl_sock)
2507 return 0;
2508
2509 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002510 smp->flags |= SMP_F_MAY_CHANGE;
2511 return 0;
2512 }
2513
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002514 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002515 if (!crt)
2516 return 0;
2517
2518 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2519
2520 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2521 if (!smp->data.str.str)
2522 return 0;
2523
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002524 smp->type = SMP_T_STR;
2525 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002526 smp->data.str.len = strlen(smp->data.str.str);
2527
2528 return 1;
2529}
2530
Emeric Brun521a0112012-10-22 12:22:55 +02002531/* str, returns the client certificate key alg */
2532static int
2533smp_fetch_ssl_f_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002534 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002535{
2536 X509 *crt;
2537 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002538 struct connection *conn;
2539
2540 if (!l4)
2541 return 0;
Emeric Brun521a0112012-10-22 12:22:55 +02002542
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002543 conn = objt_conn(l4->si[0].end);
2544 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun521a0112012-10-22 12:22:55 +02002545 return 0;
2546
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002547 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002548 smp->flags |= SMP_F_MAY_CHANGE;
2549 return 0;
2550 }
2551
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002552 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002553 if (!crt)
2554 return 0;
2555
2556 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2557
2558 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2559 if (!smp->data.str.str)
2560 return 0;
2561
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002562 smp->type = SMP_T_STR;
2563 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002564 smp->data.str.len = strlen(smp->data.str.str);
2565
2566 return 1;
2567}
2568
Emeric Brun87855892012-10-17 17:39:35 +02002569/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2570static int
2571smp_fetch_ssl_f_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002572 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002573{
2574 X509 *crt = NULL;
2575 X509_NAME *name;
2576 int ret = 0;
2577 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002578 struct connection *conn;
2579
2580 if (!l4)
2581 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002582
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002583 conn = objt_conn(l4->si[0].end);
2584 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002585 return 0;
2586
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002587 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002588 smp->flags |= SMP_F_MAY_CHANGE;
2589 return 0;
2590 }
2591
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002592 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002593 if (!crt)
2594 goto out;
2595
2596 name = X509_get_issuer_name(crt);
2597 if (!name)
2598 goto out;
2599
Willy Tarreau47ca5452012-12-23 20:22:19 +01002600 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002601 if (args && args[0].type == ARGT_STR) {
2602 int pos = 1;
2603
2604 if (args[1].type == ARGT_SINT)
2605 pos = args[1].data.sint;
2606 else if (args[1].type == ARGT_UINT)
2607 pos =(int)args[1].data.uint;
2608
2609 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2610 goto out;
2611 }
2612 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2613 goto out;
2614
2615 smp->type = SMP_T_STR;
2616 smp->data.str = *smp_trash;
2617 ret = 1;
2618out:
2619 return ret;
2620}
2621
2622/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2623static int
2624smp_fetch_ssl_f_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002625 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002626{
2627 X509 *crt = NULL;
2628 X509_NAME *name;
2629 int ret = 0;
2630 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002631 struct connection *conn;
2632
2633 if (!l4)
2634 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002635
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002636 conn = objt_conn(l4->si[0].end);
2637 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002638 return 0;
2639
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002640 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002641 smp->flags |= SMP_F_MAY_CHANGE;
2642 return 0;
2643 }
2644
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002645 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002646 if (!crt)
2647 goto out;
2648
2649 name = X509_get_subject_name(crt);
2650 if (!name)
2651 goto out;
2652
Willy Tarreau47ca5452012-12-23 20:22:19 +01002653 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002654 if (args && args[0].type == ARGT_STR) {
2655 int pos = 1;
2656
2657 if (args[1].type == ARGT_SINT)
2658 pos = args[1].data.sint;
2659 else if (args[1].type == ARGT_UINT)
2660 pos =(int)args[1].data.uint;
2661
2662 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2663 goto out;
2664 }
2665 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2666 goto out;
2667
2668 smp->type = SMP_T_STR;
2669 smp->data.str = *smp_trash;
2670 ret = 1;
2671out:
2672 return ret;
2673}
2674
Emeric Brun589fcad2012-10-16 14:13:26 +02002675static int
2676smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002677 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002678{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002679 struct connection *conn;
2680
Emeric Brun589fcad2012-10-16 14:13:26 +02002681 smp->flags = 0;
2682
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002683 if (!l4)
2684 return 0;
2685
2686 conn = objt_conn(l4->si[0].end);
2687 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002688 return 0;
2689
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002690 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002691 if (!smp->data.str.str)
2692 return 0;
2693
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002694 smp->type = SMP_T_STR;
2695 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002696 smp->data.str.len = strlen(smp->data.str.str);
2697
2698 return 1;
2699}
2700
2701static int
2702smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002703 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002704{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002705 struct connection *conn;
2706
Emeric Brun589fcad2012-10-16 14:13:26 +02002707 smp->flags = 0;
2708
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002709 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002710 return 0;
2711
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002712 conn = objt_conn(l4->si[0].end);
2713 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002714 return 0;
2715
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002716 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
2717 return 0;
2718
Emeric Brun589fcad2012-10-16 14:13:26 +02002719 smp->type = SMP_T_UINT;
2720
2721 return 1;
2722}
2723
2724static int
2725smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002726 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002727{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002728 struct connection *conn;
2729
Emeric Brun589fcad2012-10-16 14:13:26 +02002730 smp->flags = 0;
2731
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002732 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002733 return 0;
2734
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002735 conn = objt_conn(l4->si[0].end);
2736 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2737 return 0;
2738
2739 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02002740 if (!smp->data.uint)
2741 return 0;
2742
2743 smp->type = SMP_T_UINT;
2744
2745 return 1;
2746}
2747
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002748#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02002749static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002750smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002751 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002752{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002753 struct connection *conn;
2754
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002755 smp->flags = SMP_F_CONST;
2756 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002757
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002758 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002759 return 0;
2760
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002761 conn = objt_conn(l4->si[0].end);
2762 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2763 return 0;
2764
Willy Tarreaua33c6542012-10-15 13:19:06 +02002765 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002766 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02002767 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2768
2769 if (!smp->data.str.str)
2770 return 0;
2771
2772 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002773}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002774#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02002775
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002776#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002777static int
2778smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002779 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02002780{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002781 struct connection *conn;
2782
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002783 smp->flags = SMP_F_CONST;
2784 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02002785
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002786 if (!l4)
2787 return 0;
2788
2789 conn = objt_conn(l4->si[0].end);
2790 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02002791 return 0;
2792
2793 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002794 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02002795 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2796
2797 if (!smp->data.str.str)
2798 return 0;
2799
2800 return 1;
2801}
2802#endif
2803
Willy Tarreaua33c6542012-10-15 13:19:06 +02002804static int
Emeric Brun589fcad2012-10-16 14:13:26 +02002805smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002806 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002807{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002808 struct connection *conn;
2809
Emeric Brun589fcad2012-10-16 14:13:26 +02002810 smp->flags = 0;
2811
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002812 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002813 return 0;
2814
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002815 conn = objt_conn(l4->si[0].end);
2816 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2817 return 0;
2818
2819 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002820 if (!smp->data.str.str)
2821 return 0;
2822
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002823 smp->type = SMP_T_STR;
2824 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002825 smp->data.str.len = strlen(smp->data.str.str);
2826
2827 return 1;
2828}
2829
2830static int
Emeric Brunfe68f682012-10-16 14:59:28 +02002831smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002832 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02002833{
2834#if OPENSSL_VERSION_NUMBER > 0x0090800fL
2835 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002836 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02002837
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002838 smp->flags = SMP_F_CONST;
2839 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02002840
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002841 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02002842 return 0;
2843
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002844 conn = objt_conn(l4->si[0].end);
2845 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2846 return 0;
2847
2848 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02002849 if (!sess)
2850 return 0;
2851
2852 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
2853 if (!smp->data.str.str || !&smp->data.str.len)
2854 return 0;
2855
2856 return 1;
2857#else
2858 return 0;
2859#endif
2860}
2861
2862static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002863smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002864 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002865{
2866#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002867 struct connection *conn;
2868
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002869 smp->flags = SMP_F_CONST;
2870 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02002871
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002872 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02002873 return 0;
2874
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002875 conn = objt_conn(l4->si[0].end);
2876 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2877 return 0;
2878
2879 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02002880 if (!smp->data.str.str)
2881 return 0;
2882
Willy Tarreau7875d092012-09-10 08:20:03 +02002883 smp->data.str.len = strlen(smp->data.str.str);
2884 return 1;
2885#else
2886 return 0;
2887#endif
2888}
2889
David Sc1ad52e2014-04-08 18:48:47 -04002890static int
2891smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2892 const struct arg *args, struct sample *smp, const char *kw)
2893{
2894#if OPENSSL_VERSION_NUMBER > 0x0090800fL
2895 struct connection *conn;
2896 int finished_len;
2897 int b64_len;
2898 struct chunk *finished_trash;
2899 struct chunk *smp_trash;
2900
2901 smp->flags = 0;
2902
2903 if (!l4)
2904 return 0;
2905
2906 conn = objt_conn(l4->si[0].end);
2907 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2908 return 0;
2909
2910 if (!(conn->flags & CO_FL_CONNECTED)) {
2911 smp->flags |= SMP_F_MAY_CHANGE;
2912 return 0;
2913 }
2914
2915 finished_trash = get_trash_chunk();
2916 if (!SSL_session_reused(conn->xprt_ctx))
2917 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2918 else
2919 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2920
2921 if (!finished_len)
2922 return 0;
2923
2924 smp_trash = get_trash_chunk();
2925 b64_len = a2base64(finished_trash->str, finished_len, smp_trash->str, smp_trash->size);
2926 if (b64_len < 0)
2927 return 0;
2928
2929 smp->data.str.str = smp_trash->str;
Willy Tarreau073edf32014-04-09 15:40:42 +02002930 smp->type = SMP_T_STR;
2931 smp->flags |= SMP_F_CONST;
David Sc1ad52e2014-04-08 18:48:47 -04002932 smp->data.str.len = b64_len;
2933
2934 return 1;
2935#else
2936 return 0;
2937#endif
2938}
2939
Emeric Brun2525b6b2012-10-18 15:59:43 +02002940/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002941static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002942smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002943 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002944{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002945 struct connection *conn;
2946
2947 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002948 return 0;
2949
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002950 conn = objt_conn(l4->si[0].end);
2951 if (!conn || conn->xprt != &ssl_sock)
2952 return 0;
2953
2954 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002955 smp->flags = SMP_F_MAY_CHANGE;
2956 return 0;
2957 }
2958
2959 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002960 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002961 smp->flags = 0;
2962
2963 return 1;
2964}
2965
Emeric Brun2525b6b2012-10-18 15:59:43 +02002966/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002967static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002968smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002969 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002970{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002971 struct connection *conn;
2972
2973 if (!l4)
2974 return 0;
2975
2976 conn = objt_conn(l4->si[0].end);
2977 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02002978 return 0;
2979
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002980 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002981 smp->flags = SMP_F_MAY_CHANGE;
2982 return 0;
2983 }
2984
2985 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002986 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002987 smp->flags = 0;
2988
2989 return 1;
2990}
2991
Emeric Brun2525b6b2012-10-18 15:59:43 +02002992/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02002993static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002994smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002995 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002996{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002997 struct connection *conn;
2998
2999 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003000 return 0;
3001
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003002 conn = objt_conn(l4->si[0].end);
3003 if (!conn || conn->xprt != &ssl_sock)
3004 return 0;
3005
3006 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003007 smp->flags = SMP_F_MAY_CHANGE;
3008 return 0;
3009 }
3010
3011 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003012 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003013 smp->flags = 0;
3014
3015 return 1;
3016}
3017
Emeric Brun2525b6b2012-10-18 15:59:43 +02003018/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003019static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003020smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003021 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003022{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003023 struct connection *conn;
3024
3025 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003026 return 0;
3027
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003028 conn = objt_conn(l4->si[0].end);
3029 if (!conn || conn->xprt != &ssl_sock)
3030 return 0;
3031
3032 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003033 smp->flags = SMP_F_MAY_CHANGE;
3034 return 0;
3035 }
3036
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003037 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003038 return 0;
3039
3040 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003041 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003042 smp->flags = 0;
3043
3044 return 1;
3045}
3046
Emeric Brunfb510ea2012-10-05 12:00:26 +02003047/* parse the "ca-file" bind keyword */
3048static 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 +02003049{
3050 if (!*args[cur_arg + 1]) {
3051 if (err)
3052 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3053 return ERR_ALERT | ERR_FATAL;
3054 }
3055
Emeric Brunef42d922012-10-11 16:11:36 +02003056 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3057 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3058 else
3059 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003060
Emeric Brund94b3fe2012-09-20 18:23:56 +02003061 return 0;
3062}
3063
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003064/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003065static 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 +02003066{
3067 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003068 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003069 return ERR_ALERT | ERR_FATAL;
3070 }
3071
Emeric Brun76d88952012-10-05 15:47:31 +02003072 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003073 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003074 return 0;
3075}
3076
3077/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003078static 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 +02003079{
Willy Tarreau38011032013-08-13 16:59:39 +02003080 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003081
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003082 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003083 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003084 return ERR_ALERT | ERR_FATAL;
3085 }
3086
Emeric Brunc8e8d122012-10-02 18:42:10 +02003087 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003088 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003089 memprintf(err, "'%s' : path too long", args[cur_arg]);
3090 return ERR_ALERT | ERR_FATAL;
3091 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003092 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003093 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3094 return ERR_ALERT | ERR_FATAL;
3095
3096 return 0;
3097 }
3098
Willy Tarreau4348fad2012-09-20 16:48:07 +02003099 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003100 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003101
3102 return 0;
3103}
3104
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003105/* parse the "crt-list" bind keyword */
3106static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3107{
3108 if (!*args[cur_arg + 1]) {
3109 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3110 return ERR_ALERT | ERR_FATAL;
3111 }
3112
Willy Tarreauad1731d2013-04-02 17:35:58 +02003113 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3114 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003115 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003116 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003117
3118 return 0;
3119}
3120
Emeric Brunfb510ea2012-10-05 12:00:26 +02003121/* parse the "crl-file" bind keyword */
3122static 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 +02003123{
Emeric Brun051cdab2012-10-02 19:25:50 +02003124#ifndef X509_V_FLAG_CRL_CHECK
3125 if (err)
3126 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3127 return ERR_ALERT | ERR_FATAL;
3128#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003129 if (!*args[cur_arg + 1]) {
3130 if (err)
3131 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3132 return ERR_ALERT | ERR_FATAL;
3133 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003134
Emeric Brunef42d922012-10-11 16:11:36 +02003135 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3136 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3137 else
3138 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003139
Emeric Brun2b58d042012-09-20 17:10:03 +02003140 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003141#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003142}
3143
3144/* parse the "ecdhe" bind keyword keywords */
3145static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3146{
3147#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3148 if (err)
3149 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3150 return ERR_ALERT | ERR_FATAL;
3151#elif defined(OPENSSL_NO_ECDH)
3152 if (err)
3153 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3154 return ERR_ALERT | ERR_FATAL;
3155#else
3156 if (!*args[cur_arg + 1]) {
3157 if (err)
3158 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3159 return ERR_ALERT | ERR_FATAL;
3160 }
3161
3162 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003163
3164 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003165#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003166}
3167
Emeric Brun81c00f02012-09-21 14:31:21 +02003168/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3169static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3170{
3171 int code;
3172 char *p = args[cur_arg + 1];
3173 unsigned long long *ignerr = &conf->crt_ignerr;
3174
3175 if (!*p) {
3176 if (err)
3177 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3178 return ERR_ALERT | ERR_FATAL;
3179 }
3180
3181 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3182 ignerr = &conf->ca_ignerr;
3183
3184 if (strcmp(p, "all") == 0) {
3185 *ignerr = ~0ULL;
3186 return 0;
3187 }
3188
3189 while (p) {
3190 code = atoi(p);
3191 if ((code <= 0) || (code > 63)) {
3192 if (err)
3193 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3194 args[cur_arg], code, args[cur_arg + 1]);
3195 return ERR_ALERT | ERR_FATAL;
3196 }
3197 *ignerr |= 1ULL << code;
3198 p = strchr(p, ',');
3199 if (p)
3200 p++;
3201 }
3202
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003203 return 0;
3204}
3205
3206/* parse the "force-sslv3" bind keyword */
3207static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3208{
3209 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3210 return 0;
3211}
3212
3213/* parse the "force-tlsv10" bind keyword */
3214static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3215{
3216 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003217 return 0;
3218}
3219
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003220/* parse the "force-tlsv11" bind keyword */
3221static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3222{
3223#if SSL_OP_NO_TLSv1_1
3224 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3225 return 0;
3226#else
3227 if (err)
3228 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3229 return ERR_ALERT | ERR_FATAL;
3230#endif
3231}
3232
3233/* parse the "force-tlsv12" bind keyword */
3234static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3235{
3236#if SSL_OP_NO_TLSv1_2
3237 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3238 return 0;
3239#else
3240 if (err)
3241 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3242 return ERR_ALERT | ERR_FATAL;
3243#endif
3244}
3245
3246
Emeric Brun2d0c4822012-10-02 13:45:20 +02003247/* parse the "no-tls-tickets" bind keyword */
3248static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3249{
Emeric Brun89675492012-10-05 13:48:26 +02003250 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003251 return 0;
3252}
3253
Emeric Brun2d0c4822012-10-02 13:45:20 +02003254
Emeric Brun9b3009b2012-10-05 11:55:06 +02003255/* parse the "no-sslv3" bind keyword */
3256static 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 +02003257{
Emeric Brun89675492012-10-05 13:48:26 +02003258 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003259 return 0;
3260}
3261
Emeric Brun9b3009b2012-10-05 11:55:06 +02003262/* parse the "no-tlsv10" bind keyword */
3263static 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 +02003264{
Emeric Brun89675492012-10-05 13:48:26 +02003265 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003266 return 0;
3267}
3268
Emeric Brun9b3009b2012-10-05 11:55:06 +02003269/* parse the "no-tlsv11" bind keyword */
3270static 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 +02003271{
Emeric Brun89675492012-10-05 13:48:26 +02003272 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003273 return 0;
3274}
3275
Emeric Brun9b3009b2012-10-05 11:55:06 +02003276/* parse the "no-tlsv12" bind keyword */
3277static 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 +02003278{
Emeric Brun89675492012-10-05 13:48:26 +02003279 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003280 return 0;
3281}
3282
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003283/* parse the "npn" bind keyword */
3284static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3285{
3286#ifdef OPENSSL_NPN_NEGOTIATED
3287 char *p1, *p2;
3288
3289 if (!*args[cur_arg + 1]) {
3290 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3291 return ERR_ALERT | ERR_FATAL;
3292 }
3293
3294 free(conf->npn_str);
3295
3296 /* the NPN string is built as a suite of (<len> <name>)* */
3297 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3298 conf->npn_str = calloc(1, conf->npn_len);
3299 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3300
3301 /* replace commas with the name length */
3302 p1 = conf->npn_str;
3303 p2 = p1 + 1;
3304 while (1) {
3305 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3306 if (!p2)
3307 p2 = p1 + 1 + strlen(p1 + 1);
3308
3309 if (p2 - (p1 + 1) > 255) {
3310 *p2 = '\0';
3311 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3312 return ERR_ALERT | ERR_FATAL;
3313 }
3314
3315 *p1 = p2 - (p1 + 1);
3316 p1 = p2;
3317
3318 if (!*p2)
3319 break;
3320
3321 *(p2++) = '\0';
3322 }
3323 return 0;
3324#else
3325 if (err)
3326 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3327 return ERR_ALERT | ERR_FATAL;
3328#endif
3329}
3330
Willy Tarreauab861d32013-04-02 02:30:41 +02003331/* parse the "alpn" bind keyword */
3332static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3333{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003334#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003335 char *p1, *p2;
3336
3337 if (!*args[cur_arg + 1]) {
3338 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3339 return ERR_ALERT | ERR_FATAL;
3340 }
3341
3342 free(conf->alpn_str);
3343
3344 /* the ALPN string is built as a suite of (<len> <name>)* */
3345 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3346 conf->alpn_str = calloc(1, conf->alpn_len);
3347 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3348
3349 /* replace commas with the name length */
3350 p1 = conf->alpn_str;
3351 p2 = p1 + 1;
3352 while (1) {
3353 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3354 if (!p2)
3355 p2 = p1 + 1 + strlen(p1 + 1);
3356
3357 if (p2 - (p1 + 1) > 255) {
3358 *p2 = '\0';
3359 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3360 return ERR_ALERT | ERR_FATAL;
3361 }
3362
3363 *p1 = p2 - (p1 + 1);
3364 p1 = p2;
3365
3366 if (!*p2)
3367 break;
3368
3369 *(p2++) = '\0';
3370 }
3371 return 0;
3372#else
3373 if (err)
3374 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3375 return ERR_ALERT | ERR_FATAL;
3376#endif
3377}
3378
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003379/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003380static 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 +02003381{
Willy Tarreau81796be2012-09-22 19:11:47 +02003382 struct listener *l;
3383
Willy Tarreau4348fad2012-09-20 16:48:07 +02003384 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003385
3386 if (global.listen_default_ciphers && !conf->ciphers)
3387 conf->ciphers = strdup(global.listen_default_ciphers);
3388
Willy Tarreau81796be2012-09-22 19:11:47 +02003389 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003390 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003391
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003392 return 0;
3393}
3394
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003395/* parse the "strict-sni" bind keyword */
3396static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3397{
3398 conf->strict_sni = 1;
3399 return 0;
3400}
3401
Emeric Brund94b3fe2012-09-20 18:23:56 +02003402/* parse the "verify" bind keyword */
3403static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3404{
3405 if (!*args[cur_arg + 1]) {
3406 if (err)
3407 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3408 return ERR_ALERT | ERR_FATAL;
3409 }
3410
3411 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003412 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003413 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003414 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003415 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003416 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003417 else {
3418 if (err)
3419 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3420 args[cur_arg], args[cur_arg + 1]);
3421 return ERR_ALERT | ERR_FATAL;
3422 }
3423
3424 return 0;
3425}
3426
Willy Tarreau92faadf2012-10-10 23:04:25 +02003427/************** "server" keywords ****************/
3428
Emeric Brunef42d922012-10-11 16:11:36 +02003429/* parse the "ca-file" server keyword */
3430static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3431{
3432 if (!*args[*cur_arg + 1]) {
3433 if (err)
3434 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3435 return ERR_ALERT | ERR_FATAL;
3436 }
3437
3438 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3439 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3440 else
3441 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3442
3443 return 0;
3444}
3445
Willy Tarreau92faadf2012-10-10 23:04:25 +02003446/* parse the "check-ssl" server keyword */
3447static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3448{
3449 newsrv->check.use_ssl = 1;
3450 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3451 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3452 return 0;
3453}
3454
3455/* parse the "ciphers" server keyword */
3456static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3457{
3458 if (!*args[*cur_arg + 1]) {
3459 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3460 return ERR_ALERT | ERR_FATAL;
3461 }
3462
3463 free(newsrv->ssl_ctx.ciphers);
3464 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3465 return 0;
3466}
3467
Emeric Brunef42d922012-10-11 16:11:36 +02003468/* parse the "crl-file" server keyword */
3469static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3470{
3471#ifndef X509_V_FLAG_CRL_CHECK
3472 if (err)
3473 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3474 return ERR_ALERT | ERR_FATAL;
3475#else
3476 if (!*args[*cur_arg + 1]) {
3477 if (err)
3478 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
3479 return ERR_ALERT | ERR_FATAL;
3480 }
3481
3482 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3483 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3484 else
3485 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
3486
3487 return 0;
3488#endif
3489}
3490
Emeric Bruna7aa3092012-10-26 12:58:00 +02003491/* parse the "crt" server keyword */
3492static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3493{
3494 if (!*args[*cur_arg + 1]) {
3495 if (err)
3496 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
3497 return ERR_ALERT | ERR_FATAL;
3498 }
3499
3500 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
3501 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3502 else
3503 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
3504
3505 return 0;
3506}
Emeric Brunef42d922012-10-11 16:11:36 +02003507
Willy Tarreau92faadf2012-10-10 23:04:25 +02003508/* parse the "force-sslv3" server keyword */
3509static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3510{
3511 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
3512 return 0;
3513}
3514
3515/* parse the "force-tlsv10" server keyword */
3516static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3517{
3518 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
3519 return 0;
3520}
3521
3522/* parse the "force-tlsv11" server keyword */
3523static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3524{
3525#if SSL_OP_NO_TLSv1_1
3526 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
3527 return 0;
3528#else
3529 if (err)
3530 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
3531 return ERR_ALERT | ERR_FATAL;
3532#endif
3533}
3534
3535/* parse the "force-tlsv12" server keyword */
3536static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3537{
3538#if SSL_OP_NO_TLSv1_2
3539 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
3540 return 0;
3541#else
3542 if (err)
3543 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
3544 return ERR_ALERT | ERR_FATAL;
3545#endif
3546}
3547
3548/* parse the "no-sslv3" server keyword */
3549static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3550{
3551 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
3552 return 0;
3553}
3554
3555/* parse the "no-tlsv10" server keyword */
3556static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3557{
3558 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
3559 return 0;
3560}
3561
3562/* parse the "no-tlsv11" server keyword */
3563static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3564{
3565 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
3566 return 0;
3567}
3568
3569/* parse the "no-tlsv12" server keyword */
3570static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3571{
3572 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
3573 return 0;
3574}
3575
Emeric Brunf9c5c472012-10-11 15:28:34 +02003576/* parse the "no-tls-tickets" server keyword */
3577static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3578{
3579 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
3580 return 0;
3581}
3582
Willy Tarreau92faadf2012-10-10 23:04:25 +02003583/* parse the "ssl" server keyword */
3584static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3585{
3586 newsrv->use_ssl = 1;
3587 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3588 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3589 return 0;
3590}
3591
Emeric Brunef42d922012-10-11 16:11:36 +02003592/* parse the "verify" server keyword */
3593static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3594{
3595 if (!*args[*cur_arg + 1]) {
3596 if (err)
3597 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
3598 return ERR_ALERT | ERR_FATAL;
3599 }
3600
3601 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003602 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02003603 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003604 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02003605 else {
3606 if (err)
3607 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
3608 args[*cur_arg], args[*cur_arg + 1]);
3609 return ERR_ALERT | ERR_FATAL;
3610 }
3611
Evan Broderbe554312013-06-27 00:05:25 -07003612 return 0;
3613}
3614
3615/* parse the "verifyhost" server keyword */
3616static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3617{
3618 if (!*args[*cur_arg + 1]) {
3619 if (err)
3620 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
3621 return ERR_ALERT | ERR_FATAL;
3622 }
3623
3624 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
3625
Emeric Brunef42d922012-10-11 16:11:36 +02003626 return 0;
3627}
3628
Willy Tarreau7875d092012-09-10 08:20:03 +02003629/* Note: must not be declared <const> as its list will be overwritten.
3630 * Please take care of keeping this list alphabetically sorted.
3631 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003632static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Willy Tarreau80aca902013-01-07 15:42:20 +01003633 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3634 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3635 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3636 { "ssl_c_i_dn", smp_fetch_ssl_c_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3637 { "ssl_c_key_alg", smp_fetch_ssl_c_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3638 { "ssl_c_notafter", smp_fetch_ssl_c_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3639 { "ssl_c_notbefore", smp_fetch_ssl_c_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3640 { "ssl_c_sig_alg", smp_fetch_ssl_c_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3641 { "ssl_c_s_dn", smp_fetch_ssl_c_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3642 { "ssl_c_serial", smp_fetch_ssl_c_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
James Votha051b4a2013-05-14 20:37:59 +02003643 { "ssl_c_sha1", smp_fetch_ssl_c_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003644 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3645 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3646 { "ssl_c_version", smp_fetch_ssl_c_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3647 { "ssl_f_i_dn", smp_fetch_ssl_f_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3648 { "ssl_f_key_alg", smp_fetch_ssl_f_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3649 { "ssl_f_notafter", smp_fetch_ssl_f_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3650 { "ssl_f_notbefore", smp_fetch_ssl_f_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3651 { "ssl_f_sig_alg", smp_fetch_ssl_f_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3652 { "ssl_f_s_dn", smp_fetch_ssl_f_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3653 { "ssl_f_serial", smp_fetch_ssl_f_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3654 { "ssl_f_version", smp_fetch_ssl_f_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3655 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3656 { "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 +01003657 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003658 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3659 { "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 +02003660#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003661 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003662#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003663#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003664 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02003665#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003666 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau073edf32014-04-09 15:40:42 +02003667 { "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 +01003668 { "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 +01003669 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3670 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02003671 { NULL, NULL, 0, 0, 0 },
3672}};
3673
3674/* Note: must not be declared <const> as its list will be overwritten.
3675 * Please take care of keeping this list alphabetically sorted.
3676 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003677static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003678 { "ssl_c_i_dn", NULL, PAT_MATCH_STR },
3679 { "ssl_c_key_alg", NULL, PAT_MATCH_STR },
3680 { "ssl_c_notafter", NULL, PAT_MATCH_STR },
3681 { "ssl_c_notbefore", NULL, PAT_MATCH_STR },
3682 { "ssl_c_sig_alg", NULL, PAT_MATCH_STR },
3683 { "ssl_c_s_dn", NULL, PAT_MATCH_STR },
3684 { "ssl_c_serial", NULL, PAT_MATCH_BIN },
3685 { "ssl_f_i_dn", NULL, PAT_MATCH_STR },
3686 { "ssl_f_key_alg", NULL, PAT_MATCH_STR },
3687 { "ssl_f_notafter", NULL, PAT_MATCH_STR },
3688 { "ssl_f_notbefore", NULL, PAT_MATCH_STR },
3689 { "ssl_f_sig_alg", NULL, PAT_MATCH_STR },
3690 { "ssl_f_s_dn", NULL, PAT_MATCH_STR },
3691 { "ssl_f_serial", NULL, PAT_MATCH_BIN },
3692 { "ssl_fc_cipher", NULL, PAT_MATCH_STR },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003693#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003694 { "ssl_fc_npn", NULL, PAT_MATCH_STR },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003695#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003696#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003697 { "ssl_fc_alpn", NULL, PAT_MATCH_STR },
Willy Tarreauab861d32013-04-02 02:30:41 +02003698#endif
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003699 { "ssl_fc_protocol", NULL, PAT_MATCH_STR },
3700 { "ssl_fc_sni", "ssl_fc_sni", PAT_MATCH_STR },
3701 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
3702 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01003703 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02003704}};
3705
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003706/* Note: must not be declared <const> as its list will be overwritten.
3707 * Please take care of keeping this list alphabetically sorted, doing so helps
3708 * all code contributors.
3709 * Optional keywords are also declared with a NULL ->parse() function so that
3710 * the config parser can report an appropriate error when a known keyword was
3711 * not enabled.
3712 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02003713static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02003714 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003715 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003716 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
3717 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003718 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003719 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
3720 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003721 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003722 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003723 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
3724 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
3725 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
3726 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02003727 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
3728 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
3729 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
3730 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003731 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003732 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003733 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003734 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003735 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003736 { NULL, NULL, 0 },
3737}};
Emeric Brun46591952012-05-18 15:47:34 +02003738
Willy Tarreau92faadf2012-10-10 23:04:25 +02003739/* Note: must not be declared <const> as its list will be overwritten.
3740 * Please take care of keeping this list alphabetically sorted, doing so helps
3741 * all code contributors.
3742 * Optional keywords are also declared with a NULL ->parse() function so that
3743 * the config parser can report an appropriate error when a known keyword was
3744 * not enabled.
3745 */
3746static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02003747 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003748 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
3749 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02003750 { "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 +02003751 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003752 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
3753 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
3754 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
3755 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
3756 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
3757 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
3758 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
3759 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02003760 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003761 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02003762 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07003763 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02003764 { NULL, NULL, 0, 0 },
3765}};
3766
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003767/* transport-layer operations for SSL sockets */
3768struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02003769 .snd_buf = ssl_sock_from_buf,
3770 .rcv_buf = ssl_sock_to_buf,
3771 .rcv_pipe = NULL,
3772 .snd_pipe = NULL,
3773 .shutr = NULL,
3774 .shutw = ssl_sock_shutw,
3775 .close = ssl_sock_close,
3776 .init = ssl_sock_init,
3777};
3778
3779__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02003780static void __ssl_sock_init(void)
3781{
Emeric Brun46591952012-05-18 15:47:34 +02003782 STACK_OF(SSL_COMP)* cm;
3783
Willy Tarreau610f04b2014-02-13 11:36:41 +01003784#ifdef LISTEN_DEFAULT_CIPHERS
3785 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
3786#endif
3787#ifdef CONNECT_DEFAULT_CIPHERS
3788 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
3789#endif
3790 if (global.listen_default_ciphers)
3791 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
3792 if (global.connect_default_ciphers)
3793 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
3794
Emeric Brun46591952012-05-18 15:47:34 +02003795 SSL_library_init();
3796 cm = SSL_COMP_get_compression_methods();
3797 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02003798 sample_register_fetches(&sample_fetch_keywords);
3799 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003800 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02003801 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02003802}
3803
3804/*
3805 * Local variables:
3806 * c-indent-level: 8
3807 * c-basic-offset: 8
3808 * End:
3809 */