blob: 880e7275b0881e4dc908f31f9f482f74be481c22 [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02003 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Willy Tarreau69845df2012-09-10 09:43:09 +020011 * Acknowledgement:
12 * We'd like to specially thank the Stud project authors for a very clean
13 * and well documented code which helped us understand how the OpenSSL API
14 * ought to be used in non-blocking mode. This is one difficult part which
15 * is not easy to get from the OpenSSL doc, and reading the Stud code made
16 * it much more obvious than the examples in the OpenSSL package. Keep up
17 * the good works, guys !
18 *
19 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
20 * particularly well with haproxy. For more info about this project, visit :
21 * https://github.com/bumptech/stud
22 *
Emeric Brun46591952012-05-18 15:47:34 +020023 */
24
25#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020026#include <ctype.h>
27#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020028#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020032#include <string.h>
33#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020034
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38
39#include <netinet/tcp.h>
40
41#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020042#include <openssl/x509.h>
43#include <openssl/x509v3.h>
44#include <openssl/x509.h>
45#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010046#include <openssl/rand.h>
Emeric Brun46591952012-05-18 15:47:34 +020047
48#include <common/buffer.h>
49#include <common/compat.h>
50#include <common/config.h>
51#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020052#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020053#include <common/standard.h>
54#include <common/ticks.h>
55#include <common/time.h>
56
Emeric Brunfc0421f2012-09-07 17:30:07 +020057#include <ebsttree.h>
58
59#include <types/global.h>
60#include <types/ssl_sock.h>
61
Willy Tarreau7875d092012-09-10 08:20:03 +020062#include <proto/acl.h>
63#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020064#include <proto/connection.h>
65#include <proto/fd.h>
66#include <proto/freq_ctr.h>
67#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020068#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010069#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020070#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020071#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020072#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020073#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020074#include <proto/ssl_sock.h>
75#include <proto/task.h>
76
Willy Tarreau518cedd2014-02-17 15:43:01 +010077/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020078#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010079#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010080#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020081#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
82
Emeric Brunf282a812012-09-21 15:27:54 +020083/* bits 0xFFFF0000 are reserved to store verify errors */
84
85/* Verify errors macros */
86#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
87#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
88#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
89
90#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
91#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
92#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020093
Emeric Brun850efd52014-01-29 12:24:34 +010094/* server and bind verify method, it uses a global value as default */
95enum {
96 SSL_SOCK_VERIFY_DEFAULT = 0,
97 SSL_SOCK_VERIFY_REQUIRED = 1,
98 SSL_SOCK_VERIFY_OPTIONAL = 2,
99 SSL_SOCK_VERIFY_NONE = 3,
100};
101
Willy Tarreau71b734c2014-01-28 15:19:44 +0100102int sslconns = 0;
103int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200104
105void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
106{
107 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
108 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100109 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200110
111 if (where & SSL_CB_HANDSHAKE_START) {
112 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100113 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200114 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100115 conn->err_code = CO_ER_SSL_RENEG;
116 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200117 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100118
119 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
120 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
121 /* Long certificate chains optimz
122 If write and read bios are differents, we
123 consider that the buffering was activated,
124 so we rise the output buffer size from 4k
125 to 16k */
126 write_bio = SSL_get_wbio(ssl);
127 if (write_bio != SSL_get_rbio(ssl)) {
128 BIO_set_write_buffer_size(write_bio, 16384);
129 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
130 }
131 }
132 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200133}
134
Emeric Brune64aef12012-09-21 13:15:06 +0200135/* Callback is called for each certificate of the chain during a verify
136 ok is set to 1 if preverify detect no error on current certificate.
137 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700138int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200139{
140 SSL *ssl;
141 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200142 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200143
144 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
145 conn = (struct connection *)SSL_get_app_data(ssl);
146
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200147 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200148
Emeric Brun81c00f02012-09-21 14:31:21 +0200149 if (ok) /* no errors */
150 return ok;
151
152 depth = X509_STORE_CTX_get_error_depth(x_store);
153 err = X509_STORE_CTX_get_error(x_store);
154
155 /* check if CA error needs to be ignored */
156 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200157 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
158 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
159 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200160 }
161
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100162 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
163 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200164 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100165 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200166
Willy Tarreau20879a02012-12-03 16:32:10 +0100167 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200168 return 0;
169 }
170
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200171 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
172 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200173
Emeric Brun81c00f02012-09-21 14:31:21 +0200174 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100175 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
176 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200177 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100178 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200179
Willy Tarreau20879a02012-12-03 16:32:10 +0100180 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200181 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200182}
183
Emeric Brun29f037d2014-04-25 19:05:36 +0200184/* Callback is called for ssl protocol analyse */
185void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
186{
Emeric Brun29f037d2014-04-25 19:05:36 +0200187#ifdef TLS1_RT_HEARTBEAT
188 /* test heartbeat received (write_p is set to 0
189 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200190 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200191 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200192 const unsigned char *p = buf;
193 unsigned int payload;
194
Emeric Brun29f037d2014-04-25 19:05:36 +0200195 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200196
197 /* Check if this is a CVE-2014-0160 exploitation attempt. */
198 if (*p != TLS1_HB_REQUEST)
199 return;
200
Willy Tarreauaeed6722014-04-25 23:59:58 +0200201 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200202 goto kill_it;
203
204 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200205 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200206 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200207 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200208 /* We have a clear heartbleed attack (CVE-2014-0160), the
209 * advertised payload is larger than the advertised packet
210 * length, so we have garbage in the buffer between the
211 * payload and the end of the buffer (p+len). We can't know
212 * if the SSL stack is patched, and we don't know if we can
213 * safely wipe out the area between p+3+len and payload.
214 * So instead, we prevent the response from being sent by
215 * setting the max_send_fragment to 0 and we report an SSL
216 * error, which will kill this connection. It will be reported
217 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200218 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
219 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200220 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200221 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
222 return;
223 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200224#endif
225}
226
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200227#ifdef OPENSSL_NPN_NEGOTIATED
228/* This callback is used so that the server advertises the list of
229 * negociable protocols for NPN.
230 */
231static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
232 unsigned int *len, void *arg)
233{
234 struct bind_conf *conf = arg;
235
236 *data = (const unsigned char *)conf->npn_str;
237 *len = conf->npn_len;
238 return SSL_TLSEXT_ERR_OK;
239}
240#endif
241
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100242#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200243/* This callback is used so that the server advertises the list of
244 * negociable protocols for ALPN.
245 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100246static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
247 unsigned char *outlen,
248 const unsigned char *server,
249 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200250{
251 struct bind_conf *conf = arg;
252
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100253 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
254 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
255 return SSL_TLSEXT_ERR_NOACK;
256 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200257 return SSL_TLSEXT_ERR_OK;
258}
259#endif
260
Emeric Brunfc0421f2012-09-07 17:30:07 +0200261#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
262/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
263 * warning when no match is found, which implies the default (first) cert
264 * will keep being used.
265 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200266static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200267{
268 const char *servername;
269 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200270 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200271 int i;
272 (void)al; /* shut gcc stupid warning */
273
274 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100275 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200276 return (s->strict_sni ?
277 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200278 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100279 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200280
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100281 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200282 if (!servername[i])
283 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100284 trash.str[i] = tolower(servername[i]);
285 if (!wildp && (trash.str[i] == '.'))
286 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200287 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100288 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200289
290 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100291 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200292
293 /* lookup a not neg filter */
294 for (n = node; n; n = ebmb_next_dup(n)) {
295 if (!container_of(n, struct sni_ctx, name)->neg) {
296 node = n;
297 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100298 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200299 }
300 if (!node && wildp) {
301 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200302 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200303 }
304 if (!node || container_of(node, struct sni_ctx, name)->neg) {
305 return (s->strict_sni ?
306 SSL_TLSEXT_ERR_ALERT_FATAL :
307 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200308 }
309
310 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200311 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200312 return SSL_TLSEXT_ERR_OK;
313}
314#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
315
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200316#ifndef OPENSSL_NO_DH
317/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
318 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +0200319int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200320{
321 int ret = -1;
322 BIO *in;
323 DH *dh = NULL;
Willy Tarreau6e774b42014-04-25 21:35:23 +0200324 /* If not present, use parameters generated using 'openssl dhparam 1024 -C':
325 * -----BEGIN DH PARAMETERS-----
326 * MIGHAoGBAJJAJDXDoS5E03MNjnjK36eOL1tRqVa/9NuOVlI+lpXmPjJQbP65EvKn
327 * fSLnG7VMhoCJO4KtG88zf393ltP7loGB2bofcDSr+x+XsxBM8yA/Zj6BmQt+CQ9s
328 * TF7hoOV+wXTT6ErZ5y5qx9pq6hLfKXwTGFT78hrE6HnCO7xgtPdTAgEC
329 * -----END DH PARAMETERS-----
330 */
331 static const unsigned char dh1024_p[] = {
332 0x92, 0x40, 0x24, 0x35, 0xC3, 0xA1, 0x2E, 0x44, 0xD3, 0x73, 0x0D, 0x8E,
333 0x78, 0xCA, 0xDF, 0xA7, 0x8E, 0x2F, 0x5B, 0x51, 0xA9, 0x56, 0xBF, 0xF4,
334 0xDB, 0x8E, 0x56, 0x52, 0x3E, 0x96, 0x95, 0xE6, 0x3E, 0x32, 0x50, 0x6C,
335 0xFE, 0xB9, 0x12, 0xF2, 0xA7, 0x7D, 0x22, 0xE7, 0x1B, 0xB5, 0x4C, 0x86,
336 0x80, 0x89, 0x3B, 0x82, 0xAD, 0x1B, 0xCF, 0x33, 0x7F, 0x7F, 0x77, 0x96,
337 0xD3, 0xFB, 0x96, 0x81, 0x81, 0xD9, 0xBA, 0x1F, 0x70, 0x34, 0xAB, 0xFB,
338 0x1F, 0x97, 0xB3, 0x10, 0x4C, 0xF3, 0x20, 0x3F, 0x66, 0x3E, 0x81, 0x99,
339 0x0B, 0x7E, 0x09, 0x0F, 0x6C, 0x4C, 0x5E, 0xE1, 0xA0, 0xE5, 0x7E, 0xC1,
340 0x74, 0xD3, 0xE8, 0x4A, 0xD9, 0xE7, 0x2E, 0x6A, 0xC7, 0xDA, 0x6A, 0xEA,
341 0x12, 0xDF, 0x29, 0x7C, 0x13, 0x18, 0x54, 0xFB, 0xF2, 0x1A, 0xC4, 0xE8,
342 0x79, 0xC2, 0x3B, 0xBC, 0x60, 0xB4, 0xF7, 0x53,
343 };
344 static const unsigned char dh1024_g[] = {
345 0x02,
346 };
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200347
348 in = BIO_new(BIO_s_file());
349 if (in == NULL)
350 goto end;
351
352 if (BIO_read_filename(in, file) <= 0)
353 goto end;
354
355 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Willy Tarreau6e774b42014-04-25 21:35:23 +0200356 if (!dh) {
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200357 /* Clear openssl global errors stack */
358 ERR_clear_error();
359
Willy Tarreau6e774b42014-04-25 21:35:23 +0200360 dh = DH_new();
361 if (dh == NULL)
362 goto end;
363
364 dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
365 if (dh->p == NULL)
366 goto end;
367
368 dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
369 if (dh->g == NULL)
370 goto end;
371
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200372 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200373 }
Willy Tarreau6e774b42014-04-25 21:35:23 +0200374 else
375 ret = 1;
376
377 SSL_CTX_set_tmp_dh(ctx, dh);
Emeric Brun644cde02012-12-14 11:21:13 +0100378
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200379end:
380 if (dh)
381 DH_free(dh);
382
383 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200384 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200385
386 return ret;
387}
388#endif
389
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200390static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100391{
392 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200393 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100394
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200395 if (*name == '!') {
396 neg = 1;
397 name++;
398 }
399 if (*name == '*') {
400 wild = 1;
401 name++;
402 }
403 /* !* filter is a nop */
404 if (neg && wild)
405 return order;
406 if (*name) {
407 int j, len;
408 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100409 sc = malloc(sizeof(struct sni_ctx) + len + 1);
410 for (j = 0; j < len; j++)
411 sc->name.key[j] = tolower(name[j]);
412 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100413 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200414 sc->order = order++;
415 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100416 if (wild)
417 ebst_insert(&s->sni_w_ctx, &sc->name);
418 else
419 ebst_insert(&s->sni_ctx, &sc->name);
420 }
421 return order;
422}
423
Emeric Brunfc0421f2012-09-07 17:30:07 +0200424/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
425 * an early error happens and the caller must call SSL_CTX_free() by itelf.
426 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200427static 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 +0200428{
429 BIO *in;
430 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200431 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200432 int ret = -1;
433 int order = 0;
434 X509_NAME *xname;
435 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200436#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
437 STACK_OF(GENERAL_NAME) *names;
438#endif
439
440 in = BIO_new(BIO_s_file());
441 if (in == NULL)
442 goto end;
443
444 if (BIO_read_filename(in, file) <= 0)
445 goto end;
446
447 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
448 if (x == NULL)
449 goto end;
450
Emeric Brun50bcecc2013-04-22 13:05:23 +0200451 if (fcount) {
452 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200453 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100454 }
455 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200456#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100457 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
458 if (names) {
459 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
460 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
461 if (name->type == GEN_DNS) {
462 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200463 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100464 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200465 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200466 }
467 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100468 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200469 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200470#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100471 xname = X509_get_subject_name(x);
472 i = -1;
473 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
474 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
475 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200476 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100477 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200478 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200479 }
480 }
481
482 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
483 if (!SSL_CTX_use_certificate(ctx, x))
484 goto end;
485
486 if (ctx->extra_certs != NULL) {
487 sk_X509_pop_free(ctx->extra_certs, X509_free);
488 ctx->extra_certs = NULL;
489 }
490
491 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
492 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
493 X509_free(ca);
494 goto end;
495 }
496 }
497
498 err = ERR_get_error();
499 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
500 /* we successfully reached the last cert in the file */
501 ret = 1;
502 }
503 ERR_clear_error();
504
505end:
506 if (x)
507 X509_free(x);
508
509 if (in)
510 BIO_free(in);
511
512 return ret;
513}
514
Emeric Brun50bcecc2013-04-22 13:05:23 +0200515static 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 +0200516{
517 int ret;
518 SSL_CTX *ctx;
519
520 ctx = SSL_CTX_new(SSLv23_server_method());
521 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200522 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
523 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200524 return 1;
525 }
526
527 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200528 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
529 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200530 SSL_CTX_free(ctx);
531 return 1;
532 }
533
Emeric Brun50bcecc2013-04-22 13:05:23 +0200534 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200535 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200536 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
537 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200538 if (ret < 0) /* serious error, must do that ourselves */
539 SSL_CTX_free(ctx);
540 return 1;
541 }
Emeric Brun61694ab2012-10-26 13:35:33 +0200542
543 if (SSL_CTX_check_private_key(ctx) <= 0) {
544 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
545 err && *err ? *err : "", path);
546 return 1;
547 }
548
Emeric Brunfc0421f2012-09-07 17:30:07 +0200549 /* we must not free the SSL_CTX anymore below, since it's already in
550 * the tree, so it will be discovered and cleaned in time.
551 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200552#ifndef OPENSSL_NO_DH
553 ret = ssl_sock_load_dh_params(ctx, path);
554 if (ret < 0) {
555 if (err)
556 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
557 *err ? *err : "", path);
558 return 1;
559 }
560#endif
561
Emeric Brunfc0421f2012-09-07 17:30:07 +0200562#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200563 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200564 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
565 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +0200566 return 1;
567 }
568#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200569 if (!bind_conf->default_ctx)
570 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200571
572 return 0;
573}
574
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200575int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200576{
577 struct dirent *de;
578 DIR *dir;
579 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +0100580 char *end;
581 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200582 int cfgerr = 0;
583
584 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +0200585 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200586
587 /* strip trailing slashes, including first one */
588 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
589 *end = 0;
590
Emeric Brunfc0421f2012-09-07 17:30:07 +0200591 while ((de = readdir(dir))) {
Willy Tarreauee2663b2012-12-06 11:36:59 +0100592 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200593 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200594 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
595 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +0200596 cfgerr++;
597 continue;
598 }
599 if (!S_ISREG(buf.st_mode))
600 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200601 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200602 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200603 closedir(dir);
604 return cfgerr;
605}
606
Thierry Fournier383085f2013-01-24 14:15:43 +0100607/* Make sure openssl opens /dev/urandom before the chroot. The work is only
608 * done once. Zero is returned if the operation fails. No error is returned
609 * if the random is said as not implemented, because we expect that openssl
610 * will use another method once needed.
611 */
612static int ssl_initialize_random()
613{
614 unsigned char random;
615 static int random_initialized = 0;
616
617 if (!random_initialized && RAND_bytes(&random, 1) != 0)
618 random_initialized = 1;
619
620 return random_initialized;
621}
622
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100623int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
624{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200625 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100626 FILE *f;
627 int linenum = 0;
628 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100629
Willy Tarreauad1731d2013-04-02 17:35:58 +0200630 if ((f = fopen(file, "r")) == NULL) {
631 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100632 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200633 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100634
635 while (fgets(thisline, sizeof(thisline), f) != NULL) {
636 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200637 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100638 char *end;
639 char *args[MAX_LINE_ARGS + 1];
640 char *line = thisline;
641
642 linenum++;
643 end = line + strlen(line);
644 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
645 /* Check if we reached the limit and the last char is not \n.
646 * Watch out for the last line without the terminating '\n'!
647 */
Willy Tarreauad1731d2013-04-02 17:35:58 +0200648 memprintf(err, "line %d too long in file '%s', limit is %d characters",
649 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100650 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200651 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100652 }
653
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100654 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200655 newarg = 1;
656 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100657 if (*line == '#' || *line == '\n' || *line == '\r') {
658 /* end of string, end of loop */
659 *line = 0;
660 break;
661 }
662 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +0200663 newarg = 1;
664 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100665 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200666 else if (newarg) {
667 if (arg == MAX_LINE_ARGS) {
668 memprintf(err, "too many args on line %d in file '%s'.",
669 linenum, file);
670 cfgerr = 1;
671 break;
672 }
673 newarg = 0;
674 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100675 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200676 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100677 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200678 if (cfgerr)
679 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200680
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100681 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +0200682 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100683 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100684
Emeric Brun50bcecc2013-04-22 13:05:23 +0200685 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +0200686 if (cfgerr) {
687 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100688 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200689 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100690 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100691 fclose(f);
692 return cfgerr;
693}
694
Emeric Brunfc0421f2012-09-07 17:30:07 +0200695#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
696#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
697#endif
698
699#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
700#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +0100701#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +0200702#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200703#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
704#define SSL_OP_SINGLE_ECDH_USE 0
705#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +0200706#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
707#define SSL_OP_NO_TICKET 0
708#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200709#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
710#define SSL_OP_NO_COMPRESSION 0
711#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +0200712#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
713#define SSL_OP_NO_TLSv1_1 0
714#endif
715#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
716#define SSL_OP_NO_TLSv1_2 0
717#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200718#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
719#define SSL_OP_SINGLE_DH_USE 0
720#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200721#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
722#define SSL_OP_SINGLE_ECDH_USE 0
723#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200724#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
725#define SSL_MODE_RELEASE_BUFFERS 0
726#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200727int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200728{
729 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +0100730 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +0200731 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +0200732 SSL_OP_ALL | /* all known workarounds for bugs */
733 SSL_OP_NO_SSLv2 |
734 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200735 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +0200736 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +0200737 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
738 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +0200739 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +0200740 SSL_MODE_ENABLE_PARTIAL_WRITE |
741 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
742 SSL_MODE_RELEASE_BUFFERS;
743
Thierry Fournier383085f2013-01-24 14:15:43 +0100744 /* Make sure openssl opens /dev/urandom before the chroot */
745 if (!ssl_initialize_random()) {
746 Alert("OpenSSL random data generator initialization failed.\n");
747 cfgerr++;
748 }
749
Emeric Brun89675492012-10-05 13:48:26 +0200750 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200751 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +0200752 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200753 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +0200754 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200755 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +0200756 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200757 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +0200758 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +0200759 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +0200760 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
761 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
762 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
763 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
764#if SSL_OP_NO_TLSv1_1
765 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
766 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
767#endif
768#if SSL_OP_NO_TLSv1_2
769 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
770 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
771#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200772
773 SSL_CTX_set_options(ctx, ssloptions);
774 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +0100775 switch (bind_conf->verify) {
776 case SSL_SOCK_VERIFY_NONE:
777 verify = SSL_VERIFY_NONE;
778 break;
779 case SSL_SOCK_VERIFY_OPTIONAL:
780 verify = SSL_VERIFY_PEER;
781 break;
782 case SSL_SOCK_VERIFY_REQUIRED:
783 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
784 break;
785 }
786 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
787 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +0200788 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200789 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200790 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200791 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200792 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200793 cfgerr++;
794 }
795 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200796 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +0200797 }
Emeric Brun850efd52014-01-29 12:24:34 +0100798 else {
799 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
800 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
801 cfgerr++;
802 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200803#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +0200804 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200805 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
806
Emeric Brunfb510ea2012-10-05 12:00:26 +0200807 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200808 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200809 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200810 cfgerr++;
811 }
Emeric Brun561e5742012-10-02 15:20:55 +0200812 else {
813 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
814 }
Emeric Brund94b3fe2012-09-20 18:23:56 +0200815 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200816#endif
Emeric Brun644cde02012-12-14 11:21:13 +0100817 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +0200818 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200819
Emeric Brun4f65bff2012-11-16 15:11:00 +0100820 if (global.tune.ssllifetime)
821 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
822
Emeric Brunfc0421f2012-09-07 17:30:07 +0200823 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200824 if (bind_conf->ciphers &&
825 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200826 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 +0200827 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200828 cfgerr++;
829 }
830
831 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +0200832#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +0200833 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +0200834#endif
Emeric Brun29f037d2014-04-25 19:05:36 +0200835
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;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +0200998 long options =
Emeric Brun94324a42012-10-11 14:00:19 +0200999 SSL_OP_ALL | /* all known workarounds for bugs */
1000 SSL_OP_NO_SSLv2 |
1001 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001002 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001003 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
David Safb76832014-05-08 23:42:08 -04001874char *ssl_sock_get_version(struct connection *conn)
1875{
1876 if (!ssl_sock_is_ssl(conn))
1877 return NULL;
1878
1879 return (char *)SSL_get_version(conn->xprt_ctx);
1880}
1881
1882/* returns common name, NULL terminated, from client certificate, or NULL if none */
1883char *ssl_sock_get_common_name(struct connection *conn)
1884{
1885 X509 *crt = NULL;
1886 X509_NAME *name;
1887 struct chunk *cn_trash;
1888 const char find_cn[] = "CN";
1889 const struct chunk find_cn_chunk = {
1890 .str = (char *)&find_cn,
1891 .len = sizeof(find_cn)-1
1892 };
1893 char *result = NULL;
1894
1895 if (!ssl_sock_is_ssl(conn))
1896 return NULL;
1897
1898 /* SSL_get_peer_certificate, it increase X509 * ref count */
1899 crt = SSL_get_peer_certificate(conn->xprt_ctx);
1900 if (!crt)
1901 goto out;
1902
1903 name = X509_get_subject_name(crt);
1904 if (!name)
1905 goto out;
1906
1907 cn_trash = get_trash_chunk();
1908 if (ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, cn_trash) <= 0)
1909 goto out;
1910 cn_trash->str[cn_trash->len] = '\0';
1911 result = cn_trash->str;
1912
1913 out:
1914 if (crt)
1915 X509_free(crt);
1916
1917 return result;
1918}
1919
1920/* returns 1 if client passed a certificate, 0 if not */
1921int ssl_sock_get_cert_used(struct connection *conn)
1922{
1923 if (!ssl_sock_is_ssl(conn))
1924 return 0;
1925
1926 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
1927}
1928
1929/* returns result from SSL verify */
1930unsigned int ssl_sock_get_verify_result(struct connection *conn)
1931{
1932 if (!ssl_sock_is_ssl(conn))
1933 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
1934
1935 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
1936}
1937
Willy Tarreau7875d092012-09-10 08:20:03 +02001938/***** Below are some sample fetching functions for ACL/patterns *****/
1939
Emeric Brune64aef12012-09-21 13:15:06 +02001940/* boolean, returns true if client cert was present */
1941static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02001942smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001943 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02001944{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001945 struct connection *conn;
1946
1947 if (!l4)
1948 return 0;
1949
1950 conn = objt_conn(l4->si[0].end);
1951 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02001952 return 0;
1953
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001954 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02001955 smp->flags |= SMP_F_MAY_CHANGE;
1956 return 0;
1957 }
1958
1959 smp->flags = 0;
1960 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001961 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001962
1963 return 1;
1964}
1965
Emeric Brunba841a12014-04-30 17:05:08 +02001966/* binary, returns serial of certificate in a binary chunk.
1967 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
1968 * should be use.
1969 */
Willy Tarreau8d598402012-10-22 17:58:39 +02001970static int
Emeric Brunba841a12014-04-30 17:05:08 +02001971smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001972 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02001973{
Emeric Brunba841a12014-04-30 17:05:08 +02001974 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001975 X509 *crt = NULL;
1976 int ret = 0;
1977 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001978 struct connection *conn;
1979
1980 if (!l4)
1981 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001982
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001983 conn = objt_conn(l4->si[0].end);
1984 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02001985 return 0;
1986
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001987 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02001988 smp->flags |= SMP_F_MAY_CHANGE;
1989 return 0;
1990 }
1991
Emeric Brunba841a12014-04-30 17:05:08 +02001992 if (cert_peer)
1993 crt = SSL_get_peer_certificate(conn->xprt_ctx);
1994 else
1995 crt = SSL_get_certificate(conn->xprt_ctx);
1996
Willy Tarreau8d598402012-10-22 17:58:39 +02001997 if (!crt)
1998 goto out;
1999
Willy Tarreau47ca5452012-12-23 20:22:19 +01002000 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002001 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2002 goto out;
2003
2004 smp->data.str = *smp_trash;
2005 smp->type = SMP_T_BIN;
2006 ret = 1;
2007out:
Emeric Brunba841a12014-04-30 17:05:08 +02002008 /* SSL_get_peer_certificate, it increase X509 * ref count */
2009 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002010 X509_free(crt);
2011 return ret;
2012}
Emeric Brune64aef12012-09-21 13:15:06 +02002013
Emeric Brunba841a12014-04-30 17:05:08 +02002014/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2015 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2016 * should be use.
2017 */
James Votha051b4a2013-05-14 20:37:59 +02002018static int
Emeric Brunba841a12014-04-30 17:05:08 +02002019smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002020 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002021{
Emeric Brunba841a12014-04-30 17:05:08 +02002022 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002023 X509 *crt = NULL;
2024 const EVP_MD *digest;
2025 int ret = 0;
2026 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002027 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002028
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002029 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002030 return 0;
2031
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002032 conn = objt_conn(l4->si[0].end);
2033 if (!conn || conn->xprt != &ssl_sock)
2034 return 0;
2035
2036 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002037 smp->flags |= SMP_F_MAY_CHANGE;
2038 return 0;
2039 }
2040
Emeric Brunba841a12014-04-30 17:05:08 +02002041 if (cert_peer)
2042 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2043 else
2044 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002045 if (!crt)
2046 goto out;
2047
2048 smp_trash = get_trash_chunk();
2049 digest = EVP_sha1();
2050 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2051
2052 smp->data.str = *smp_trash;
2053 smp->type = SMP_T_BIN;
2054 ret = 1;
2055out:
Emeric Brunba841a12014-04-30 17:05:08 +02002056 /* SSL_get_peer_certificate, it increase X509 * ref count */
2057 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002058 X509_free(crt);
2059 return ret;
2060}
2061
Emeric Brunba841a12014-04-30 17:05:08 +02002062/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2063 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2064 * should be use.
2065 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002066static int
Emeric Brunba841a12014-04-30 17:05:08 +02002067smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002068 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002069{
Emeric Brunba841a12014-04-30 17:05:08 +02002070 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002071 X509 *crt = NULL;
2072 int ret = 0;
2073 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002074 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002075
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002076 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002077 return 0;
2078
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002079 conn = objt_conn(l4->si[0].end);
2080 if (!conn || conn->xprt != &ssl_sock)
2081 return 0;
2082
2083 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002084 smp->flags |= SMP_F_MAY_CHANGE;
2085 return 0;
2086 }
2087
Emeric Brunba841a12014-04-30 17:05:08 +02002088 if (cert_peer)
2089 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2090 else
2091 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002092 if (!crt)
2093 goto out;
2094
Willy Tarreau47ca5452012-12-23 20:22:19 +01002095 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002096 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2097 goto out;
2098
2099 smp->data.str = *smp_trash;
2100 smp->type = SMP_T_STR;
2101 ret = 1;
2102out:
Emeric Brunba841a12014-04-30 17:05:08 +02002103 /* SSL_get_peer_certificate, it increase X509 * ref count */
2104 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002105 X509_free(crt);
2106 return ret;
2107}
2108
Emeric Brunba841a12014-04-30 17:05:08 +02002109/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2110 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2111 * should be use.
2112 */
Emeric Brun87855892012-10-17 17:39:35 +02002113static int
Emeric Brunba841a12014-04-30 17:05:08 +02002114smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002115 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002116{
Emeric Brunba841a12014-04-30 17:05:08 +02002117 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002118 X509 *crt = NULL;
2119 X509_NAME *name;
2120 int ret = 0;
2121 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002122 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002123
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002124 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002125 return 0;
2126
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002127 conn = objt_conn(l4->si[0].end);
2128 if (!conn || conn->xprt != &ssl_sock)
2129 return 0;
2130
2131 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002132 smp->flags |= SMP_F_MAY_CHANGE;
2133 return 0;
2134 }
2135
Emeric Brunba841a12014-04-30 17:05:08 +02002136 if (cert_peer)
2137 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2138 else
2139 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002140 if (!crt)
2141 goto out;
2142
2143 name = X509_get_issuer_name(crt);
2144 if (!name)
2145 goto out;
2146
Willy Tarreau47ca5452012-12-23 20:22:19 +01002147 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002148 if (args && args[0].type == ARGT_STR) {
2149 int pos = 1;
2150
2151 if (args[1].type == ARGT_SINT)
2152 pos = args[1].data.sint;
2153 else if (args[1].type == ARGT_UINT)
2154 pos =(int)args[1].data.uint;
2155
2156 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2157 goto out;
2158 }
2159 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2160 goto out;
2161
2162 smp->type = SMP_T_STR;
2163 smp->data.str = *smp_trash;
2164 ret = 1;
2165out:
Emeric Brunba841a12014-04-30 17:05:08 +02002166 /* SSL_get_peer_certificate, it increase X509 * ref count */
2167 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002168 X509_free(crt);
2169 return ret;
2170}
2171
Emeric Brunba841a12014-04-30 17:05:08 +02002172/* string, returns notbefore date in ASN1_UTCTIME format.
2173 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2174 * should be use.
2175 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002176static int
Emeric Brunba841a12014-04-30 17:05:08 +02002177smp_fetch_ssl_x_notbefore(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 Brunce5ad802012-10-22 14:11:22 +02002179{
Emeric Brunba841a12014-04-30 17:05:08 +02002180 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002181 X509 *crt = NULL;
2182 int ret = 0;
2183 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002184 struct connection *conn;
2185
2186 if (!l4)
2187 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002188
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002189 conn = objt_conn(l4->si[0].end);
2190 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002191 return 0;
2192
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002193 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002194 smp->flags |= SMP_F_MAY_CHANGE;
2195 return 0;
2196 }
2197
Emeric Brunba841a12014-04-30 17:05:08 +02002198 if (cert_peer)
2199 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2200 else
2201 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002202 if (!crt)
2203 goto out;
2204
Willy Tarreau47ca5452012-12-23 20:22:19 +01002205 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002206 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2207 goto out;
2208
2209 smp->data.str = *smp_trash;
2210 smp->type = SMP_T_STR;
2211 ret = 1;
2212out:
Emeric Brunba841a12014-04-30 17:05:08 +02002213 /* SSL_get_peer_certificate, it increase X509 * ref count */
2214 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002215 X509_free(crt);
2216 return ret;
2217}
2218
Emeric Brunba841a12014-04-30 17:05:08 +02002219/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
2220 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2221 * should be use.
2222 */
Emeric Brun87855892012-10-17 17:39:35 +02002223static int
Emeric Brunba841a12014-04-30 17:05:08 +02002224smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002225 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002226{
Emeric Brunba841a12014-04-30 17:05:08 +02002227 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002228 X509 *crt = NULL;
2229 X509_NAME *name;
2230 int ret = 0;
2231 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002232 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002233
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002234 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002235 return 0;
2236
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002237 conn = objt_conn(l4->si[0].end);
2238 if (!conn || conn->xprt != &ssl_sock)
2239 return 0;
2240
2241 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002242 smp->flags |= SMP_F_MAY_CHANGE;
2243 return 0;
2244 }
2245
Emeric Brunba841a12014-04-30 17:05:08 +02002246 if (cert_peer)
2247 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2248 else
2249 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002250 if (!crt)
2251 goto out;
2252
2253 name = X509_get_subject_name(crt);
2254 if (!name)
2255 goto out;
2256
Willy Tarreau47ca5452012-12-23 20:22:19 +01002257 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002258 if (args && args[0].type == ARGT_STR) {
2259 int pos = 1;
2260
2261 if (args[1].type == ARGT_SINT)
2262 pos = args[1].data.sint;
2263 else if (args[1].type == ARGT_UINT)
2264 pos =(int)args[1].data.uint;
2265
2266 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2267 goto out;
2268 }
2269 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2270 goto out;
2271
2272 smp->type = SMP_T_STR;
2273 smp->data.str = *smp_trash;
2274 ret = 1;
2275out:
Emeric Brunba841a12014-04-30 17:05:08 +02002276 /* SSL_get_peer_certificate, it increase X509 * ref count */
2277 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002278 X509_free(crt);
2279 return ret;
2280}
Emeric Brun9143d372012-12-20 15:44:16 +01002281
2282/* integer, returns true if current session use a client certificate */
2283static int
2284smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002285 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01002286{
2287 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002288 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01002289
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002290 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01002291 return 0;
2292
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002293 conn = objt_conn(l4->si[0].end);
2294 if (!conn || conn->xprt != &ssl_sock)
2295 return 0;
2296
2297 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01002298 smp->flags |= SMP_F_MAY_CHANGE;
2299 return 0;
2300 }
2301
2302 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002303 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01002304 if (crt) {
2305 X509_free(crt);
2306 }
2307
2308 smp->type = SMP_T_BOOL;
2309 smp->data.uint = (crt != NULL);
2310 return 1;
2311}
2312
Emeric Brunba841a12014-04-30 17:05:08 +02002313/* integer, returns the certificate version
2314 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2315 * should be use.
2316 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02002317static int
Emeric Brunba841a12014-04-30 17:05:08 +02002318smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002319 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002320{
Emeric Brunba841a12014-04-30 17:05:08 +02002321 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002322 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002323 struct connection *conn;
2324
2325 if (!l4)
2326 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002327
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002328 conn = objt_conn(l4->si[0].end);
2329 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002330 return 0;
2331
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002332 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002333 smp->flags |= SMP_F_MAY_CHANGE;
2334 return 0;
2335 }
2336
Emeric Brunba841a12014-04-30 17:05:08 +02002337 if (cert_peer)
2338 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2339 else
2340 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002341 if (!crt)
2342 return 0;
2343
2344 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02002345 /* SSL_get_peer_certificate increase X509 * ref count */
2346 if (cert_peer)
2347 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002348 smp->type = SMP_T_UINT;
2349
2350 return 1;
2351}
2352
Emeric Brunba841a12014-04-30 17:05:08 +02002353/* string, returns the certificate's signature algorithm.
2354 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2355 * should be use.
2356 */
Emeric Brun7f56e742012-10-19 18:15:40 +02002357static int
Emeric Brunba841a12014-04-30 17:05:08 +02002358smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002359 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002360{
Emeric Brunba841a12014-04-30 17:05:08 +02002361 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02002362 X509 *crt;
2363 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002364 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002365
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002366 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002367 return 0;
2368
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002369 conn = objt_conn(l4->si[0].end);
2370 if (!conn || conn->xprt != &ssl_sock)
2371 return 0;
2372
2373 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002374 smp->flags |= SMP_F_MAY_CHANGE;
2375 return 0;
2376 }
2377
Emeric Brunba841a12014-04-30 17:05:08 +02002378 if (cert_peer)
2379 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2380 else
2381 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002382 if (!crt)
2383 return 0;
2384
2385 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2386
2387 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002388 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02002389 /* SSL_get_peer_certificate increase X509 * ref count */
2390 if (cert_peer)
2391 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002392 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002393 }
Emeric Brun7f56e742012-10-19 18:15:40 +02002394
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002395 smp->type = SMP_T_STR;
2396 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002397 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02002398 /* SSL_get_peer_certificate increase X509 * ref count */
2399 if (cert_peer)
2400 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002401
2402 return 1;
2403}
2404
Emeric Brunba841a12014-04-30 17:05:08 +02002405/* string, returns the certificate's key algorithm.
2406 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2407 * should be use.
2408 */
Emeric Brun521a0112012-10-22 12:22:55 +02002409static int
Emeric Brunba841a12014-04-30 17:05:08 +02002410smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002411 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002412{
Emeric Brunba841a12014-04-30 17:05:08 +02002413 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02002414 X509 *crt;
2415 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002416 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02002417
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002418 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02002419 return 0;
2420
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002421 conn = objt_conn(l4->si[0].end);
2422 if (!conn || conn->xprt != &ssl_sock)
2423 return 0;
2424
2425 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002426 smp->flags |= SMP_F_MAY_CHANGE;
2427 return 0;
2428 }
2429
Emeric Brunba841a12014-04-30 17:05:08 +02002430 if (cert_peer)
2431 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2432 else
2433 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002434 if (!crt)
2435 return 0;
2436
2437 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2438
2439 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002440 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02002441 /* SSL_get_peer_certificate increase X509 * ref count */
2442 if (cert_peer)
2443 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002444 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002445 }
Emeric Brun521a0112012-10-22 12:22:55 +02002446
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002447 smp->type = SMP_T_STR;
2448 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002449 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02002450 if (cert_peer)
2451 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002452
2453 return 1;
2454}
2455
Emeric Brun645ae792014-04-30 14:21:06 +02002456/* boolean, returns true if front conn. transport layer is SSL.
2457 * This function is also usable on backend conn if the fetch keyword 5th
2458 * char is 'b'.
2459 */
Willy Tarreau7875d092012-09-10 08:20:03 +02002460static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002461smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002462 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002463{
Emeric Brun645ae792014-04-30 14:21:06 +02002464 int back_conn = (kw[4] == 'b') ? 1 : 0;
2465 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002466
Willy Tarreau7875d092012-09-10 08:20:03 +02002467 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002468 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02002469 return 1;
2470}
2471
Emeric Brun2525b6b2012-10-18 15:59:43 +02002472/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02002473static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002474smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002475 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002476{
2477#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002478 struct connection *conn = objt_conn(l4->si[0].end);
2479
Willy Tarreau7875d092012-09-10 08:20:03 +02002480 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002481 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
2482 conn->xprt_ctx &&
2483 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02002484 return 1;
2485#else
2486 return 0;
2487#endif
2488}
2489
Emeric Brun645ae792014-04-30 14:21:06 +02002490/* string, returns the used cipher if front conn. transport layer is SSL.
2491 * This function is also usable on backend conn if the fetch keyword 5th
2492 * char is 'b'.
2493 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002494static int
2495smp_fetch_ssl_fc_cipher(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 Brun589fcad2012-10-16 14:13:26 +02002497{
Emeric Brun645ae792014-04-30 14:21:06 +02002498 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002499 struct connection *conn;
2500
Emeric Brun589fcad2012-10-16 14:13:26 +02002501 smp->flags = 0;
2502
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002503 if (!l4)
2504 return 0;
2505
Emeric Brun645ae792014-04-30 14:21:06 +02002506 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002507 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002508 return 0;
2509
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002510 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002511 if (!smp->data.str.str)
2512 return 0;
2513
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002514 smp->type = SMP_T_STR;
2515 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002516 smp->data.str.len = strlen(smp->data.str.str);
2517
2518 return 1;
2519}
2520
Emeric Brun645ae792014-04-30 14:21:06 +02002521/* integer, returns the algoritm's keysize if front conn. transport layer
2522 * is SSL.
2523 * This function is also usable on backend conn if the fetch keyword 5th
2524 * char is 'b'.
2525 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002526static int
2527smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002528 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002529{
Emeric Brun645ae792014-04-30 14:21:06 +02002530 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002531 struct connection *conn;
2532
Emeric Brun589fcad2012-10-16 14:13:26 +02002533 smp->flags = 0;
2534
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002535 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002536 return 0;
2537
Emeric Brun645ae792014-04-30 14:21:06 +02002538 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002539 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002540 return 0;
2541
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002542 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
2543 return 0;
2544
Emeric Brun589fcad2012-10-16 14:13:26 +02002545 smp->type = SMP_T_UINT;
2546
2547 return 1;
2548}
2549
Emeric Brun645ae792014-04-30 14:21:06 +02002550/* integer, returns the used keysize if front conn. transport layer is SSL.
2551 * This function is also usable on backend conn if the fetch keyword 5th
2552 * char is 'b'.
2553 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002554static int
2555smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002556 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002557{
Emeric Brun645ae792014-04-30 14:21:06 +02002558 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002559 struct connection *conn;
2560
Emeric Brun589fcad2012-10-16 14:13:26 +02002561 smp->flags = 0;
2562
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002563 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002564 return 0;
2565
Emeric Brun645ae792014-04-30 14:21:06 +02002566 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002567 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2568 return 0;
2569
2570 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02002571 if (!smp->data.uint)
2572 return 0;
2573
2574 smp->type = SMP_T_UINT;
2575
2576 return 1;
2577}
2578
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002579#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02002580static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002581smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002582 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002583{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002584 struct connection *conn;
2585
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002586 smp->flags = SMP_F_CONST;
2587 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002588
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002589 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002590 return 0;
2591
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002592 conn = objt_conn(l4->si[0].end);
2593 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2594 return 0;
2595
Willy Tarreaua33c6542012-10-15 13:19:06 +02002596 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002597 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02002598 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2599
2600 if (!smp->data.str.str)
2601 return 0;
2602
2603 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002604}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002605#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02002606
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002607#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002608static int
2609smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002610 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02002611{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002612 struct connection *conn;
2613
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002614 smp->flags = SMP_F_CONST;
2615 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02002616
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002617 if (!l4)
2618 return 0;
2619
2620 conn = objt_conn(l4->si[0].end);
2621 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02002622 return 0;
2623
2624 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002625 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02002626 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2627
2628 if (!smp->data.str.str)
2629 return 0;
2630
2631 return 1;
2632}
2633#endif
2634
Emeric Brun645ae792014-04-30 14:21:06 +02002635/* string, returns the used protocol if front conn. transport layer is SSL.
2636 * This function is also usable on backend conn if the fetch keyword 5th
2637 * char is 'b'.
2638 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02002639static int
Emeric Brun589fcad2012-10-16 14:13:26 +02002640smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002641 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002642{
Emeric Brun645ae792014-04-30 14:21:06 +02002643 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002644 struct connection *conn;
2645
Emeric Brun589fcad2012-10-16 14:13:26 +02002646 smp->flags = 0;
2647
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002648 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002649 return 0;
2650
Emeric Brun645ae792014-04-30 14:21:06 +02002651 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002652 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2653 return 0;
2654
2655 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002656 if (!smp->data.str.str)
2657 return 0;
2658
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002659 smp->type = SMP_T_STR;
2660 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002661 smp->data.str.len = strlen(smp->data.str.str);
2662
2663 return 1;
2664}
2665
Emeric Brun645ae792014-04-30 14:21:06 +02002666/* binary, returns the SSL session id if front conn. transport layer is SSL.
2667 * This function is also usable on backend conn if the fetch keyword 5th
2668 * char is 'b'.
2669 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002670static int
Emeric Brunfe68f682012-10-16 14:59:28 +02002671smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002672 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02002673{
2674#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02002675 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02002676 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002677 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02002678
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002679 smp->flags = SMP_F_CONST;
2680 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02002681
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002682 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02002683 return 0;
2684
Emeric Brun645ae792014-04-30 14:21:06 +02002685 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002686 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2687 return 0;
2688
2689 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02002690 if (!sess)
2691 return 0;
2692
2693 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
2694 if (!smp->data.str.str || !&smp->data.str.len)
2695 return 0;
2696
2697 return 1;
2698#else
2699 return 0;
2700#endif
2701}
2702
2703static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002704smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002705 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002706{
2707#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002708 struct connection *conn;
2709
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002710 smp->flags = SMP_F_CONST;
2711 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02002712
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002713 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02002714 return 0;
2715
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002716 conn = objt_conn(l4->si[0].end);
2717 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2718 return 0;
2719
2720 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02002721 if (!smp->data.str.str)
2722 return 0;
2723
Willy Tarreau7875d092012-09-10 08:20:03 +02002724 smp->data.str.len = strlen(smp->data.str.str);
2725 return 1;
2726#else
2727 return 0;
2728#endif
2729}
2730
David Sc1ad52e2014-04-08 18:48:47 -04002731static int
2732smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2733 const struct arg *args, struct sample *smp, const char *kw)
2734{
2735#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02002736 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04002737 struct connection *conn;
2738 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04002739 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04002740
2741 smp->flags = 0;
2742
2743 if (!l4)
2744 return 0;
2745
Emeric Brun645ae792014-04-30 14:21:06 +02002746 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04002747 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2748 return 0;
2749
2750 if (!(conn->flags & CO_FL_CONNECTED)) {
2751 smp->flags |= SMP_F_MAY_CHANGE;
2752 return 0;
2753 }
2754
2755 finished_trash = get_trash_chunk();
2756 if (!SSL_session_reused(conn->xprt_ctx))
2757 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2758 else
2759 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2760
2761 if (!finished_len)
2762 return 0;
2763
Emeric Brunb73a9b02014-04-30 18:49:19 +02002764 finished_trash->len = finished_len;
2765 smp->data.str = *finished_trash;
2766 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04002767
2768 return 1;
2769#else
2770 return 0;
2771#endif
2772}
2773
Emeric Brun2525b6b2012-10-18 15:59:43 +02002774/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002775static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002776smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002777 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002778{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002779 struct connection *conn;
2780
2781 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002782 return 0;
2783
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002784 conn = objt_conn(l4->si[0].end);
2785 if (!conn || conn->xprt != &ssl_sock)
2786 return 0;
2787
2788 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002789 smp->flags = SMP_F_MAY_CHANGE;
2790 return 0;
2791 }
2792
2793 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002794 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002795 smp->flags = 0;
2796
2797 return 1;
2798}
2799
Emeric Brun2525b6b2012-10-18 15:59:43 +02002800/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002801static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002802smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002803 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002804{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002805 struct connection *conn;
2806
2807 if (!l4)
2808 return 0;
2809
2810 conn = objt_conn(l4->si[0].end);
2811 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02002812 return 0;
2813
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002814 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002815 smp->flags = SMP_F_MAY_CHANGE;
2816 return 0;
2817 }
2818
2819 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002820 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002821 smp->flags = 0;
2822
2823 return 1;
2824}
2825
Emeric Brun2525b6b2012-10-18 15:59:43 +02002826/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02002827static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002828smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002829 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002830{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002831 struct connection *conn;
2832
2833 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002834 return 0;
2835
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002836 conn = objt_conn(l4->si[0].end);
2837 if (!conn || conn->xprt != &ssl_sock)
2838 return 0;
2839
2840 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002841 smp->flags = SMP_F_MAY_CHANGE;
2842 return 0;
2843 }
2844
2845 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002846 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002847 smp->flags = 0;
2848
2849 return 1;
2850}
2851
Emeric Brun2525b6b2012-10-18 15:59:43 +02002852/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002853static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002854smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002855 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002856{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002857 struct connection *conn;
2858
2859 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002860 return 0;
2861
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002862 conn = objt_conn(l4->si[0].end);
2863 if (!conn || conn->xprt != &ssl_sock)
2864 return 0;
2865
2866 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002867 smp->flags = SMP_F_MAY_CHANGE;
2868 return 0;
2869 }
2870
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002871 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002872 return 0;
2873
2874 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002875 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002876 smp->flags = 0;
2877
2878 return 1;
2879}
2880
Emeric Brunfb510ea2012-10-05 12:00:26 +02002881/* parse the "ca-file" bind keyword */
2882static 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 +02002883{
2884 if (!*args[cur_arg + 1]) {
2885 if (err)
2886 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
2887 return ERR_ALERT | ERR_FATAL;
2888 }
2889
Emeric Brunef42d922012-10-11 16:11:36 +02002890 if ((*args[cur_arg + 1] != '/') && global.ca_base)
2891 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
2892 else
2893 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002894
Emeric Brund94b3fe2012-09-20 18:23:56 +02002895 return 0;
2896}
2897
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002898/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002899static 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 +02002900{
2901 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002902 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002903 return ERR_ALERT | ERR_FATAL;
2904 }
2905
Emeric Brun76d88952012-10-05 15:47:31 +02002906 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002907 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002908 return 0;
2909}
2910
2911/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002912static 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 +02002913{
Willy Tarreau38011032013-08-13 16:59:39 +02002914 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02002915
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002916 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002917 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002918 return ERR_ALERT | ERR_FATAL;
2919 }
2920
Emeric Brunc8e8d122012-10-02 18:42:10 +02002921 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02002922 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02002923 memprintf(err, "'%s' : path too long", args[cur_arg]);
2924 return ERR_ALERT | ERR_FATAL;
2925 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02002926 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002927 if (ssl_sock_load_cert(path, conf, px, err) > 0)
2928 return ERR_ALERT | ERR_FATAL;
2929
2930 return 0;
2931 }
2932
Willy Tarreau4348fad2012-09-20 16:48:07 +02002933 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002934 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02002935
2936 return 0;
2937}
2938
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002939/* parse the "crt-list" bind keyword */
2940static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2941{
2942 if (!*args[cur_arg + 1]) {
2943 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
2944 return ERR_ALERT | ERR_FATAL;
2945 }
2946
Willy Tarreauad1731d2013-04-02 17:35:58 +02002947 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
2948 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002949 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002950 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002951
2952 return 0;
2953}
2954
Emeric Brunfb510ea2012-10-05 12:00:26 +02002955/* parse the "crl-file" bind keyword */
2956static 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 +02002957{
Emeric Brun051cdab2012-10-02 19:25:50 +02002958#ifndef X509_V_FLAG_CRL_CHECK
2959 if (err)
2960 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
2961 return ERR_ALERT | ERR_FATAL;
2962#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02002963 if (!*args[cur_arg + 1]) {
2964 if (err)
2965 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
2966 return ERR_ALERT | ERR_FATAL;
2967 }
Emeric Brun2b58d042012-09-20 17:10:03 +02002968
Emeric Brunef42d922012-10-11 16:11:36 +02002969 if ((*args[cur_arg + 1] != '/') && global.ca_base)
2970 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
2971 else
2972 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002973
Emeric Brun2b58d042012-09-20 17:10:03 +02002974 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02002975#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002976}
2977
2978/* parse the "ecdhe" bind keyword keywords */
2979static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2980{
2981#if OPENSSL_VERSION_NUMBER < 0x0090800fL
2982 if (err)
2983 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
2984 return ERR_ALERT | ERR_FATAL;
2985#elif defined(OPENSSL_NO_ECDH)
2986 if (err)
2987 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
2988 return ERR_ALERT | ERR_FATAL;
2989#else
2990 if (!*args[cur_arg + 1]) {
2991 if (err)
2992 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
2993 return ERR_ALERT | ERR_FATAL;
2994 }
2995
2996 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002997
2998 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02002999#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003000}
3001
Emeric Brun81c00f02012-09-21 14:31:21 +02003002/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3003static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3004{
3005 int code;
3006 char *p = args[cur_arg + 1];
3007 unsigned long long *ignerr = &conf->crt_ignerr;
3008
3009 if (!*p) {
3010 if (err)
3011 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3012 return ERR_ALERT | ERR_FATAL;
3013 }
3014
3015 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3016 ignerr = &conf->ca_ignerr;
3017
3018 if (strcmp(p, "all") == 0) {
3019 *ignerr = ~0ULL;
3020 return 0;
3021 }
3022
3023 while (p) {
3024 code = atoi(p);
3025 if ((code <= 0) || (code > 63)) {
3026 if (err)
3027 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3028 args[cur_arg], code, args[cur_arg + 1]);
3029 return ERR_ALERT | ERR_FATAL;
3030 }
3031 *ignerr |= 1ULL << code;
3032 p = strchr(p, ',');
3033 if (p)
3034 p++;
3035 }
3036
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003037 return 0;
3038}
3039
3040/* parse the "force-sslv3" bind keyword */
3041static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3042{
3043 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3044 return 0;
3045}
3046
3047/* parse the "force-tlsv10" bind keyword */
3048static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3049{
3050 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003051 return 0;
3052}
3053
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003054/* parse the "force-tlsv11" bind keyword */
3055static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3056{
3057#if SSL_OP_NO_TLSv1_1
3058 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3059 return 0;
3060#else
3061 if (err)
3062 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3063 return ERR_ALERT | ERR_FATAL;
3064#endif
3065}
3066
3067/* parse the "force-tlsv12" bind keyword */
3068static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3069{
3070#if SSL_OP_NO_TLSv1_2
3071 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3072 return 0;
3073#else
3074 if (err)
3075 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3076 return ERR_ALERT | ERR_FATAL;
3077#endif
3078}
3079
3080
Emeric Brun2d0c4822012-10-02 13:45:20 +02003081/* parse the "no-tls-tickets" bind keyword */
3082static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3083{
Emeric Brun89675492012-10-05 13:48:26 +02003084 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003085 return 0;
3086}
3087
Emeric Brun2d0c4822012-10-02 13:45:20 +02003088
Emeric Brun9b3009b2012-10-05 11:55:06 +02003089/* parse the "no-sslv3" bind keyword */
3090static 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 +02003091{
Emeric Brun89675492012-10-05 13:48:26 +02003092 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003093 return 0;
3094}
3095
Emeric Brun9b3009b2012-10-05 11:55:06 +02003096/* parse the "no-tlsv10" bind keyword */
3097static 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 +02003098{
Emeric Brun89675492012-10-05 13:48:26 +02003099 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003100 return 0;
3101}
3102
Emeric Brun9b3009b2012-10-05 11:55:06 +02003103/* parse the "no-tlsv11" bind keyword */
3104static 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 +02003105{
Emeric Brun89675492012-10-05 13:48:26 +02003106 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003107 return 0;
3108}
3109
Emeric Brun9b3009b2012-10-05 11:55:06 +02003110/* parse the "no-tlsv12" bind keyword */
3111static 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 +02003112{
Emeric Brun89675492012-10-05 13:48:26 +02003113 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003114 return 0;
3115}
3116
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003117/* parse the "npn" bind keyword */
3118static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3119{
3120#ifdef OPENSSL_NPN_NEGOTIATED
3121 char *p1, *p2;
3122
3123 if (!*args[cur_arg + 1]) {
3124 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3125 return ERR_ALERT | ERR_FATAL;
3126 }
3127
3128 free(conf->npn_str);
3129
3130 /* the NPN string is built as a suite of (<len> <name>)* */
3131 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3132 conf->npn_str = calloc(1, conf->npn_len);
3133 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3134
3135 /* replace commas with the name length */
3136 p1 = conf->npn_str;
3137 p2 = p1 + 1;
3138 while (1) {
3139 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3140 if (!p2)
3141 p2 = p1 + 1 + strlen(p1 + 1);
3142
3143 if (p2 - (p1 + 1) > 255) {
3144 *p2 = '\0';
3145 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3146 return ERR_ALERT | ERR_FATAL;
3147 }
3148
3149 *p1 = p2 - (p1 + 1);
3150 p1 = p2;
3151
3152 if (!*p2)
3153 break;
3154
3155 *(p2++) = '\0';
3156 }
3157 return 0;
3158#else
3159 if (err)
3160 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3161 return ERR_ALERT | ERR_FATAL;
3162#endif
3163}
3164
Willy Tarreauab861d32013-04-02 02:30:41 +02003165/* parse the "alpn" bind keyword */
3166static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3167{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003168#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003169 char *p1, *p2;
3170
3171 if (!*args[cur_arg + 1]) {
3172 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3173 return ERR_ALERT | ERR_FATAL;
3174 }
3175
3176 free(conf->alpn_str);
3177
3178 /* the ALPN string is built as a suite of (<len> <name>)* */
3179 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3180 conf->alpn_str = calloc(1, conf->alpn_len);
3181 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3182
3183 /* replace commas with the name length */
3184 p1 = conf->alpn_str;
3185 p2 = p1 + 1;
3186 while (1) {
3187 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3188 if (!p2)
3189 p2 = p1 + 1 + strlen(p1 + 1);
3190
3191 if (p2 - (p1 + 1) > 255) {
3192 *p2 = '\0';
3193 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3194 return ERR_ALERT | ERR_FATAL;
3195 }
3196
3197 *p1 = p2 - (p1 + 1);
3198 p1 = p2;
3199
3200 if (!*p2)
3201 break;
3202
3203 *(p2++) = '\0';
3204 }
3205 return 0;
3206#else
3207 if (err)
3208 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3209 return ERR_ALERT | ERR_FATAL;
3210#endif
3211}
3212
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003213/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003214static 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 +02003215{
Willy Tarreau81796be2012-09-22 19:11:47 +02003216 struct listener *l;
3217
Willy Tarreau4348fad2012-09-20 16:48:07 +02003218 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003219
3220 if (global.listen_default_ciphers && !conf->ciphers)
3221 conf->ciphers = strdup(global.listen_default_ciphers);
3222
Willy Tarreau81796be2012-09-22 19:11:47 +02003223 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003224 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003225
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003226 return 0;
3227}
3228
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003229/* parse the "strict-sni" bind keyword */
3230static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3231{
3232 conf->strict_sni = 1;
3233 return 0;
3234}
3235
Emeric Brund94b3fe2012-09-20 18:23:56 +02003236/* parse the "verify" bind keyword */
3237static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3238{
3239 if (!*args[cur_arg + 1]) {
3240 if (err)
3241 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3242 return ERR_ALERT | ERR_FATAL;
3243 }
3244
3245 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003246 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003247 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003248 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003249 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003250 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003251 else {
3252 if (err)
3253 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3254 args[cur_arg], args[cur_arg + 1]);
3255 return ERR_ALERT | ERR_FATAL;
3256 }
3257
3258 return 0;
3259}
3260
Willy Tarreau92faadf2012-10-10 23:04:25 +02003261/************** "server" keywords ****************/
3262
Emeric Brunef42d922012-10-11 16:11:36 +02003263/* parse the "ca-file" server keyword */
3264static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3265{
3266 if (!*args[*cur_arg + 1]) {
3267 if (err)
3268 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3269 return ERR_ALERT | ERR_FATAL;
3270 }
3271
3272 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3273 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3274 else
3275 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3276
3277 return 0;
3278}
3279
Willy Tarreau92faadf2012-10-10 23:04:25 +02003280/* parse the "check-ssl" server keyword */
3281static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3282{
3283 newsrv->check.use_ssl = 1;
3284 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3285 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3286 return 0;
3287}
3288
3289/* parse the "ciphers" server keyword */
3290static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3291{
3292 if (!*args[*cur_arg + 1]) {
3293 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3294 return ERR_ALERT | ERR_FATAL;
3295 }
3296
3297 free(newsrv->ssl_ctx.ciphers);
3298 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3299 return 0;
3300}
3301
Emeric Brunef42d922012-10-11 16:11:36 +02003302/* parse the "crl-file" server keyword */
3303static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3304{
3305#ifndef X509_V_FLAG_CRL_CHECK
3306 if (err)
3307 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3308 return ERR_ALERT | ERR_FATAL;
3309#else
3310 if (!*args[*cur_arg + 1]) {
3311 if (err)
3312 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
3313 return ERR_ALERT | ERR_FATAL;
3314 }
3315
3316 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3317 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3318 else
3319 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
3320
3321 return 0;
3322#endif
3323}
3324
Emeric Bruna7aa3092012-10-26 12:58:00 +02003325/* parse the "crt" server keyword */
3326static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3327{
3328 if (!*args[*cur_arg + 1]) {
3329 if (err)
3330 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
3331 return ERR_ALERT | ERR_FATAL;
3332 }
3333
3334 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
3335 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3336 else
3337 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
3338
3339 return 0;
3340}
Emeric Brunef42d922012-10-11 16:11:36 +02003341
Willy Tarreau92faadf2012-10-10 23:04:25 +02003342/* parse the "force-sslv3" server keyword */
3343static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3344{
3345 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
3346 return 0;
3347}
3348
3349/* parse the "force-tlsv10" server keyword */
3350static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3351{
3352 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
3353 return 0;
3354}
3355
3356/* parse the "force-tlsv11" server keyword */
3357static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3358{
3359#if SSL_OP_NO_TLSv1_1
3360 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
3361 return 0;
3362#else
3363 if (err)
3364 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
3365 return ERR_ALERT | ERR_FATAL;
3366#endif
3367}
3368
3369/* parse the "force-tlsv12" server keyword */
3370static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3371{
3372#if SSL_OP_NO_TLSv1_2
3373 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
3374 return 0;
3375#else
3376 if (err)
3377 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
3378 return ERR_ALERT | ERR_FATAL;
3379#endif
3380}
3381
3382/* parse the "no-sslv3" server keyword */
3383static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3384{
3385 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
3386 return 0;
3387}
3388
3389/* parse the "no-tlsv10" server keyword */
3390static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3391{
3392 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
3393 return 0;
3394}
3395
3396/* parse the "no-tlsv11" server keyword */
3397static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3398{
3399 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
3400 return 0;
3401}
3402
3403/* parse the "no-tlsv12" server keyword */
3404static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3405{
3406 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
3407 return 0;
3408}
3409
Emeric Brunf9c5c472012-10-11 15:28:34 +02003410/* parse the "no-tls-tickets" server keyword */
3411static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3412{
3413 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
3414 return 0;
3415}
David Safb76832014-05-08 23:42:08 -04003416/* parse the "send-proxy-v2-ssl" server keyword */
3417static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3418{
3419 newsrv->pp_opts |= SRV_PP_V2;
3420 newsrv->pp_opts |= SRV_PP_V2_SSL;
3421 return 0;
3422}
3423
3424/* parse the "send-proxy-v2-ssl-cn" server keyword */
3425static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3426{
3427 newsrv->pp_opts |= SRV_PP_V2;
3428 newsrv->pp_opts |= SRV_PP_V2_SSL;
3429 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
3430 return 0;
3431}
Emeric Brunf9c5c472012-10-11 15:28:34 +02003432
Willy Tarreau92faadf2012-10-10 23:04:25 +02003433/* parse the "ssl" server keyword */
3434static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3435{
3436 newsrv->use_ssl = 1;
3437 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3438 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3439 return 0;
3440}
3441
Emeric Brunef42d922012-10-11 16:11:36 +02003442/* parse the "verify" server keyword */
3443static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3444{
3445 if (!*args[*cur_arg + 1]) {
3446 if (err)
3447 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
3448 return ERR_ALERT | ERR_FATAL;
3449 }
3450
3451 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003452 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02003453 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003454 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02003455 else {
3456 if (err)
3457 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
3458 args[*cur_arg], args[*cur_arg + 1]);
3459 return ERR_ALERT | ERR_FATAL;
3460 }
3461
Evan Broderbe554312013-06-27 00:05:25 -07003462 return 0;
3463}
3464
3465/* parse the "verifyhost" server keyword */
3466static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3467{
3468 if (!*args[*cur_arg + 1]) {
3469 if (err)
3470 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
3471 return ERR_ALERT | ERR_FATAL;
3472 }
3473
3474 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
3475
Emeric Brunef42d922012-10-11 16:11:36 +02003476 return 0;
3477}
3478
Willy Tarreau7875d092012-09-10 08:20:03 +02003479/* Note: must not be declared <const> as its list will be overwritten.
3480 * Please take care of keeping this list alphabetically sorted.
3481 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003482static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02003483 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
3484 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
3485 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
3486 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02003487 { "ssl_bc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
Emeric Brun645ae792014-04-30 14:21:06 +02003488 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
3489 { "ssl_bc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
Willy Tarreau80aca902013-01-07 15:42:20 +01003490 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3491 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3492 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003493 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3494 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3495 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3496 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3497 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3498 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3499 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3500 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003501 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3502 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003503 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3504 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3505 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3506 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3507 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3508 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3509 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3510 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02003511 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003512 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003513 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3514 { "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 +01003515 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003516 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3517 { "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 +02003518#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003519 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003520#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003521#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003522 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02003523#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003524 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02003525 { "ssl_fc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003526 { "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 +01003527 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3528 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02003529 { NULL, NULL, 0, 0, 0 },
3530}};
3531
3532/* Note: must not be declared <const> as its list will be overwritten.
3533 * Please take care of keeping this list alphabetically sorted.
3534 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003535static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003536 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
3537 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01003538 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02003539}};
3540
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003541/* Note: must not be declared <const> as its list will be overwritten.
3542 * Please take care of keeping this list alphabetically sorted, doing so helps
3543 * all code contributors.
3544 * Optional keywords are also declared with a NULL ->parse() function so that
3545 * the config parser can report an appropriate error when a known keyword was
3546 * not enabled.
3547 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02003548static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02003549 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003550 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003551 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
3552 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003553 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003554 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
3555 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003556 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003557 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003558 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
3559 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
3560 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
3561 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02003562 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
3563 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
3564 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
3565 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003566 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003567 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003568 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003569 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003570 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003571 { NULL, NULL, 0 },
3572}};
Emeric Brun46591952012-05-18 15:47:34 +02003573
Willy Tarreau92faadf2012-10-10 23:04:25 +02003574/* Note: must not be declared <const> as its list will be overwritten.
3575 * Please take care of keeping this list alphabetically sorted, doing so helps
3576 * all code contributors.
3577 * Optional keywords are also declared with a NULL ->parse() function so that
3578 * the config parser can report an appropriate error when a known keyword was
3579 * not enabled.
3580 */
3581static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02003582 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003583 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
3584 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02003585 { "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 +02003586 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003587 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
3588 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
3589 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
3590 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
3591 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
3592 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
3593 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
3594 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02003595 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04003596 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
3597 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 0 }, /* send PROXY protocol header v2 with CN */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003598 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02003599 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07003600 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02003601 { NULL, NULL, 0, 0 },
3602}};
3603
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003604/* transport-layer operations for SSL sockets */
3605struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02003606 .snd_buf = ssl_sock_from_buf,
3607 .rcv_buf = ssl_sock_to_buf,
3608 .rcv_pipe = NULL,
3609 .snd_pipe = NULL,
3610 .shutr = NULL,
3611 .shutw = ssl_sock_shutw,
3612 .close = ssl_sock_close,
3613 .init = ssl_sock_init,
3614};
3615
3616__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02003617static void __ssl_sock_init(void)
3618{
Emeric Brun46591952012-05-18 15:47:34 +02003619 STACK_OF(SSL_COMP)* cm;
3620
Willy Tarreau610f04b2014-02-13 11:36:41 +01003621#ifdef LISTEN_DEFAULT_CIPHERS
3622 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
3623#endif
3624#ifdef CONNECT_DEFAULT_CIPHERS
3625 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
3626#endif
3627 if (global.listen_default_ciphers)
3628 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
3629 if (global.connect_default_ciphers)
3630 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
3631
Emeric Brun46591952012-05-18 15:47:34 +02003632 SSL_library_init();
3633 cm = SSL_COMP_get_compression_methods();
3634 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02003635 sample_register_fetches(&sample_fetch_keywords);
3636 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003637 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02003638 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02003639}
3640
3641/*
3642 * Local variables:
3643 * c-indent-level: 8
3644 * c-basic-offset: 8
3645 * End:
3646 */