blob: b207580b689154a08a22c8972beed5021013b6b0 [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 Tarreau0c9c2722014-05-28 12:28:58 +02001450 if (!SSL_session_reused(conn->xprt_ctx)) {
1451 if (objt_server(conn->target)) {
1452 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
1453 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
1454 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
1455
Emeric Brun46591952012-05-18 15:47:34 +02001456 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001457 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1458 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001459
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001460 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001461 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02001462 else {
1463 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
1464 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
1465 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
1466 }
Emeric Brun46591952012-05-18 15:47:34 +02001467 }
1468
1469 /* The connection is now established at both layers, it's time to leave */
1470 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
1471 return 1;
1472
1473 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001474 /* Clear openssl global errors stack */
1475 ERR_clear_error();
1476
Emeric Brun9fa89732012-10-04 17:09:56 +02001477 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001478 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
1479 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
1480 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02001481 }
1482
Emeric Brun46591952012-05-18 15:47:34 +02001483 /* Fail on all other handshake errors */
1484 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001485 if (!conn->err_code)
1486 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001487 return 0;
1488}
1489
1490/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01001491 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02001492 * buffer wraps, in which case a second call may be performed. The connection's
1493 * flags are updated with whatever special event is detected (error, read0,
1494 * empty). The caller is responsible for taking care of those events and
1495 * avoiding the call if inappropriate. The function does not call the
1496 * connection's polling update function, so the caller is responsible for this.
1497 */
1498static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
1499{
1500 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01001501 int try;
Emeric Brun46591952012-05-18 15:47:34 +02001502
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001503 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001504 goto out_error;
1505
1506 if (conn->flags & CO_FL_HANDSHAKE)
1507 /* a handshake was requested */
1508 return 0;
1509
Willy Tarreauabf08d92014-01-14 11:31:27 +01001510 /* let's realign the buffer to optimize I/O */
1511 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02001512 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02001513
1514 /* read the largest possible block. For this, we perform only one call
1515 * to recv() unless the buffer wraps and we exactly fill the first hunk,
1516 * in which case we accept to do it once again. A new attempt is made on
1517 * EINTR too.
1518 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01001519 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01001520 /* first check if we have some room after p+i */
1521 try = buf->data + buf->size - (buf->p + buf->i);
1522 /* otherwise continue between data and p-o */
1523 if (try <= 0) {
1524 try = buf->p - (buf->data + buf->o);
1525 if (try <= 0)
1526 break;
1527 }
1528 if (try > count)
1529 try = count;
1530
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001531 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02001532 if (conn->flags & CO_FL_ERROR) {
1533 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001534 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001535 }
Emeric Brun46591952012-05-18 15:47:34 +02001536 if (ret > 0) {
1537 buf->i += ret;
1538 done += ret;
1539 if (ret < try)
1540 break;
1541 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02001542 }
1543 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01001544 ret = SSL_get_error(conn->xprt_ctx, ret);
1545 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01001546 /* error on protocol or underlying transport */
1547 if ((ret != SSL_ERROR_SYSCALL)
1548 || (errno && (errno != EAGAIN)))
1549 conn->flags |= CO_FL_ERROR;
1550
Emeric Brun644cde02012-12-14 11:21:13 +01001551 /* Clear openssl global errors stack */
1552 ERR_clear_error();
1553 }
Emeric Brun46591952012-05-18 15:47:34 +02001554 goto read0;
1555 }
1556 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001557 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001558 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001559 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02001560 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001561 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001562 break;
1563 }
1564 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001565 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1566 /* handshake is running, and it may need to re-enable read */
1567 conn->flags |= CO_FL_SSL_WAIT_HS;
1568 __conn_sock_want_recv(conn);
1569 break;
1570 }
Emeric Brun46591952012-05-18 15:47:34 +02001571 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001572 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001573 break;
1574 }
1575 /* otherwise it's a real error */
1576 goto out_error;
1577 }
1578 }
1579 return done;
1580
1581 read0:
1582 conn_sock_read0(conn);
1583 return done;
1584 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001585 /* Clear openssl global errors stack */
1586 ERR_clear_error();
1587
Emeric Brun46591952012-05-18 15:47:34 +02001588 conn->flags |= CO_FL_ERROR;
1589 return done;
1590}
1591
1592
1593/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01001594 * <flags> may contain some CO_SFL_* flags to hint the system about other
1595 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02001596 * Only one call to send() is performed, unless the buffer wraps, in which case
1597 * a second call may be performed. The connection's flags are updated with
1598 * whatever special event is detected (error, empty). The caller is responsible
1599 * for taking care of those events and avoiding the call if inappropriate. The
1600 * function does not call the connection's polling update function, so the caller
1601 * is responsible for this.
1602 */
1603static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
1604{
1605 int ret, try, done;
1606
1607 done = 0;
1608
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001609 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001610 goto out_error;
1611
1612 if (conn->flags & CO_FL_HANDSHAKE)
1613 /* a handshake was requested */
1614 return 0;
1615
1616 /* send the largest possible block. For this we perform only one call
1617 * to send() unless the buffer wraps and we exactly fill the first hunk,
1618 * in which case we accept to do it once again.
1619 */
1620 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07001621 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01001622
Willy Tarreau7bed9452014-02-02 02:00:24 +01001623 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01001624 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
1625 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01001626 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01001627 }
1628 else {
1629 /* we need to keep the information about the fact that
1630 * we're not limiting the upcoming send(), because if it
1631 * fails, we'll have to retry with at least as many data.
1632 */
1633 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
1634 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01001635
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001636 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01001637
Emeric Brune1f38db2012-09-03 20:36:47 +02001638 if (conn->flags & CO_FL_ERROR) {
1639 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001640 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001641 }
Emeric Brun46591952012-05-18 15:47:34 +02001642 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01001643 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
1644
Emeric Brun46591952012-05-18 15:47:34 +02001645 buf->o -= ret;
1646 done += ret;
1647
Willy Tarreau5fb38032012-12-16 19:39:09 +01001648 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02001649 /* optimize data alignment in the buffer */
1650 buf->p = buf->data;
1651
1652 /* if the system buffer is full, don't insist */
1653 if (ret < try)
1654 break;
1655 }
1656 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001657 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001658 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001659 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1660 /* handshake is running, and it may need to re-enable write */
1661 conn->flags |= CO_FL_SSL_WAIT_HS;
1662 __conn_sock_want_send(conn);
1663 break;
1664 }
Emeric Brun46591952012-05-18 15:47:34 +02001665 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001666 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001667 break;
1668 }
1669 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001670 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02001671 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001672 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001673 break;
1674 }
1675 goto out_error;
1676 }
1677 }
1678 return done;
1679
1680 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001681 /* Clear openssl global errors stack */
1682 ERR_clear_error();
1683
Emeric Brun46591952012-05-18 15:47:34 +02001684 conn->flags |= CO_FL_ERROR;
1685 return done;
1686}
1687
Emeric Brun46591952012-05-18 15:47:34 +02001688static void ssl_sock_close(struct connection *conn) {
1689
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001690 if (conn->xprt_ctx) {
1691 SSL_free(conn->xprt_ctx);
1692 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02001693 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02001694 }
Emeric Brun46591952012-05-18 15:47:34 +02001695}
1696
1697/* This function tries to perform a clean shutdown on an SSL connection, and in
1698 * any case, flags the connection as reusable if no handshake was in progress.
1699 */
1700static void ssl_sock_shutw(struct connection *conn, int clean)
1701{
1702 if (conn->flags & CO_FL_HANDSHAKE)
1703 return;
1704 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01001705 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
1706 /* Clear openssl global errors stack */
1707 ERR_clear_error();
1708 }
Emeric Brun46591952012-05-18 15:47:34 +02001709
1710 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001711 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02001712}
1713
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02001714/* used for logging, may be changed for a sample fetch later */
1715const char *ssl_sock_get_cipher_name(struct connection *conn)
1716{
1717 if (!conn->xprt && !conn->xprt_ctx)
1718 return NULL;
1719 return SSL_get_cipher_name(conn->xprt_ctx);
1720}
1721
1722/* used for logging, may be changed for a sample fetch later */
1723const char *ssl_sock_get_proto_version(struct connection *conn)
1724{
1725 if (!conn->xprt && !conn->xprt_ctx)
1726 return NULL;
1727 return SSL_get_version(conn->xprt_ctx);
1728}
1729
Willy Tarreau8d598402012-10-22 17:58:39 +02001730/* Extract a serial from a cert, and copy it to a chunk.
1731 * Returns 1 if serial is found and copied, 0 if no serial found and
1732 * -1 if output is not large enough.
1733 */
1734static int
1735ssl_sock_get_serial(X509 *crt, struct chunk *out)
1736{
1737 ASN1_INTEGER *serial;
1738
1739 serial = X509_get_serialNumber(crt);
1740 if (!serial)
1741 return 0;
1742
1743 if (out->size < serial->length)
1744 return -1;
1745
1746 memcpy(out->str, serial->data, serial->length);
1747 out->len = serial->length;
1748 return 1;
1749}
1750
Emeric Brunce5ad802012-10-22 14:11:22 +02001751
1752/* Copy Date in ASN1_UTCTIME format in struct chunk out.
1753 * Returns 1 if serial is found and copied, 0 if no valid time found
1754 * and -1 if output is not large enough.
1755 */
1756static int
1757ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
1758{
1759 if (tm->type == V_ASN1_GENERALIZEDTIME) {
1760 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
1761
1762 if (gentm->length < 12)
1763 return 0;
1764 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
1765 return 0;
1766 if (out->size < gentm->length-2)
1767 return -1;
1768
1769 memcpy(out->str, gentm->data+2, gentm->length-2);
1770 out->len = gentm->length-2;
1771 return 1;
1772 }
1773 else if (tm->type == V_ASN1_UTCTIME) {
1774 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
1775
1776 if (utctm->length < 10)
1777 return 0;
1778 if (utctm->data[0] >= 0x35)
1779 return 0;
1780 if (out->size < utctm->length)
1781 return -1;
1782
1783 memcpy(out->str, utctm->data, utctm->length);
1784 out->len = utctm->length;
1785 return 1;
1786 }
1787
1788 return 0;
1789}
1790
Emeric Brun87855892012-10-17 17:39:35 +02001791/* Extract an entry from a X509_NAME and copy its value to an output chunk.
1792 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
1793 */
1794static int
1795ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
1796{
1797 X509_NAME_ENTRY *ne;
1798 int i, j, n;
1799 int cur = 0;
1800 const char *s;
1801 char tmp[128];
1802
1803 out->len = 0;
1804 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1805 if (pos < 0)
1806 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
1807 else
1808 j = i;
1809
1810 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
1811 n = OBJ_obj2nid(ne->object);
1812 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1813 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1814 s = tmp;
1815 }
1816
1817 if (chunk_strcasecmp(entry, s) != 0)
1818 continue;
1819
1820 if (pos < 0)
1821 cur--;
1822 else
1823 cur++;
1824
1825 if (cur != pos)
1826 continue;
1827
1828 if (ne->value->length > out->size)
1829 return -1;
1830
1831 memcpy(out->str, ne->value->data, ne->value->length);
1832 out->len = ne->value->length;
1833 return 1;
1834 }
1835
1836 return 0;
1837
1838}
1839
1840/* Extract and format full DN from a X509_NAME and copy result into a chunk
1841 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
1842 */
1843static int
1844ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
1845{
1846 X509_NAME_ENTRY *ne;
1847 int i, n, ln;
1848 int l = 0;
1849 const char *s;
1850 char *p;
1851 char tmp[128];
1852
1853 out->len = 0;
1854 p = out->str;
1855 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1856 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
1857 n = OBJ_obj2nid(ne->object);
1858 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1859 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1860 s = tmp;
1861 }
1862 ln = strlen(s);
1863
1864 l += 1 + ln + 1 + ne->value->length;
1865 if (l > out->size)
1866 return -1;
1867 out->len = l;
1868
1869 *(p++)='/';
1870 memcpy(p, s, ln);
1871 p += ln;
1872 *(p++)='=';
1873 memcpy(p, ne->value->data, ne->value->length);
1874 p += ne->value->length;
1875 }
1876
1877 if (!out->len)
1878 return 0;
1879
1880 return 1;
1881}
1882
David Safb76832014-05-08 23:42:08 -04001883char *ssl_sock_get_version(struct connection *conn)
1884{
1885 if (!ssl_sock_is_ssl(conn))
1886 return NULL;
1887
1888 return (char *)SSL_get_version(conn->xprt_ctx);
1889}
1890
1891/* returns common name, NULL terminated, from client certificate, or NULL if none */
1892char *ssl_sock_get_common_name(struct connection *conn)
1893{
1894 X509 *crt = NULL;
1895 X509_NAME *name;
1896 struct chunk *cn_trash;
1897 const char find_cn[] = "CN";
1898 const struct chunk find_cn_chunk = {
1899 .str = (char *)&find_cn,
1900 .len = sizeof(find_cn)-1
1901 };
1902 char *result = NULL;
1903
1904 if (!ssl_sock_is_ssl(conn))
1905 return NULL;
1906
1907 /* SSL_get_peer_certificate, it increase X509 * ref count */
1908 crt = SSL_get_peer_certificate(conn->xprt_ctx);
1909 if (!crt)
1910 goto out;
1911
1912 name = X509_get_subject_name(crt);
1913 if (!name)
1914 goto out;
1915
1916 cn_trash = get_trash_chunk();
1917 if (ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, cn_trash) <= 0)
1918 goto out;
1919 cn_trash->str[cn_trash->len] = '\0';
1920 result = cn_trash->str;
1921
1922 out:
1923 if (crt)
1924 X509_free(crt);
1925
1926 return result;
1927}
1928
1929/* returns 1 if client passed a certificate, 0 if not */
1930int ssl_sock_get_cert_used(struct connection *conn)
1931{
1932 if (!ssl_sock_is_ssl(conn))
1933 return 0;
1934
1935 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
1936}
1937
1938/* returns result from SSL verify */
1939unsigned int ssl_sock_get_verify_result(struct connection *conn)
1940{
1941 if (!ssl_sock_is_ssl(conn))
1942 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
1943
1944 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
1945}
1946
Willy Tarreau7875d092012-09-10 08:20:03 +02001947/***** Below are some sample fetching functions for ACL/patterns *****/
1948
Emeric Brune64aef12012-09-21 13:15:06 +02001949/* boolean, returns true if client cert was present */
1950static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02001951smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001952 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02001953{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001954 struct connection *conn;
1955
1956 if (!l4)
1957 return 0;
1958
1959 conn = objt_conn(l4->si[0].end);
1960 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02001961 return 0;
1962
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001963 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02001964 smp->flags |= SMP_F_MAY_CHANGE;
1965 return 0;
1966 }
1967
1968 smp->flags = 0;
1969 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001970 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001971
1972 return 1;
1973}
1974
Emeric Brunba841a12014-04-30 17:05:08 +02001975/* binary, returns serial of certificate in a binary chunk.
1976 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
1977 * should be use.
1978 */
Willy Tarreau8d598402012-10-22 17:58:39 +02001979static int
Emeric Brunba841a12014-04-30 17:05:08 +02001980smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001981 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02001982{
Emeric Brunba841a12014-04-30 17:05:08 +02001983 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001984 X509 *crt = NULL;
1985 int ret = 0;
1986 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001987 struct connection *conn;
1988
1989 if (!l4)
1990 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001991
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001992 conn = objt_conn(l4->si[0].end);
1993 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02001994 return 0;
1995
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001996 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02001997 smp->flags |= SMP_F_MAY_CHANGE;
1998 return 0;
1999 }
2000
Emeric Brunba841a12014-04-30 17:05:08 +02002001 if (cert_peer)
2002 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2003 else
2004 crt = SSL_get_certificate(conn->xprt_ctx);
2005
Willy Tarreau8d598402012-10-22 17:58:39 +02002006 if (!crt)
2007 goto out;
2008
Willy Tarreau47ca5452012-12-23 20:22:19 +01002009 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002010 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2011 goto out;
2012
2013 smp->data.str = *smp_trash;
2014 smp->type = SMP_T_BIN;
2015 ret = 1;
2016out:
Emeric Brunba841a12014-04-30 17:05:08 +02002017 /* SSL_get_peer_certificate, it increase X509 * ref count */
2018 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002019 X509_free(crt);
2020 return ret;
2021}
Emeric Brune64aef12012-09-21 13:15:06 +02002022
Emeric Brunba841a12014-04-30 17:05:08 +02002023/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2024 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2025 * should be use.
2026 */
James Votha051b4a2013-05-14 20:37:59 +02002027static int
Emeric Brunba841a12014-04-30 17:05:08 +02002028smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002029 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002030{
Emeric Brunba841a12014-04-30 17:05:08 +02002031 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002032 X509 *crt = NULL;
2033 const EVP_MD *digest;
2034 int ret = 0;
2035 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002036 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002037
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002038 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002039 return 0;
2040
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002041 conn = objt_conn(l4->si[0].end);
2042 if (!conn || conn->xprt != &ssl_sock)
2043 return 0;
2044
2045 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002046 smp->flags |= SMP_F_MAY_CHANGE;
2047 return 0;
2048 }
2049
Emeric Brunba841a12014-04-30 17:05:08 +02002050 if (cert_peer)
2051 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2052 else
2053 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002054 if (!crt)
2055 goto out;
2056
2057 smp_trash = get_trash_chunk();
2058 digest = EVP_sha1();
2059 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2060
2061 smp->data.str = *smp_trash;
2062 smp->type = SMP_T_BIN;
2063 ret = 1;
2064out:
Emeric Brunba841a12014-04-30 17:05:08 +02002065 /* SSL_get_peer_certificate, it increase X509 * ref count */
2066 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002067 X509_free(crt);
2068 return ret;
2069}
2070
Emeric Brunba841a12014-04-30 17:05:08 +02002071/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2072 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2073 * should be use.
2074 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002075static int
Emeric Brunba841a12014-04-30 17:05:08 +02002076smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002077 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002078{
Emeric Brunba841a12014-04-30 17:05:08 +02002079 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002080 X509 *crt = NULL;
2081 int ret = 0;
2082 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002083 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002084
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002085 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002086 return 0;
2087
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002088 conn = objt_conn(l4->si[0].end);
2089 if (!conn || conn->xprt != &ssl_sock)
2090 return 0;
2091
2092 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002093 smp->flags |= SMP_F_MAY_CHANGE;
2094 return 0;
2095 }
2096
Emeric Brunba841a12014-04-30 17:05:08 +02002097 if (cert_peer)
2098 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2099 else
2100 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002101 if (!crt)
2102 goto out;
2103
Willy Tarreau47ca5452012-12-23 20:22:19 +01002104 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002105 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2106 goto out;
2107
2108 smp->data.str = *smp_trash;
2109 smp->type = SMP_T_STR;
2110 ret = 1;
2111out:
Emeric Brunba841a12014-04-30 17:05:08 +02002112 /* SSL_get_peer_certificate, it increase X509 * ref count */
2113 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002114 X509_free(crt);
2115 return ret;
2116}
2117
Emeric Brunba841a12014-04-30 17:05:08 +02002118/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2119 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2120 * should be use.
2121 */
Emeric Brun87855892012-10-17 17:39:35 +02002122static int
Emeric Brunba841a12014-04-30 17:05:08 +02002123smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002124 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002125{
Emeric Brunba841a12014-04-30 17:05:08 +02002126 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002127 X509 *crt = NULL;
2128 X509_NAME *name;
2129 int ret = 0;
2130 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002131 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002132
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002133 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002134 return 0;
2135
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002136 conn = objt_conn(l4->si[0].end);
2137 if (!conn || conn->xprt != &ssl_sock)
2138 return 0;
2139
2140 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002141 smp->flags |= SMP_F_MAY_CHANGE;
2142 return 0;
2143 }
2144
Emeric Brunba841a12014-04-30 17:05:08 +02002145 if (cert_peer)
2146 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2147 else
2148 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002149 if (!crt)
2150 goto out;
2151
2152 name = X509_get_issuer_name(crt);
2153 if (!name)
2154 goto out;
2155
Willy Tarreau47ca5452012-12-23 20:22:19 +01002156 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002157 if (args && args[0].type == ARGT_STR) {
2158 int pos = 1;
2159
2160 if (args[1].type == ARGT_SINT)
2161 pos = args[1].data.sint;
2162 else if (args[1].type == ARGT_UINT)
2163 pos =(int)args[1].data.uint;
2164
2165 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2166 goto out;
2167 }
2168 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2169 goto out;
2170
2171 smp->type = SMP_T_STR;
2172 smp->data.str = *smp_trash;
2173 ret = 1;
2174out:
Emeric Brunba841a12014-04-30 17:05:08 +02002175 /* SSL_get_peer_certificate, it increase X509 * ref count */
2176 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002177 X509_free(crt);
2178 return ret;
2179}
2180
Emeric Brunba841a12014-04-30 17:05:08 +02002181/* string, returns notbefore date in ASN1_UTCTIME format.
2182 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2183 * should be use.
2184 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002185static int
Emeric Brunba841a12014-04-30 17:05:08 +02002186smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002187 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002188{
Emeric Brunba841a12014-04-30 17:05:08 +02002189 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002190 X509 *crt = NULL;
2191 int ret = 0;
2192 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002193 struct connection *conn;
2194
2195 if (!l4)
2196 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002197
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002198 conn = objt_conn(l4->si[0].end);
2199 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002200 return 0;
2201
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002202 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002203 smp->flags |= SMP_F_MAY_CHANGE;
2204 return 0;
2205 }
2206
Emeric Brunba841a12014-04-30 17:05:08 +02002207 if (cert_peer)
2208 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2209 else
2210 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002211 if (!crt)
2212 goto out;
2213
Willy Tarreau47ca5452012-12-23 20:22:19 +01002214 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002215 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2216 goto out;
2217
2218 smp->data.str = *smp_trash;
2219 smp->type = SMP_T_STR;
2220 ret = 1;
2221out:
Emeric Brunba841a12014-04-30 17:05:08 +02002222 /* SSL_get_peer_certificate, it increase X509 * ref count */
2223 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002224 X509_free(crt);
2225 return ret;
2226}
2227
Emeric Brunba841a12014-04-30 17:05:08 +02002228/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
2229 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2230 * should be use.
2231 */
Emeric Brun87855892012-10-17 17:39:35 +02002232static int
Emeric Brunba841a12014-04-30 17:05:08 +02002233smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002234 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002235{
Emeric Brunba841a12014-04-30 17:05:08 +02002236 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002237 X509 *crt = NULL;
2238 X509_NAME *name;
2239 int ret = 0;
2240 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002241 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002242
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002243 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002244 return 0;
2245
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002246 conn = objt_conn(l4->si[0].end);
2247 if (!conn || conn->xprt != &ssl_sock)
2248 return 0;
2249
2250 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002251 smp->flags |= SMP_F_MAY_CHANGE;
2252 return 0;
2253 }
2254
Emeric Brunba841a12014-04-30 17:05:08 +02002255 if (cert_peer)
2256 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2257 else
2258 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002259 if (!crt)
2260 goto out;
2261
2262 name = X509_get_subject_name(crt);
2263 if (!name)
2264 goto out;
2265
Willy Tarreau47ca5452012-12-23 20:22:19 +01002266 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002267 if (args && args[0].type == ARGT_STR) {
2268 int pos = 1;
2269
2270 if (args[1].type == ARGT_SINT)
2271 pos = args[1].data.sint;
2272 else if (args[1].type == ARGT_UINT)
2273 pos =(int)args[1].data.uint;
2274
2275 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2276 goto out;
2277 }
2278 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2279 goto out;
2280
2281 smp->type = SMP_T_STR;
2282 smp->data.str = *smp_trash;
2283 ret = 1;
2284out:
Emeric Brunba841a12014-04-30 17:05:08 +02002285 /* SSL_get_peer_certificate, it increase X509 * ref count */
2286 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002287 X509_free(crt);
2288 return ret;
2289}
Emeric Brun9143d372012-12-20 15:44:16 +01002290
2291/* integer, returns true if current session use a client certificate */
2292static int
2293smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002294 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01002295{
2296 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002297 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01002298
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002299 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01002300 return 0;
2301
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002302 conn = objt_conn(l4->si[0].end);
2303 if (!conn || conn->xprt != &ssl_sock)
2304 return 0;
2305
2306 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01002307 smp->flags |= SMP_F_MAY_CHANGE;
2308 return 0;
2309 }
2310
2311 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002312 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01002313 if (crt) {
2314 X509_free(crt);
2315 }
2316
2317 smp->type = SMP_T_BOOL;
2318 smp->data.uint = (crt != NULL);
2319 return 1;
2320}
2321
Emeric Brunba841a12014-04-30 17:05:08 +02002322/* integer, returns the certificate version
2323 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2324 * should be use.
2325 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02002326static int
Emeric Brunba841a12014-04-30 17:05:08 +02002327smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002328 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002329{
Emeric Brunba841a12014-04-30 17:05:08 +02002330 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002331 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002332 struct connection *conn;
2333
2334 if (!l4)
2335 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002336
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002337 conn = objt_conn(l4->si[0].end);
2338 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002339 return 0;
2340
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002341 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002342 smp->flags |= SMP_F_MAY_CHANGE;
2343 return 0;
2344 }
2345
Emeric Brunba841a12014-04-30 17:05:08 +02002346 if (cert_peer)
2347 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2348 else
2349 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002350 if (!crt)
2351 return 0;
2352
2353 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02002354 /* SSL_get_peer_certificate increase X509 * ref count */
2355 if (cert_peer)
2356 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002357 smp->type = SMP_T_UINT;
2358
2359 return 1;
2360}
2361
Emeric Brunba841a12014-04-30 17:05:08 +02002362/* string, returns the certificate's signature algorithm.
2363 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2364 * should be use.
2365 */
Emeric Brun7f56e742012-10-19 18:15:40 +02002366static int
Emeric Brunba841a12014-04-30 17:05:08 +02002367smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002368 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002369{
Emeric Brunba841a12014-04-30 17:05:08 +02002370 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02002371 X509 *crt;
2372 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002373 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002374
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002375 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002376 return 0;
2377
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002378 conn = objt_conn(l4->si[0].end);
2379 if (!conn || conn->xprt != &ssl_sock)
2380 return 0;
2381
2382 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002383 smp->flags |= SMP_F_MAY_CHANGE;
2384 return 0;
2385 }
2386
Emeric Brunba841a12014-04-30 17:05:08 +02002387 if (cert_peer)
2388 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2389 else
2390 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002391 if (!crt)
2392 return 0;
2393
2394 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2395
2396 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002397 if (!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 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002402 }
Emeric Brun7f56e742012-10-19 18:15:40 +02002403
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002404 smp->type = SMP_T_STR;
2405 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002406 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02002407 /* SSL_get_peer_certificate increase X509 * ref count */
2408 if (cert_peer)
2409 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002410
2411 return 1;
2412}
2413
Emeric Brunba841a12014-04-30 17:05:08 +02002414/* string, returns the certificate's key algorithm.
2415 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2416 * should be use.
2417 */
Emeric Brun521a0112012-10-22 12:22:55 +02002418static int
Emeric Brunba841a12014-04-30 17:05:08 +02002419smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002420 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002421{
Emeric Brunba841a12014-04-30 17:05:08 +02002422 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02002423 X509 *crt;
2424 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002425 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02002426
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002427 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02002428 return 0;
2429
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002430 conn = objt_conn(l4->si[0].end);
2431 if (!conn || conn->xprt != &ssl_sock)
2432 return 0;
2433
2434 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002435 smp->flags |= SMP_F_MAY_CHANGE;
2436 return 0;
2437 }
2438
Emeric Brunba841a12014-04-30 17:05:08 +02002439 if (cert_peer)
2440 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2441 else
2442 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002443 if (!crt)
2444 return 0;
2445
2446 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2447
2448 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002449 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02002450 /* SSL_get_peer_certificate increase X509 * ref count */
2451 if (cert_peer)
2452 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002453 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002454 }
Emeric Brun521a0112012-10-22 12:22:55 +02002455
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002456 smp->type = SMP_T_STR;
2457 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002458 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02002459 if (cert_peer)
2460 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002461
2462 return 1;
2463}
2464
Emeric Brun645ae792014-04-30 14:21:06 +02002465/* boolean, returns true if front conn. transport layer is SSL.
2466 * This function is also usable on backend conn if the fetch keyword 5th
2467 * char is 'b'.
2468 */
Willy Tarreau7875d092012-09-10 08:20:03 +02002469static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002470smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002471 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002472{
Emeric Brun645ae792014-04-30 14:21:06 +02002473 int back_conn = (kw[4] == 'b') ? 1 : 0;
2474 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002475
Willy Tarreau7875d092012-09-10 08:20:03 +02002476 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002477 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02002478 return 1;
2479}
2480
Emeric Brun2525b6b2012-10-18 15:59:43 +02002481/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02002482static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002483smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002484 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002485{
2486#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002487 struct connection *conn = objt_conn(l4->si[0].end);
2488
Willy Tarreau7875d092012-09-10 08:20:03 +02002489 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002490 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
2491 conn->xprt_ctx &&
2492 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02002493 return 1;
2494#else
2495 return 0;
2496#endif
2497}
2498
Emeric Brun645ae792014-04-30 14:21:06 +02002499/* string, returns the used cipher if front conn. transport layer is SSL.
2500 * This function is also usable on backend conn if the fetch keyword 5th
2501 * char is 'b'.
2502 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002503static int
2504smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002505 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002506{
Emeric Brun645ae792014-04-30 14:21:06 +02002507 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002508 struct connection *conn;
2509
Emeric Brun589fcad2012-10-16 14:13:26 +02002510 smp->flags = 0;
2511
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002512 if (!l4)
2513 return 0;
2514
Emeric Brun645ae792014-04-30 14:21:06 +02002515 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002516 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002517 return 0;
2518
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002519 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002520 if (!smp->data.str.str)
2521 return 0;
2522
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002523 smp->type = SMP_T_STR;
2524 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002525 smp->data.str.len = strlen(smp->data.str.str);
2526
2527 return 1;
2528}
2529
Emeric Brun645ae792014-04-30 14:21:06 +02002530/* integer, returns the algoritm's keysize if front conn. transport layer
2531 * is SSL.
2532 * This function is also usable on backend conn if the fetch keyword 5th
2533 * char is 'b'.
2534 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002535static int
2536smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002537 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002538{
Emeric Brun645ae792014-04-30 14:21:06 +02002539 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002540 struct connection *conn;
2541
Emeric Brun589fcad2012-10-16 14:13:26 +02002542 smp->flags = 0;
2543
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002544 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002545 return 0;
2546
Emeric Brun645ae792014-04-30 14:21:06 +02002547 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002548 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002549 return 0;
2550
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002551 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
2552 return 0;
2553
Emeric Brun589fcad2012-10-16 14:13:26 +02002554 smp->type = SMP_T_UINT;
2555
2556 return 1;
2557}
2558
Emeric Brun645ae792014-04-30 14:21:06 +02002559/* integer, returns the used keysize if front conn. transport layer is SSL.
2560 * This function is also usable on backend conn if the fetch keyword 5th
2561 * char is 'b'.
2562 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002563static int
2564smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002565 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002566{
Emeric Brun645ae792014-04-30 14:21:06 +02002567 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002568 struct connection *conn;
2569
Emeric Brun589fcad2012-10-16 14:13:26 +02002570 smp->flags = 0;
2571
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002572 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002573 return 0;
2574
Emeric Brun645ae792014-04-30 14:21:06 +02002575 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002576 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2577 return 0;
2578
2579 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02002580 if (!smp->data.uint)
2581 return 0;
2582
2583 smp->type = SMP_T_UINT;
2584
2585 return 1;
2586}
2587
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002588#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02002589static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002590smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002591 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002592{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002593 struct connection *conn;
2594
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002595 smp->flags = SMP_F_CONST;
2596 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002597
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002598 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002599 return 0;
2600
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002601 conn = objt_conn(l4->si[0].end);
2602 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2603 return 0;
2604
Willy Tarreaua33c6542012-10-15 13:19:06 +02002605 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002606 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02002607 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2608
2609 if (!smp->data.str.str)
2610 return 0;
2611
2612 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002613}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002614#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02002615
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002616#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002617static int
2618smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002619 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02002620{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002621 struct connection *conn;
2622
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002623 smp->flags = SMP_F_CONST;
2624 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02002625
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002626 if (!l4)
2627 return 0;
2628
2629 conn = objt_conn(l4->si[0].end);
2630 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02002631 return 0;
2632
2633 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002634 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02002635 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2636
2637 if (!smp->data.str.str)
2638 return 0;
2639
2640 return 1;
2641}
2642#endif
2643
Emeric Brun645ae792014-04-30 14:21:06 +02002644/* string, returns the used protocol if front conn. transport layer is SSL.
2645 * This function is also usable on backend conn if the fetch keyword 5th
2646 * char is 'b'.
2647 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02002648static int
Emeric Brun589fcad2012-10-16 14:13:26 +02002649smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002650 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002651{
Emeric Brun645ae792014-04-30 14:21:06 +02002652 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002653 struct connection *conn;
2654
Emeric Brun589fcad2012-10-16 14:13:26 +02002655 smp->flags = 0;
2656
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002657 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002658 return 0;
2659
Emeric Brun645ae792014-04-30 14:21:06 +02002660 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002661 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2662 return 0;
2663
2664 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002665 if (!smp->data.str.str)
2666 return 0;
2667
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002668 smp->type = SMP_T_STR;
2669 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002670 smp->data.str.len = strlen(smp->data.str.str);
2671
2672 return 1;
2673}
2674
Emeric Brun645ae792014-04-30 14:21:06 +02002675/* binary, returns the SSL session id if front conn. transport layer is SSL.
2676 * This function is also usable on backend conn if the fetch keyword 5th
2677 * char is 'b'.
2678 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002679static int
Emeric Brunfe68f682012-10-16 14:59:28 +02002680smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002681 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02002682{
2683#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02002684 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02002685 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002686 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02002687
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002688 smp->flags = SMP_F_CONST;
2689 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02002690
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002691 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02002692 return 0;
2693
Emeric Brun645ae792014-04-30 14:21:06 +02002694 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002695 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2696 return 0;
2697
2698 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02002699 if (!sess)
2700 return 0;
2701
2702 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
2703 if (!smp->data.str.str || !&smp->data.str.len)
2704 return 0;
2705
2706 return 1;
2707#else
2708 return 0;
2709#endif
2710}
2711
2712static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002713smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002714 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002715{
2716#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002717 struct connection *conn;
2718
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002719 smp->flags = SMP_F_CONST;
2720 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02002721
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002722 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02002723 return 0;
2724
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002725 conn = objt_conn(l4->si[0].end);
2726 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2727 return 0;
2728
2729 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02002730 if (!smp->data.str.str)
2731 return 0;
2732
Willy Tarreau7875d092012-09-10 08:20:03 +02002733 smp->data.str.len = strlen(smp->data.str.str);
2734 return 1;
2735#else
2736 return 0;
2737#endif
2738}
2739
David Sc1ad52e2014-04-08 18:48:47 -04002740static int
2741smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2742 const struct arg *args, struct sample *smp, const char *kw)
2743{
2744#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02002745 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04002746 struct connection *conn;
2747 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04002748 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04002749
2750 smp->flags = 0;
2751
2752 if (!l4)
2753 return 0;
2754
Emeric Brun645ae792014-04-30 14:21:06 +02002755 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04002756 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2757 return 0;
2758
2759 if (!(conn->flags & CO_FL_CONNECTED)) {
2760 smp->flags |= SMP_F_MAY_CHANGE;
2761 return 0;
2762 }
2763
2764 finished_trash = get_trash_chunk();
2765 if (!SSL_session_reused(conn->xprt_ctx))
2766 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2767 else
2768 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2769
2770 if (!finished_len)
2771 return 0;
2772
Emeric Brunb73a9b02014-04-30 18:49:19 +02002773 finished_trash->len = finished_len;
2774 smp->data.str = *finished_trash;
2775 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04002776
2777 return 1;
2778#else
2779 return 0;
2780#endif
2781}
2782
Emeric Brun2525b6b2012-10-18 15:59:43 +02002783/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002784static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002785smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002786 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002787{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002788 struct connection *conn;
2789
2790 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002791 return 0;
2792
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002793 conn = objt_conn(l4->si[0].end);
2794 if (!conn || conn->xprt != &ssl_sock)
2795 return 0;
2796
2797 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002798 smp->flags = SMP_F_MAY_CHANGE;
2799 return 0;
2800 }
2801
2802 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002803 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002804 smp->flags = 0;
2805
2806 return 1;
2807}
2808
Emeric Brun2525b6b2012-10-18 15:59:43 +02002809/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002810static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002811smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002812 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002813{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002814 struct connection *conn;
2815
2816 if (!l4)
2817 return 0;
2818
2819 conn = objt_conn(l4->si[0].end);
2820 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02002821 return 0;
2822
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002823 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002824 smp->flags = SMP_F_MAY_CHANGE;
2825 return 0;
2826 }
2827
2828 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002829 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002830 smp->flags = 0;
2831
2832 return 1;
2833}
2834
Emeric Brun2525b6b2012-10-18 15:59:43 +02002835/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02002836static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002837smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002838 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002839{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002840 struct connection *conn;
2841
2842 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002843 return 0;
2844
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002845 conn = objt_conn(l4->si[0].end);
2846 if (!conn || conn->xprt != &ssl_sock)
2847 return 0;
2848
2849 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002850 smp->flags = SMP_F_MAY_CHANGE;
2851 return 0;
2852 }
2853
2854 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002855 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002856 smp->flags = 0;
2857
2858 return 1;
2859}
2860
Emeric Brun2525b6b2012-10-18 15:59:43 +02002861/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002862static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002863smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002864 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002865{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002866 struct connection *conn;
2867
2868 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002869 return 0;
2870
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002871 conn = objt_conn(l4->si[0].end);
2872 if (!conn || conn->xprt != &ssl_sock)
2873 return 0;
2874
2875 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002876 smp->flags = SMP_F_MAY_CHANGE;
2877 return 0;
2878 }
2879
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002880 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002881 return 0;
2882
2883 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002884 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002885 smp->flags = 0;
2886
2887 return 1;
2888}
2889
Emeric Brunfb510ea2012-10-05 12:00:26 +02002890/* parse the "ca-file" bind keyword */
2891static 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 +02002892{
2893 if (!*args[cur_arg + 1]) {
2894 if (err)
2895 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
2896 return ERR_ALERT | ERR_FATAL;
2897 }
2898
Emeric Brunef42d922012-10-11 16:11:36 +02002899 if ((*args[cur_arg + 1] != '/') && global.ca_base)
2900 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
2901 else
2902 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002903
Emeric Brund94b3fe2012-09-20 18:23:56 +02002904 return 0;
2905}
2906
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002907/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002908static 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 +02002909{
2910 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002911 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002912 return ERR_ALERT | ERR_FATAL;
2913 }
2914
Emeric Brun76d88952012-10-05 15:47:31 +02002915 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002916 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002917 return 0;
2918}
2919
2920/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002921static 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 +02002922{
Willy Tarreau38011032013-08-13 16:59:39 +02002923 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02002924
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002925 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002926 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002927 return ERR_ALERT | ERR_FATAL;
2928 }
2929
Emeric Brunc8e8d122012-10-02 18:42:10 +02002930 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02002931 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02002932 memprintf(err, "'%s' : path too long", args[cur_arg]);
2933 return ERR_ALERT | ERR_FATAL;
2934 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02002935 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002936 if (ssl_sock_load_cert(path, conf, px, err) > 0)
2937 return ERR_ALERT | ERR_FATAL;
2938
2939 return 0;
2940 }
2941
Willy Tarreau4348fad2012-09-20 16:48:07 +02002942 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002943 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02002944
2945 return 0;
2946}
2947
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002948/* parse the "crt-list" bind keyword */
2949static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2950{
2951 if (!*args[cur_arg + 1]) {
2952 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
2953 return ERR_ALERT | ERR_FATAL;
2954 }
2955
Willy Tarreauad1731d2013-04-02 17:35:58 +02002956 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
2957 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002958 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002959 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002960
2961 return 0;
2962}
2963
Emeric Brunfb510ea2012-10-05 12:00:26 +02002964/* parse the "crl-file" bind keyword */
2965static 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 +02002966{
Emeric Brun051cdab2012-10-02 19:25:50 +02002967#ifndef X509_V_FLAG_CRL_CHECK
2968 if (err)
2969 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
2970 return ERR_ALERT | ERR_FATAL;
2971#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02002972 if (!*args[cur_arg + 1]) {
2973 if (err)
2974 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
2975 return ERR_ALERT | ERR_FATAL;
2976 }
Emeric Brun2b58d042012-09-20 17:10:03 +02002977
Emeric Brunef42d922012-10-11 16:11:36 +02002978 if ((*args[cur_arg + 1] != '/') && global.ca_base)
2979 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
2980 else
2981 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002982
Emeric Brun2b58d042012-09-20 17:10:03 +02002983 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02002984#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002985}
2986
2987/* parse the "ecdhe" bind keyword keywords */
2988static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2989{
2990#if OPENSSL_VERSION_NUMBER < 0x0090800fL
2991 if (err)
2992 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
2993 return ERR_ALERT | ERR_FATAL;
2994#elif defined(OPENSSL_NO_ECDH)
2995 if (err)
2996 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
2997 return ERR_ALERT | ERR_FATAL;
2998#else
2999 if (!*args[cur_arg + 1]) {
3000 if (err)
3001 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3002 return ERR_ALERT | ERR_FATAL;
3003 }
3004
3005 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003006
3007 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003008#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003009}
3010
Emeric Brun81c00f02012-09-21 14:31:21 +02003011/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3012static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3013{
3014 int code;
3015 char *p = args[cur_arg + 1];
3016 unsigned long long *ignerr = &conf->crt_ignerr;
3017
3018 if (!*p) {
3019 if (err)
3020 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3021 return ERR_ALERT | ERR_FATAL;
3022 }
3023
3024 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3025 ignerr = &conf->ca_ignerr;
3026
3027 if (strcmp(p, "all") == 0) {
3028 *ignerr = ~0ULL;
3029 return 0;
3030 }
3031
3032 while (p) {
3033 code = atoi(p);
3034 if ((code <= 0) || (code > 63)) {
3035 if (err)
3036 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3037 args[cur_arg], code, args[cur_arg + 1]);
3038 return ERR_ALERT | ERR_FATAL;
3039 }
3040 *ignerr |= 1ULL << code;
3041 p = strchr(p, ',');
3042 if (p)
3043 p++;
3044 }
3045
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003046 return 0;
3047}
3048
3049/* parse the "force-sslv3" bind keyword */
3050static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3051{
3052 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3053 return 0;
3054}
3055
3056/* parse the "force-tlsv10" bind keyword */
3057static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3058{
3059 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003060 return 0;
3061}
3062
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003063/* parse the "force-tlsv11" bind keyword */
3064static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3065{
3066#if SSL_OP_NO_TLSv1_1
3067 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3068 return 0;
3069#else
3070 if (err)
3071 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3072 return ERR_ALERT | ERR_FATAL;
3073#endif
3074}
3075
3076/* parse the "force-tlsv12" bind keyword */
3077static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3078{
3079#if SSL_OP_NO_TLSv1_2
3080 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3081 return 0;
3082#else
3083 if (err)
3084 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3085 return ERR_ALERT | ERR_FATAL;
3086#endif
3087}
3088
3089
Emeric Brun2d0c4822012-10-02 13:45:20 +02003090/* parse the "no-tls-tickets" bind keyword */
3091static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3092{
Emeric Brun89675492012-10-05 13:48:26 +02003093 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003094 return 0;
3095}
3096
Emeric Brun2d0c4822012-10-02 13:45:20 +02003097
Emeric Brun9b3009b2012-10-05 11:55:06 +02003098/* parse the "no-sslv3" bind keyword */
3099static 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 +02003100{
Emeric Brun89675492012-10-05 13:48:26 +02003101 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003102 return 0;
3103}
3104
Emeric Brun9b3009b2012-10-05 11:55:06 +02003105/* parse the "no-tlsv10" bind keyword */
3106static 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 +02003107{
Emeric Brun89675492012-10-05 13:48:26 +02003108 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003109 return 0;
3110}
3111
Emeric Brun9b3009b2012-10-05 11:55:06 +02003112/* parse the "no-tlsv11" bind keyword */
3113static 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 +02003114{
Emeric Brun89675492012-10-05 13:48:26 +02003115 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003116 return 0;
3117}
3118
Emeric Brun9b3009b2012-10-05 11:55:06 +02003119/* parse the "no-tlsv12" bind keyword */
3120static 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 +02003121{
Emeric Brun89675492012-10-05 13:48:26 +02003122 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003123 return 0;
3124}
3125
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003126/* parse the "npn" bind keyword */
3127static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3128{
3129#ifdef OPENSSL_NPN_NEGOTIATED
3130 char *p1, *p2;
3131
3132 if (!*args[cur_arg + 1]) {
3133 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3134 return ERR_ALERT | ERR_FATAL;
3135 }
3136
3137 free(conf->npn_str);
3138
3139 /* the NPN string is built as a suite of (<len> <name>)* */
3140 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3141 conf->npn_str = calloc(1, conf->npn_len);
3142 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3143
3144 /* replace commas with the name length */
3145 p1 = conf->npn_str;
3146 p2 = p1 + 1;
3147 while (1) {
3148 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3149 if (!p2)
3150 p2 = p1 + 1 + strlen(p1 + 1);
3151
3152 if (p2 - (p1 + 1) > 255) {
3153 *p2 = '\0';
3154 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3155 return ERR_ALERT | ERR_FATAL;
3156 }
3157
3158 *p1 = p2 - (p1 + 1);
3159 p1 = p2;
3160
3161 if (!*p2)
3162 break;
3163
3164 *(p2++) = '\0';
3165 }
3166 return 0;
3167#else
3168 if (err)
3169 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3170 return ERR_ALERT | ERR_FATAL;
3171#endif
3172}
3173
Willy Tarreauab861d32013-04-02 02:30:41 +02003174/* parse the "alpn" bind keyword */
3175static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3176{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003177#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003178 char *p1, *p2;
3179
3180 if (!*args[cur_arg + 1]) {
3181 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3182 return ERR_ALERT | ERR_FATAL;
3183 }
3184
3185 free(conf->alpn_str);
3186
3187 /* the ALPN string is built as a suite of (<len> <name>)* */
3188 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3189 conf->alpn_str = calloc(1, conf->alpn_len);
3190 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3191
3192 /* replace commas with the name length */
3193 p1 = conf->alpn_str;
3194 p2 = p1 + 1;
3195 while (1) {
3196 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3197 if (!p2)
3198 p2 = p1 + 1 + strlen(p1 + 1);
3199
3200 if (p2 - (p1 + 1) > 255) {
3201 *p2 = '\0';
3202 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3203 return ERR_ALERT | ERR_FATAL;
3204 }
3205
3206 *p1 = p2 - (p1 + 1);
3207 p1 = p2;
3208
3209 if (!*p2)
3210 break;
3211
3212 *(p2++) = '\0';
3213 }
3214 return 0;
3215#else
3216 if (err)
3217 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3218 return ERR_ALERT | ERR_FATAL;
3219#endif
3220}
3221
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003222/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003223static 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 +02003224{
Willy Tarreau81796be2012-09-22 19:11:47 +02003225 struct listener *l;
3226
Willy Tarreau4348fad2012-09-20 16:48:07 +02003227 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003228
3229 if (global.listen_default_ciphers && !conf->ciphers)
3230 conf->ciphers = strdup(global.listen_default_ciphers);
3231
Willy Tarreau81796be2012-09-22 19:11:47 +02003232 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003233 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003234
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003235 return 0;
3236}
3237
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003238/* parse the "strict-sni" bind keyword */
3239static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3240{
3241 conf->strict_sni = 1;
3242 return 0;
3243}
3244
Emeric Brund94b3fe2012-09-20 18:23:56 +02003245/* parse the "verify" bind keyword */
3246static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3247{
3248 if (!*args[cur_arg + 1]) {
3249 if (err)
3250 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3251 return ERR_ALERT | ERR_FATAL;
3252 }
3253
3254 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003255 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003256 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003257 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003258 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003259 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003260 else {
3261 if (err)
3262 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3263 args[cur_arg], args[cur_arg + 1]);
3264 return ERR_ALERT | ERR_FATAL;
3265 }
3266
3267 return 0;
3268}
3269
Willy Tarreau92faadf2012-10-10 23:04:25 +02003270/************** "server" keywords ****************/
3271
Emeric Brunef42d922012-10-11 16:11:36 +02003272/* parse the "ca-file" server keyword */
3273static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3274{
3275 if (!*args[*cur_arg + 1]) {
3276 if (err)
3277 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3278 return ERR_ALERT | ERR_FATAL;
3279 }
3280
3281 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3282 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3283 else
3284 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3285
3286 return 0;
3287}
3288
Willy Tarreau92faadf2012-10-10 23:04:25 +02003289/* parse the "check-ssl" server keyword */
3290static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3291{
3292 newsrv->check.use_ssl = 1;
3293 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3294 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3295 return 0;
3296}
3297
3298/* parse the "ciphers" server keyword */
3299static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3300{
3301 if (!*args[*cur_arg + 1]) {
3302 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3303 return ERR_ALERT | ERR_FATAL;
3304 }
3305
3306 free(newsrv->ssl_ctx.ciphers);
3307 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3308 return 0;
3309}
3310
Emeric Brunef42d922012-10-11 16:11:36 +02003311/* parse the "crl-file" server keyword */
3312static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3313{
3314#ifndef X509_V_FLAG_CRL_CHECK
3315 if (err)
3316 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3317 return ERR_ALERT | ERR_FATAL;
3318#else
3319 if (!*args[*cur_arg + 1]) {
3320 if (err)
3321 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
3322 return ERR_ALERT | ERR_FATAL;
3323 }
3324
3325 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3326 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3327 else
3328 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
3329
3330 return 0;
3331#endif
3332}
3333
Emeric Bruna7aa3092012-10-26 12:58:00 +02003334/* parse the "crt" server keyword */
3335static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3336{
3337 if (!*args[*cur_arg + 1]) {
3338 if (err)
3339 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
3340 return ERR_ALERT | ERR_FATAL;
3341 }
3342
3343 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
3344 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3345 else
3346 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
3347
3348 return 0;
3349}
Emeric Brunef42d922012-10-11 16:11:36 +02003350
Willy Tarreau92faadf2012-10-10 23:04:25 +02003351/* parse the "force-sslv3" server keyword */
3352static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3353{
3354 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
3355 return 0;
3356}
3357
3358/* parse the "force-tlsv10" server keyword */
3359static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3360{
3361 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
3362 return 0;
3363}
3364
3365/* parse the "force-tlsv11" server keyword */
3366static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3367{
3368#if SSL_OP_NO_TLSv1_1
3369 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
3370 return 0;
3371#else
3372 if (err)
3373 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
3374 return ERR_ALERT | ERR_FATAL;
3375#endif
3376}
3377
3378/* parse the "force-tlsv12" server keyword */
3379static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3380{
3381#if SSL_OP_NO_TLSv1_2
3382 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
3383 return 0;
3384#else
3385 if (err)
3386 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
3387 return ERR_ALERT | ERR_FATAL;
3388#endif
3389}
3390
3391/* parse the "no-sslv3" server keyword */
3392static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3393{
3394 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
3395 return 0;
3396}
3397
3398/* parse the "no-tlsv10" server keyword */
3399static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3400{
3401 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
3402 return 0;
3403}
3404
3405/* parse the "no-tlsv11" server keyword */
3406static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3407{
3408 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
3409 return 0;
3410}
3411
3412/* parse the "no-tlsv12" server keyword */
3413static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3414{
3415 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
3416 return 0;
3417}
3418
Emeric Brunf9c5c472012-10-11 15:28:34 +02003419/* parse the "no-tls-tickets" server keyword */
3420static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3421{
3422 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
3423 return 0;
3424}
David Safb76832014-05-08 23:42:08 -04003425/* parse the "send-proxy-v2-ssl" server keyword */
3426static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3427{
3428 newsrv->pp_opts |= SRV_PP_V2;
3429 newsrv->pp_opts |= SRV_PP_V2_SSL;
3430 return 0;
3431}
3432
3433/* parse the "send-proxy-v2-ssl-cn" server keyword */
3434static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3435{
3436 newsrv->pp_opts |= SRV_PP_V2;
3437 newsrv->pp_opts |= SRV_PP_V2_SSL;
3438 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
3439 return 0;
3440}
Emeric Brunf9c5c472012-10-11 15:28:34 +02003441
Willy Tarreau92faadf2012-10-10 23:04:25 +02003442/* parse the "ssl" server keyword */
3443static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3444{
3445 newsrv->use_ssl = 1;
3446 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3447 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3448 return 0;
3449}
3450
Emeric Brunef42d922012-10-11 16:11:36 +02003451/* parse the "verify" server keyword */
3452static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3453{
3454 if (!*args[*cur_arg + 1]) {
3455 if (err)
3456 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
3457 return ERR_ALERT | ERR_FATAL;
3458 }
3459
3460 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003461 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02003462 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003463 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02003464 else {
3465 if (err)
3466 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
3467 args[*cur_arg], args[*cur_arg + 1]);
3468 return ERR_ALERT | ERR_FATAL;
3469 }
3470
Evan Broderbe554312013-06-27 00:05:25 -07003471 return 0;
3472}
3473
3474/* parse the "verifyhost" server keyword */
3475static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3476{
3477 if (!*args[*cur_arg + 1]) {
3478 if (err)
3479 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
3480 return ERR_ALERT | ERR_FATAL;
3481 }
3482
3483 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
3484
Emeric Brunef42d922012-10-11 16:11:36 +02003485 return 0;
3486}
3487
Willy Tarreau7875d092012-09-10 08:20:03 +02003488/* Note: must not be declared <const> as its list will be overwritten.
3489 * Please take care of keeping this list alphabetically sorted.
3490 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003491static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02003492 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
3493 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
3494 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
3495 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02003496 { "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 +02003497 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
3498 { "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 +01003499 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3500 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3501 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003502 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3503 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3504 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3505 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3506 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3507 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3508 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3509 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003510 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3511 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003512 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3513 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3514 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3515 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3516 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3517 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3518 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3519 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02003520 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003521 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003522 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3523 { "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 +01003524 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003525 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3526 { "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 +02003527#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003528 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003529#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003530#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003531 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02003532#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003533 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02003534 { "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 +01003535 { "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 +01003536 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3537 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02003538 { NULL, NULL, 0, 0, 0 },
3539}};
3540
3541/* Note: must not be declared <const> as its list will be overwritten.
3542 * Please take care of keeping this list alphabetically sorted.
3543 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003544static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003545 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
3546 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01003547 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02003548}};
3549
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003550/* Note: must not be declared <const> as its list will be overwritten.
3551 * Please take care of keeping this list alphabetically sorted, doing so helps
3552 * all code contributors.
3553 * Optional keywords are also declared with a NULL ->parse() function so that
3554 * the config parser can report an appropriate error when a known keyword was
3555 * not enabled.
3556 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02003557static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02003558 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003559 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003560 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
3561 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003562 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003563 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
3564 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003565 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003566 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003567 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
3568 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
3569 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
3570 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02003571 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
3572 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
3573 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
3574 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003575 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003576 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003577 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003578 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003579 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003580 { NULL, NULL, 0 },
3581}};
Emeric Brun46591952012-05-18 15:47:34 +02003582
Willy Tarreau92faadf2012-10-10 23:04:25 +02003583/* Note: must not be declared <const> as its list will be overwritten.
3584 * Please take care of keeping this list alphabetically sorted, doing so helps
3585 * all code contributors.
3586 * Optional keywords are also declared with a NULL ->parse() function so that
3587 * the config parser can report an appropriate error when a known keyword was
3588 * not enabled.
3589 */
3590static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02003591 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003592 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
3593 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02003594 { "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 +02003595 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003596 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
3597 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
3598 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
3599 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
3600 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
3601 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
3602 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
3603 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02003604 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04003605 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
3606 { "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 +02003607 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02003608 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07003609 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02003610 { NULL, NULL, 0, 0 },
3611}};
3612
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003613/* transport-layer operations for SSL sockets */
3614struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02003615 .snd_buf = ssl_sock_from_buf,
3616 .rcv_buf = ssl_sock_to_buf,
3617 .rcv_pipe = NULL,
3618 .snd_pipe = NULL,
3619 .shutr = NULL,
3620 .shutw = ssl_sock_shutw,
3621 .close = ssl_sock_close,
3622 .init = ssl_sock_init,
3623};
3624
3625__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02003626static void __ssl_sock_init(void)
3627{
Emeric Brun46591952012-05-18 15:47:34 +02003628 STACK_OF(SSL_COMP)* cm;
3629
Willy Tarreau610f04b2014-02-13 11:36:41 +01003630#ifdef LISTEN_DEFAULT_CIPHERS
3631 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
3632#endif
3633#ifdef CONNECT_DEFAULT_CIPHERS
3634 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
3635#endif
3636 if (global.listen_default_ciphers)
3637 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
3638 if (global.connect_default_ciphers)
3639 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
3640
Emeric Brun46591952012-05-18 15:47:34 +02003641 SSL_library_init();
3642 cm = SSL_COMP_get_compression_methods();
3643 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02003644 sample_register_fetches(&sample_fetch_keywords);
3645 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003646 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02003647 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02003648}
3649
3650/*
3651 * Local variables:
3652 * c-indent-level: 8
3653 * c-basic-offset: 8
3654 * End:
3655 */