blob: 229290f864bc0e1e5b933aa4d94466b175a5ec3f [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;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200731 int ssloptions =
732 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;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200739 int sslmode =
740 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);
Emeric Brun29f037d2014-04-25 19:05:36 +0200832 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
833
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200834#ifdef OPENSSL_NPN_NEGOTIATED
835 if (bind_conf->npn_str)
836 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
837#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100838#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200839 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100840 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +0200841#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200842
Emeric Brunfc0421f2012-09-07 17:30:07 +0200843#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
844 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200845 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200846#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200847#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +0100848 {
Emeric Brun2b58d042012-09-20 17:10:03 +0200849 int i;
850 EC_KEY *ecdh;
851
Emeric Brun6924ef82013-03-06 14:08:53 +0100852 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +0200853 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
854 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 +0100855 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
856 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +0200857 cfgerr++;
858 }
859 else {
860 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
861 EC_KEY_free(ecdh);
862 }
863 }
864#endif
865
Emeric Brunfc0421f2012-09-07 17:30:07 +0200866 return cfgerr;
867}
868
Evan Broderbe554312013-06-27 00:05:25 -0700869static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
870{
871 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
872 size_t prefixlen, suffixlen;
873
874 /* Trivial case */
875 if (strcmp(pattern, hostname) == 0)
876 return 1;
877
Evan Broderbe554312013-06-27 00:05:25 -0700878 /* The rest of this logic is based on RFC 6125, section 6.4.3
879 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
880
Emeric Bruna848dae2013-10-08 11:27:28 +0200881 pattern_wildcard = NULL;
882 pattern_left_label_end = pattern;
883 while (*pattern_left_label_end != '.') {
884 switch (*pattern_left_label_end) {
885 case 0:
886 /* End of label not found */
887 return 0;
888 case '*':
889 /* If there is more than one wildcards */
890 if (pattern_wildcard)
891 return 0;
892 pattern_wildcard = pattern_left_label_end;
893 break;
894 }
895 pattern_left_label_end++;
896 }
897
898 /* If it's not trivial and there is no wildcard, it can't
899 * match */
900 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -0700901 return 0;
902
903 /* Make sure all labels match except the leftmost */
904 hostname_left_label_end = strchr(hostname, '.');
905 if (!hostname_left_label_end
906 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
907 return 0;
908
909 /* Make sure the leftmost label of the hostname is long enough
910 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +0200911 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -0700912 return 0;
913
914 /* Finally compare the string on either side of the
915 * wildcard */
916 prefixlen = pattern_wildcard - pattern;
917 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +0200918 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
919 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -0700920 return 0;
921
922 return 1;
923}
924
925static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
926{
927 SSL *ssl;
928 struct connection *conn;
929 char *servername;
930
931 int depth;
932 X509 *cert;
933 STACK_OF(GENERAL_NAME) *alt_names;
934 int i;
935 X509_NAME *cert_subject;
936 char *str;
937
938 if (ok == 0)
939 return ok;
940
941 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
942 conn = (struct connection *)SSL_get_app_data(ssl);
943
944 servername = objt_server(conn->target)->ssl_ctx.verify_host;
945
946 /* We only need to verify the CN on the actual server cert,
947 * not the indirect CAs */
948 depth = X509_STORE_CTX_get_error_depth(ctx);
949 if (depth != 0)
950 return ok;
951
952 /* At this point, the cert is *not* OK unless we can find a
953 * hostname match */
954 ok = 0;
955
956 cert = X509_STORE_CTX_get_current_cert(ctx);
957 /* It seems like this might happen if verify peer isn't set */
958 if (!cert)
959 return ok;
960
961 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
962 if (alt_names) {
963 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
964 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
965 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200966#if OPENSSL_VERSION_NUMBER < 0x00907000L
967 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
968#else
Evan Broderbe554312013-06-27 00:05:25 -0700969 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200970#endif
Evan Broderbe554312013-06-27 00:05:25 -0700971 ok = ssl_sock_srv_hostcheck(str, servername);
972 OPENSSL_free(str);
973 }
974 }
975 }
Emeric Brun4ad50a42013-09-17 15:19:54 +0200976 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -0700977 }
978
979 cert_subject = X509_get_subject_name(cert);
980 i = -1;
981 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
982 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
983 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
984 ok = ssl_sock_srv_hostcheck(str, servername);
985 OPENSSL_free(str);
986 }
987 }
988
989 return ok;
990}
991
Emeric Brun94324a42012-10-11 14:00:19 +0200992/* prepare ssl context from servers options. Returns an error count */
993int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
994{
995 int cfgerr = 0;
996 int options =
997 SSL_OP_ALL | /* all known workarounds for bugs */
998 SSL_OP_NO_SSLv2 |
999 SSL_OP_NO_COMPRESSION;
1000 int mode =
1001 SSL_MODE_ENABLE_PARTIAL_WRITE |
1002 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1003 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001004 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001005
Thierry Fournier383085f2013-01-24 14:15:43 +01001006 /* Make sure openssl opens /dev/urandom before the chroot */
1007 if (!ssl_initialize_random()) {
1008 Alert("OpenSSL random data generator initialization failed.\n");
1009 cfgerr++;
1010 }
1011
Emeric Brun94324a42012-10-11 14:00:19 +02001012 /* Initiate SSL context for current server */
1013 srv->ssl_ctx.reused_sess = NULL;
1014 if (srv->use_ssl)
1015 srv->xprt = &ssl_sock;
1016 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001017 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001018
1019 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1020 if (!srv->ssl_ctx.ctx) {
1021 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1022 proxy_type_str(curproxy), curproxy->id,
1023 srv->id);
1024 cfgerr++;
1025 return cfgerr;
1026 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001027 if (srv->ssl_ctx.client_crt) {
1028 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1029 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1030 proxy_type_str(curproxy), curproxy->id,
1031 srv->id, srv->ssl_ctx.client_crt);
1032 cfgerr++;
1033 }
1034 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1035 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1036 proxy_type_str(curproxy), curproxy->id,
1037 srv->id, srv->ssl_ctx.client_crt);
1038 cfgerr++;
1039 }
1040 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1041 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1042 proxy_type_str(curproxy), curproxy->id,
1043 srv->id, srv->ssl_ctx.client_crt);
1044 cfgerr++;
1045 }
1046 }
Emeric Brun94324a42012-10-11 14:00:19 +02001047
1048 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1049 options |= SSL_OP_NO_SSLv3;
1050 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1051 options |= SSL_OP_NO_TLSv1;
1052 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1053 options |= SSL_OP_NO_TLSv1_1;
1054 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1055 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001056 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1057 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001058 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1059 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1060 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1061 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1062#if SSL_OP_NO_TLSv1_1
1063 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1064 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1065#endif
1066#if SSL_OP_NO_TLSv1_2
1067 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1068 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1069#endif
1070
1071 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1072 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001073
1074 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1075 verify = SSL_VERIFY_PEER;
1076
1077 switch (srv->ssl_ctx.verify) {
1078 case SSL_SOCK_VERIFY_NONE:
1079 verify = SSL_VERIFY_NONE;
1080 break;
1081 case SSL_SOCK_VERIFY_REQUIRED:
1082 verify = SSL_VERIFY_PEER;
1083 break;
1084 }
Evan Broderbe554312013-06-27 00:05:25 -07001085 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001086 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001087 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001088 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001089 if (srv->ssl_ctx.ca_file) {
1090 /* load CAfile to verify */
1091 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001092 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001093 curproxy->id, srv->id,
1094 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1095 cfgerr++;
1096 }
1097 }
Emeric Brun850efd52014-01-29 12:24:34 +01001098 else {
1099 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001100 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 +01001101 curproxy->id, srv->id,
1102 srv->conf.file, srv->conf.line);
1103 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001104 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001105 curproxy->id, srv->id,
1106 srv->conf.file, srv->conf.line);
1107 cfgerr++;
1108 }
Emeric Brunef42d922012-10-11 16:11:36 +02001109#ifdef X509_V_FLAG_CRL_CHECK
1110 if (srv->ssl_ctx.crl_file) {
1111 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1112
1113 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001114 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001115 curproxy->id, srv->id,
1116 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1117 cfgerr++;
1118 }
1119 else {
1120 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1121 }
1122 }
1123#endif
1124 }
1125
Emeric Brun4f65bff2012-11-16 15:11:00 +01001126 if (global.tune.ssllifetime)
1127 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1128
Emeric Brun94324a42012-10-11 14:00:19 +02001129 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1130 if (srv->ssl_ctx.ciphers &&
1131 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1132 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1133 curproxy->id, srv->id,
1134 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1135 cfgerr++;
1136 }
1137
1138 return cfgerr;
1139}
1140
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001141/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001142 * be NULL, in which case nothing is done. Returns the number of errors
1143 * encountered.
1144 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001145int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001146{
1147 struct ebmb_node *node;
1148 struct sni_ctx *sni;
1149 int err = 0;
1150
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001151 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001152 return 0;
1153
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001154 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001155 while (node) {
1156 sni = ebmb_entry(node, struct sni_ctx, name);
1157 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001158 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001159 node = ebmb_next(node);
1160 }
1161
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001162 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001163 while (node) {
1164 sni = ebmb_entry(node, struct sni_ctx, name);
1165 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001166 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001167 node = ebmb_next(node);
1168 }
1169 return err;
1170}
1171
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001172/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001173 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1174 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001175void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001176{
1177 struct ebmb_node *node, *back;
1178 struct sni_ctx *sni;
1179
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001180 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001181 return;
1182
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001183 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001184 while (node) {
1185 sni = ebmb_entry(node, struct sni_ctx, name);
1186 back = ebmb_next(node);
1187 ebmb_delete(node);
1188 if (!sni->order) /* only free the CTX on its first occurrence */
1189 SSL_CTX_free(sni->ctx);
1190 free(sni);
1191 node = back;
1192 }
1193
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001194 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001195 while (node) {
1196 sni = ebmb_entry(node, struct sni_ctx, name);
1197 back = ebmb_next(node);
1198 ebmb_delete(node);
1199 if (!sni->order) /* only free the CTX on its first occurrence */
1200 SSL_CTX_free(sni->ctx);
1201 free(sni);
1202 node = back;
1203 }
1204
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001205 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001206}
1207
Emeric Brun46591952012-05-18 15:47:34 +02001208/*
1209 * This function is called if SSL * context is not yet allocated. The function
1210 * is designed to be called before any other data-layer operation and sets the
1211 * handshake flag on the connection. It is safe to call it multiple times.
1212 * It returns 0 on success and -1 in error case.
1213 */
1214static int ssl_sock_init(struct connection *conn)
1215{
1216 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001217 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001218 return 0;
1219
Willy Tarreau3c728722014-01-23 13:50:42 +01001220 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001221 return 0;
1222
Willy Tarreau20879a02012-12-03 16:32:10 +01001223 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1224 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001225 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001226 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001227
Emeric Brun46591952012-05-18 15:47:34 +02001228 /* If it is in client mode initiate SSL session
1229 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001230 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001231 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001232 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001233 if (!conn->xprt_ctx) {
1234 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001235 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001236 }
Emeric Brun46591952012-05-18 15:47:34 +02001237
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001238 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001239 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1240 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001241
1242 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001243 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001244
Evan Broderbe554312013-06-27 00:05:25 -07001245 /* set connection pointer */
1246 SSL_set_app_data(conn->xprt_ctx, conn);
1247
Emeric Brun46591952012-05-18 15:47:34 +02001248 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001249 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001250
1251 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001252 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001253 return 0;
1254 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001255 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001256 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001257 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001258 if (!conn->xprt_ctx) {
1259 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001260 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001261 }
Emeric Brun46591952012-05-18 15:47:34 +02001262
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001263 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001264
1265 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001266 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001267
Emeric Brune1f38db2012-09-03 20:36:47 +02001268 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001269 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02001270
Emeric Brun46591952012-05-18 15:47:34 +02001271 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001272 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001273
1274 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001275 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001276 return 0;
1277 }
1278 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01001279 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02001280 return -1;
1281}
1282
1283
1284/* This is the callback which is used when an SSL handshake is pending. It
1285 * updates the FD status if it wants some polling before being called again.
1286 * It returns 0 if it fails in a fatal way or needs to poll to go further,
1287 * otherwise it returns non-zero and removes itself from the connection's
1288 * flags (the bit is provided in <flag> by the caller).
1289 */
1290int ssl_sock_handshake(struct connection *conn, unsigned int flag)
1291{
1292 int ret;
1293
Willy Tarreau3c728722014-01-23 13:50:42 +01001294 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001295 return 0;
1296
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001297 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001298 goto out_error;
1299
Emeric Brun674b7432012-11-08 19:21:55 +01001300 /* If we use SSL_do_handshake to process a reneg initiated by
1301 * the remote peer, it sometimes returns SSL_ERROR_SSL.
1302 * Usually SSL_write and SSL_read are used and process implicitly
1303 * the reneg handshake.
1304 * Here we use SSL_peek as a workaround for reneg.
1305 */
1306 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
1307 char c;
1308
1309 ret = SSL_peek(conn->xprt_ctx, &c, 1);
1310 if (ret <= 0) {
1311 /* handshake may have not been completed, let's find why */
1312 ret = SSL_get_error(conn->xprt_ctx, ret);
1313 if (ret == SSL_ERROR_WANT_WRITE) {
1314 /* SSL handshake needs to write, L4 connection may not be ready */
1315 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001316 __conn_sock_want_send(conn);
1317 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001318 return 0;
1319 }
1320 else if (ret == SSL_ERROR_WANT_READ) {
1321 /* handshake may have been completed but we have
1322 * no more data to read.
1323 */
1324 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
1325 ret = 1;
1326 goto reneg_ok;
1327 }
1328 /* SSL handshake needs to read, L4 connection is ready */
1329 if (conn->flags & CO_FL_WAIT_L4_CONN)
1330 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1331 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001332 __conn_sock_want_recv(conn);
1333 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001334 return 0;
1335 }
1336 else if (ret == SSL_ERROR_SYSCALL) {
1337 /* if errno is null, then connection was successfully established */
1338 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1339 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001340 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02001341 if (!((SSL *)conn->xprt_ctx)->packet_length) {
1342 if (!errno) {
1343 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1344 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1345 else
1346 conn->err_code = CO_ER_SSL_EMPTY;
1347 }
1348 else {
1349 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1350 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1351 else
1352 conn->err_code = CO_ER_SSL_ABORT;
1353 }
1354 }
1355 else {
1356 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1357 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01001358 else
Emeric Brun29f037d2014-04-25 19:05:36 +02001359 conn->err_code = CO_ER_SSL_HANDSHAKE;
1360 }
Willy Tarreau20879a02012-12-03 16:32:10 +01001361 }
Emeric Brun674b7432012-11-08 19:21:55 +01001362 goto out_error;
1363 }
1364 else {
1365 /* Fail on all other handshake errors */
1366 /* Note: OpenSSL may leave unread bytes in the socket's
1367 * buffer, causing an RST to be emitted upon close() on
1368 * TCP sockets. We first try to drain possibly pending
1369 * data to avoid this as much as possible.
1370 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001371 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001372 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001373 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
1374 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01001375 goto out_error;
1376 }
1377 }
1378 /* read some data: consider handshake completed */
1379 goto reneg_ok;
1380 }
1381
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001382 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001383 if (ret != 1) {
1384 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001385 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001386
1387 if (ret == SSL_ERROR_WANT_WRITE) {
1388 /* SSL handshake needs to write, L4 connection may not be ready */
1389 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001390 __conn_sock_want_send(conn);
1391 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001392 return 0;
1393 }
1394 else if (ret == SSL_ERROR_WANT_READ) {
1395 /* SSL handshake needs to read, L4 connection is ready */
1396 if (conn->flags & CO_FL_WAIT_L4_CONN)
1397 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1398 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001399 __conn_sock_want_recv(conn);
1400 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001401 return 0;
1402 }
Willy Tarreau89230192012-09-28 20:22:13 +02001403 else if (ret == SSL_ERROR_SYSCALL) {
1404 /* if errno is null, then connection was successfully established */
1405 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1406 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001407
Emeric Brun29f037d2014-04-25 19:05:36 +02001408 if (!((SSL *)conn->xprt_ctx)->packet_length) {
1409 if (!errno) {
1410 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1411 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1412 else
1413 conn->err_code = CO_ER_SSL_EMPTY;
1414 }
1415 else {
1416 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1417 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1418 else
1419 conn->err_code = CO_ER_SSL_ABORT;
1420 }
1421 }
1422 else {
1423 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1424 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01001425 else
Emeric Brun29f037d2014-04-25 19:05:36 +02001426 conn->err_code = CO_ER_SSL_HANDSHAKE;
1427 }
Willy Tarreau89230192012-09-28 20:22:13 +02001428 goto out_error;
1429 }
Emeric Brun46591952012-05-18 15:47:34 +02001430 else {
1431 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02001432 /* Note: OpenSSL may leave unread bytes in the socket's
1433 * buffer, causing an RST to be emitted upon close() on
1434 * TCP sockets. We first try to drain possibly pending
1435 * data to avoid this as much as possible.
1436 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001437 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001438 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001439 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
1440 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001441 goto out_error;
1442 }
1443 }
1444
Emeric Brun674b7432012-11-08 19:21:55 +01001445reneg_ok:
1446
Emeric Brun46591952012-05-18 15:47:34 +02001447 /* Handshake succeeded */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001448 if (objt_server(conn->target)) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001449 if (!SSL_session_reused(conn->xprt_ctx)) {
Emeric Brun46591952012-05-18 15:47:34 +02001450 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001451 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1452 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001453
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001454 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001455 }
1456 }
1457
1458 /* The connection is now established at both layers, it's time to leave */
1459 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
1460 return 1;
1461
1462 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001463 /* Clear openssl global errors stack */
1464 ERR_clear_error();
1465
Emeric Brun9fa89732012-10-04 17:09:56 +02001466 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001467 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
1468 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
1469 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02001470 }
1471
Emeric Brun46591952012-05-18 15:47:34 +02001472 /* Fail on all other handshake errors */
1473 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001474 if (!conn->err_code)
1475 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001476 return 0;
1477}
1478
1479/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01001480 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02001481 * buffer wraps, in which case a second call may be performed. The connection's
1482 * flags are updated with whatever special event is detected (error, read0,
1483 * empty). The caller is responsible for taking care of those events and
1484 * avoiding the call if inappropriate. The function does not call the
1485 * connection's polling update function, so the caller is responsible for this.
1486 */
1487static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
1488{
1489 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01001490 int try;
Emeric Brun46591952012-05-18 15:47:34 +02001491
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001492 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001493 goto out_error;
1494
1495 if (conn->flags & CO_FL_HANDSHAKE)
1496 /* a handshake was requested */
1497 return 0;
1498
Willy Tarreauabf08d92014-01-14 11:31:27 +01001499 /* let's realign the buffer to optimize I/O */
1500 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02001501 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02001502
1503 /* read the largest possible block. For this, we perform only one call
1504 * to recv() unless the buffer wraps and we exactly fill the first hunk,
1505 * in which case we accept to do it once again. A new attempt is made on
1506 * EINTR too.
1507 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01001508 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01001509 /* first check if we have some room after p+i */
1510 try = buf->data + buf->size - (buf->p + buf->i);
1511 /* otherwise continue between data and p-o */
1512 if (try <= 0) {
1513 try = buf->p - (buf->data + buf->o);
1514 if (try <= 0)
1515 break;
1516 }
1517 if (try > count)
1518 try = count;
1519
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001520 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02001521 if (conn->flags & CO_FL_ERROR) {
1522 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001523 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001524 }
Emeric Brun46591952012-05-18 15:47:34 +02001525 if (ret > 0) {
1526 buf->i += ret;
1527 done += ret;
1528 if (ret < try)
1529 break;
1530 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02001531 }
1532 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01001533 ret = SSL_get_error(conn->xprt_ctx, ret);
1534 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01001535 /* error on protocol or underlying transport */
1536 if ((ret != SSL_ERROR_SYSCALL)
1537 || (errno && (errno != EAGAIN)))
1538 conn->flags |= CO_FL_ERROR;
1539
Emeric Brun644cde02012-12-14 11:21:13 +01001540 /* Clear openssl global errors stack */
1541 ERR_clear_error();
1542 }
Emeric Brun46591952012-05-18 15:47:34 +02001543 goto read0;
1544 }
1545 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001546 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001547 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001548 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02001549 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001550 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001551 break;
1552 }
1553 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001554 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1555 /* handshake is running, and it may need to re-enable read */
1556 conn->flags |= CO_FL_SSL_WAIT_HS;
1557 __conn_sock_want_recv(conn);
1558 break;
1559 }
Emeric Brun46591952012-05-18 15:47:34 +02001560 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001561 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001562 break;
1563 }
1564 /* otherwise it's a real error */
1565 goto out_error;
1566 }
1567 }
1568 return done;
1569
1570 read0:
1571 conn_sock_read0(conn);
1572 return done;
1573 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001574 /* Clear openssl global errors stack */
1575 ERR_clear_error();
1576
Emeric Brun46591952012-05-18 15:47:34 +02001577 conn->flags |= CO_FL_ERROR;
1578 return done;
1579}
1580
1581
1582/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01001583 * <flags> may contain some CO_SFL_* flags to hint the system about other
1584 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02001585 * Only one call to send() is performed, unless the buffer wraps, in which case
1586 * a second call may be performed. The connection's flags are updated with
1587 * whatever special event is detected (error, empty). The caller is responsible
1588 * for taking care of those events and avoiding the call if inappropriate. The
1589 * function does not call the connection's polling update function, so the caller
1590 * is responsible for this.
1591 */
1592static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
1593{
1594 int ret, try, done;
1595
1596 done = 0;
1597
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001598 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001599 goto out_error;
1600
1601 if (conn->flags & CO_FL_HANDSHAKE)
1602 /* a handshake was requested */
1603 return 0;
1604
1605 /* send the largest possible block. For this we perform only one call
1606 * to send() unless the buffer wraps and we exactly fill the first hunk,
1607 * in which case we accept to do it once again.
1608 */
1609 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07001610 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01001611
Willy Tarreau7bed9452014-02-02 02:00:24 +01001612 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01001613 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
1614 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01001615 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01001616 }
1617 else {
1618 /* we need to keep the information about the fact that
1619 * we're not limiting the upcoming send(), because if it
1620 * fails, we'll have to retry with at least as many data.
1621 */
1622 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
1623 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01001624
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001625 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01001626
Emeric Brune1f38db2012-09-03 20:36:47 +02001627 if (conn->flags & CO_FL_ERROR) {
1628 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001629 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001630 }
Emeric Brun46591952012-05-18 15:47:34 +02001631 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01001632 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
1633
Emeric Brun46591952012-05-18 15:47:34 +02001634 buf->o -= ret;
1635 done += ret;
1636
Willy Tarreau5fb38032012-12-16 19:39:09 +01001637 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02001638 /* optimize data alignment in the buffer */
1639 buf->p = buf->data;
1640
1641 /* if the system buffer is full, don't insist */
1642 if (ret < try)
1643 break;
1644 }
1645 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001646 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001647 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001648 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1649 /* handshake is running, and it may need to re-enable write */
1650 conn->flags |= CO_FL_SSL_WAIT_HS;
1651 __conn_sock_want_send(conn);
1652 break;
1653 }
Emeric Brun46591952012-05-18 15:47:34 +02001654 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001655 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001656 break;
1657 }
1658 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001659 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02001660 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001661 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001662 break;
1663 }
1664 goto out_error;
1665 }
1666 }
1667 return done;
1668
1669 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001670 /* Clear openssl global errors stack */
1671 ERR_clear_error();
1672
Emeric Brun46591952012-05-18 15:47:34 +02001673 conn->flags |= CO_FL_ERROR;
1674 return done;
1675}
1676
Emeric Brun46591952012-05-18 15:47:34 +02001677static void ssl_sock_close(struct connection *conn) {
1678
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001679 if (conn->xprt_ctx) {
1680 SSL_free(conn->xprt_ctx);
1681 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02001682 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02001683 }
Emeric Brun46591952012-05-18 15:47:34 +02001684}
1685
1686/* This function tries to perform a clean shutdown on an SSL connection, and in
1687 * any case, flags the connection as reusable if no handshake was in progress.
1688 */
1689static void ssl_sock_shutw(struct connection *conn, int clean)
1690{
1691 if (conn->flags & CO_FL_HANDSHAKE)
1692 return;
1693 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01001694 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
1695 /* Clear openssl global errors stack */
1696 ERR_clear_error();
1697 }
Emeric Brun46591952012-05-18 15:47:34 +02001698
1699 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001700 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02001701}
1702
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02001703/* used for logging, may be changed for a sample fetch later */
1704const char *ssl_sock_get_cipher_name(struct connection *conn)
1705{
1706 if (!conn->xprt && !conn->xprt_ctx)
1707 return NULL;
1708 return SSL_get_cipher_name(conn->xprt_ctx);
1709}
1710
1711/* used for logging, may be changed for a sample fetch later */
1712const char *ssl_sock_get_proto_version(struct connection *conn)
1713{
1714 if (!conn->xprt && !conn->xprt_ctx)
1715 return NULL;
1716 return SSL_get_version(conn->xprt_ctx);
1717}
1718
Willy Tarreau8d598402012-10-22 17:58:39 +02001719/* Extract a serial from a cert, and copy it to a chunk.
1720 * Returns 1 if serial is found and copied, 0 if no serial found and
1721 * -1 if output is not large enough.
1722 */
1723static int
1724ssl_sock_get_serial(X509 *crt, struct chunk *out)
1725{
1726 ASN1_INTEGER *serial;
1727
1728 serial = X509_get_serialNumber(crt);
1729 if (!serial)
1730 return 0;
1731
1732 if (out->size < serial->length)
1733 return -1;
1734
1735 memcpy(out->str, serial->data, serial->length);
1736 out->len = serial->length;
1737 return 1;
1738}
1739
Emeric Brunce5ad802012-10-22 14:11:22 +02001740
1741/* Copy Date in ASN1_UTCTIME format in struct chunk out.
1742 * Returns 1 if serial is found and copied, 0 if no valid time found
1743 * and -1 if output is not large enough.
1744 */
1745static int
1746ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
1747{
1748 if (tm->type == V_ASN1_GENERALIZEDTIME) {
1749 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
1750
1751 if (gentm->length < 12)
1752 return 0;
1753 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
1754 return 0;
1755 if (out->size < gentm->length-2)
1756 return -1;
1757
1758 memcpy(out->str, gentm->data+2, gentm->length-2);
1759 out->len = gentm->length-2;
1760 return 1;
1761 }
1762 else if (tm->type == V_ASN1_UTCTIME) {
1763 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
1764
1765 if (utctm->length < 10)
1766 return 0;
1767 if (utctm->data[0] >= 0x35)
1768 return 0;
1769 if (out->size < utctm->length)
1770 return -1;
1771
1772 memcpy(out->str, utctm->data, utctm->length);
1773 out->len = utctm->length;
1774 return 1;
1775 }
1776
1777 return 0;
1778}
1779
Emeric Brun87855892012-10-17 17:39:35 +02001780/* Extract an entry from a X509_NAME and copy its value to an output chunk.
1781 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
1782 */
1783static int
1784ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
1785{
1786 X509_NAME_ENTRY *ne;
1787 int i, j, n;
1788 int cur = 0;
1789 const char *s;
1790 char tmp[128];
1791
1792 out->len = 0;
1793 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1794 if (pos < 0)
1795 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
1796 else
1797 j = i;
1798
1799 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
1800 n = OBJ_obj2nid(ne->object);
1801 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1802 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1803 s = tmp;
1804 }
1805
1806 if (chunk_strcasecmp(entry, s) != 0)
1807 continue;
1808
1809 if (pos < 0)
1810 cur--;
1811 else
1812 cur++;
1813
1814 if (cur != pos)
1815 continue;
1816
1817 if (ne->value->length > out->size)
1818 return -1;
1819
1820 memcpy(out->str, ne->value->data, ne->value->length);
1821 out->len = ne->value->length;
1822 return 1;
1823 }
1824
1825 return 0;
1826
1827}
1828
1829/* Extract and format full DN from a X509_NAME and copy result into a chunk
1830 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
1831 */
1832static int
1833ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
1834{
1835 X509_NAME_ENTRY *ne;
1836 int i, n, ln;
1837 int l = 0;
1838 const char *s;
1839 char *p;
1840 char tmp[128];
1841
1842 out->len = 0;
1843 p = out->str;
1844 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1845 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
1846 n = OBJ_obj2nid(ne->object);
1847 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1848 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1849 s = tmp;
1850 }
1851 ln = strlen(s);
1852
1853 l += 1 + ln + 1 + ne->value->length;
1854 if (l > out->size)
1855 return -1;
1856 out->len = l;
1857
1858 *(p++)='/';
1859 memcpy(p, s, ln);
1860 p += ln;
1861 *(p++)='=';
1862 memcpy(p, ne->value->data, ne->value->length);
1863 p += ne->value->length;
1864 }
1865
1866 if (!out->len)
1867 return 0;
1868
1869 return 1;
1870}
1871
Willy Tarreau7875d092012-09-10 08:20:03 +02001872/***** Below are some sample fetching functions for ACL/patterns *****/
1873
Emeric Brune64aef12012-09-21 13:15:06 +02001874/* boolean, returns true if client cert was present */
1875static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02001876smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001877 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02001878{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001879 struct connection *conn;
1880
1881 if (!l4)
1882 return 0;
1883
1884 conn = objt_conn(l4->si[0].end);
1885 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02001886 return 0;
1887
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001888 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02001889 smp->flags |= SMP_F_MAY_CHANGE;
1890 return 0;
1891 }
1892
1893 smp->flags = 0;
1894 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001895 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001896
1897 return 1;
1898}
1899
Emeric Brunba841a12014-04-30 17:05:08 +02001900/* binary, returns serial of certificate in a binary chunk.
1901 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
1902 * should be use.
1903 */
Willy Tarreau8d598402012-10-22 17:58:39 +02001904static int
Emeric Brunba841a12014-04-30 17:05:08 +02001905smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001906 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02001907{
Emeric Brunba841a12014-04-30 17:05:08 +02001908 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001909 X509 *crt = NULL;
1910 int ret = 0;
1911 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001912 struct connection *conn;
1913
1914 if (!l4)
1915 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001916
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001917 conn = objt_conn(l4->si[0].end);
1918 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02001919 return 0;
1920
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001921 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02001922 smp->flags |= SMP_F_MAY_CHANGE;
1923 return 0;
1924 }
1925
Emeric Brunba841a12014-04-30 17:05:08 +02001926 if (cert_peer)
1927 crt = SSL_get_peer_certificate(conn->xprt_ctx);
1928 else
1929 crt = SSL_get_certificate(conn->xprt_ctx);
1930
Willy Tarreau8d598402012-10-22 17:58:39 +02001931 if (!crt)
1932 goto out;
1933
Willy Tarreau47ca5452012-12-23 20:22:19 +01001934 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02001935 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
1936 goto out;
1937
1938 smp->data.str = *smp_trash;
1939 smp->type = SMP_T_BIN;
1940 ret = 1;
1941out:
Emeric Brunba841a12014-04-30 17:05:08 +02001942 /* SSL_get_peer_certificate, it increase X509 * ref count */
1943 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02001944 X509_free(crt);
1945 return ret;
1946}
Emeric Brune64aef12012-09-21 13:15:06 +02001947
Emeric Brunba841a12014-04-30 17:05:08 +02001948/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
1949 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
1950 * should be use.
1951 */
James Votha051b4a2013-05-14 20:37:59 +02001952static int
Emeric Brunba841a12014-04-30 17:05:08 +02001953smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001954 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02001955{
Emeric Brunba841a12014-04-30 17:05:08 +02001956 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02001957 X509 *crt = NULL;
1958 const EVP_MD *digest;
1959 int ret = 0;
1960 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001961 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02001962
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001963 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02001964 return 0;
1965
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001966 conn = objt_conn(l4->si[0].end);
1967 if (!conn || conn->xprt != &ssl_sock)
1968 return 0;
1969
1970 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02001971 smp->flags |= SMP_F_MAY_CHANGE;
1972 return 0;
1973 }
1974
Emeric Brunba841a12014-04-30 17:05:08 +02001975 if (cert_peer)
1976 crt = SSL_get_peer_certificate(conn->xprt_ctx);
1977 else
1978 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02001979 if (!crt)
1980 goto out;
1981
1982 smp_trash = get_trash_chunk();
1983 digest = EVP_sha1();
1984 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
1985
1986 smp->data.str = *smp_trash;
1987 smp->type = SMP_T_BIN;
1988 ret = 1;
1989out:
Emeric Brunba841a12014-04-30 17:05:08 +02001990 /* SSL_get_peer_certificate, it increase X509 * ref count */
1991 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02001992 X509_free(crt);
1993 return ret;
1994}
1995
Emeric Brunba841a12014-04-30 17:05:08 +02001996/* string, returns certificate's notafter date in ASN1_UTCTIME format.
1997 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
1998 * should be use.
1999 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002000static int
Emeric Brunba841a12014-04-30 17:05:08 +02002001smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002002 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002003{
Emeric Brunba841a12014-04-30 17:05:08 +02002004 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002005 X509 *crt = NULL;
2006 int ret = 0;
2007 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002008 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002009
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002010 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002011 return 0;
2012
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002013 conn = objt_conn(l4->si[0].end);
2014 if (!conn || conn->xprt != &ssl_sock)
2015 return 0;
2016
2017 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002018 smp->flags |= SMP_F_MAY_CHANGE;
2019 return 0;
2020 }
2021
Emeric Brunba841a12014-04-30 17:05:08 +02002022 if (cert_peer)
2023 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2024 else
2025 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002026 if (!crt)
2027 goto out;
2028
Willy Tarreau47ca5452012-12-23 20:22:19 +01002029 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002030 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2031 goto out;
2032
2033 smp->data.str = *smp_trash;
2034 smp->type = SMP_T_STR;
2035 ret = 1;
2036out:
Emeric Brunba841a12014-04-30 17:05:08 +02002037 /* SSL_get_peer_certificate, it increase X509 * ref count */
2038 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002039 X509_free(crt);
2040 return ret;
2041}
2042
Emeric Brunba841a12014-04-30 17:05:08 +02002043/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2044 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2045 * should be use.
2046 */
Emeric Brun87855892012-10-17 17:39:35 +02002047static int
Emeric Brunba841a12014-04-30 17:05:08 +02002048smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002049 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002050{
Emeric Brunba841a12014-04-30 17:05:08 +02002051 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002052 X509 *crt = NULL;
2053 X509_NAME *name;
2054 int ret = 0;
2055 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002056 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002057
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002058 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002059 return 0;
2060
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002061 conn = objt_conn(l4->si[0].end);
2062 if (!conn || conn->xprt != &ssl_sock)
2063 return 0;
2064
2065 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002066 smp->flags |= SMP_F_MAY_CHANGE;
2067 return 0;
2068 }
2069
Emeric Brunba841a12014-04-30 17:05:08 +02002070 if (cert_peer)
2071 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2072 else
2073 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002074 if (!crt)
2075 goto out;
2076
2077 name = X509_get_issuer_name(crt);
2078 if (!name)
2079 goto out;
2080
Willy Tarreau47ca5452012-12-23 20:22:19 +01002081 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002082 if (args && args[0].type == ARGT_STR) {
2083 int pos = 1;
2084
2085 if (args[1].type == ARGT_SINT)
2086 pos = args[1].data.sint;
2087 else if (args[1].type == ARGT_UINT)
2088 pos =(int)args[1].data.uint;
2089
2090 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2091 goto out;
2092 }
2093 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2094 goto out;
2095
2096 smp->type = SMP_T_STR;
2097 smp->data.str = *smp_trash;
2098 ret = 1;
2099out:
Emeric Brunba841a12014-04-30 17:05:08 +02002100 /* SSL_get_peer_certificate, it increase X509 * ref count */
2101 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002102 X509_free(crt);
2103 return ret;
2104}
2105
Emeric Brunba841a12014-04-30 17:05:08 +02002106/* string, returns notbefore date in ASN1_UTCTIME format.
2107 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2108 * should be use.
2109 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002110static int
Emeric Brunba841a12014-04-30 17:05:08 +02002111smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002112 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002113{
Emeric Brunba841a12014-04-30 17:05:08 +02002114 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002115 X509 *crt = NULL;
2116 int ret = 0;
2117 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002118 struct connection *conn;
2119
2120 if (!l4)
2121 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002122
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002123 conn = objt_conn(l4->si[0].end);
2124 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002125 return 0;
2126
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002127 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002128 smp->flags |= SMP_F_MAY_CHANGE;
2129 return 0;
2130 }
2131
Emeric Brunba841a12014-04-30 17:05:08 +02002132 if (cert_peer)
2133 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2134 else
2135 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002136 if (!crt)
2137 goto out;
2138
Willy Tarreau47ca5452012-12-23 20:22:19 +01002139 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002140 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2141 goto out;
2142
2143 smp->data.str = *smp_trash;
2144 smp->type = SMP_T_STR;
2145 ret = 1;
2146out:
Emeric Brunba841a12014-04-30 17:05:08 +02002147 /* SSL_get_peer_certificate, it increase X509 * ref count */
2148 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002149 X509_free(crt);
2150 return ret;
2151}
2152
Emeric Brunba841a12014-04-30 17:05:08 +02002153/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
2154 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2155 * should be use.
2156 */
Emeric Brun87855892012-10-17 17:39:35 +02002157static int
Emeric Brunba841a12014-04-30 17:05:08 +02002158smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002159 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002160{
Emeric Brunba841a12014-04-30 17:05:08 +02002161 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002162 X509 *crt = NULL;
2163 X509_NAME *name;
2164 int ret = 0;
2165 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002166 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002167
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002168 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002169 return 0;
2170
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002171 conn = objt_conn(l4->si[0].end);
2172 if (!conn || conn->xprt != &ssl_sock)
2173 return 0;
2174
2175 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002176 smp->flags |= SMP_F_MAY_CHANGE;
2177 return 0;
2178 }
2179
Emeric Brunba841a12014-04-30 17:05:08 +02002180 if (cert_peer)
2181 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2182 else
2183 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002184 if (!crt)
2185 goto out;
2186
2187 name = X509_get_subject_name(crt);
2188 if (!name)
2189 goto out;
2190
Willy Tarreau47ca5452012-12-23 20:22:19 +01002191 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002192 if (args && args[0].type == ARGT_STR) {
2193 int pos = 1;
2194
2195 if (args[1].type == ARGT_SINT)
2196 pos = args[1].data.sint;
2197 else if (args[1].type == ARGT_UINT)
2198 pos =(int)args[1].data.uint;
2199
2200 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2201 goto out;
2202 }
2203 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2204 goto out;
2205
2206 smp->type = SMP_T_STR;
2207 smp->data.str = *smp_trash;
2208 ret = 1;
2209out:
Emeric Brunba841a12014-04-30 17:05:08 +02002210 /* SSL_get_peer_certificate, it increase X509 * ref count */
2211 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002212 X509_free(crt);
2213 return ret;
2214}
Emeric Brun9143d372012-12-20 15:44:16 +01002215
2216/* integer, returns true if current session use a client certificate */
2217static int
2218smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002219 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01002220{
2221 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002222 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01002223
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002224 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01002225 return 0;
2226
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002227 conn = objt_conn(l4->si[0].end);
2228 if (!conn || conn->xprt != &ssl_sock)
2229 return 0;
2230
2231 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01002232 smp->flags |= SMP_F_MAY_CHANGE;
2233 return 0;
2234 }
2235
2236 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002237 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01002238 if (crt) {
2239 X509_free(crt);
2240 }
2241
2242 smp->type = SMP_T_BOOL;
2243 smp->data.uint = (crt != NULL);
2244 return 1;
2245}
2246
Emeric Brunba841a12014-04-30 17:05:08 +02002247/* integer, returns the certificate version
2248 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2249 * should be use.
2250 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02002251static int
Emeric Brunba841a12014-04-30 17:05:08 +02002252smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002253 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002254{
Emeric Brunba841a12014-04-30 17:05:08 +02002255 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002256 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002257 struct connection *conn;
2258
2259 if (!l4)
2260 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002261
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002262 conn = objt_conn(l4->si[0].end);
2263 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002264 return 0;
2265
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002266 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002267 smp->flags |= SMP_F_MAY_CHANGE;
2268 return 0;
2269 }
2270
Emeric Brunba841a12014-04-30 17:05:08 +02002271 if (cert_peer)
2272 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2273 else
2274 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002275 if (!crt)
2276 return 0;
2277
2278 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02002279 /* SSL_get_peer_certificate increase X509 * ref count */
2280 if (cert_peer)
2281 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002282 smp->type = SMP_T_UINT;
2283
2284 return 1;
2285}
2286
Emeric Brunba841a12014-04-30 17:05:08 +02002287/* string, returns the certificate's signature algorithm.
2288 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2289 * should be use.
2290 */
Emeric Brun7f56e742012-10-19 18:15:40 +02002291static int
Emeric Brunba841a12014-04-30 17:05:08 +02002292smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002293 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002294{
Emeric Brunba841a12014-04-30 17:05:08 +02002295 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02002296 X509 *crt;
2297 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002298 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002299
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002300 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002301 return 0;
2302
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002303 conn = objt_conn(l4->si[0].end);
2304 if (!conn || conn->xprt != &ssl_sock)
2305 return 0;
2306
2307 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002308 smp->flags |= SMP_F_MAY_CHANGE;
2309 return 0;
2310 }
2311
Emeric Brunba841a12014-04-30 17:05:08 +02002312 if (cert_peer)
2313 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2314 else
2315 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002316 if (!crt)
2317 return 0;
2318
2319 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2320
2321 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002322 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02002323 /* SSL_get_peer_certificate increase X509 * ref count */
2324 if (cert_peer)
2325 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002326 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002327 }
Emeric Brun7f56e742012-10-19 18:15:40 +02002328
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002329 smp->type = SMP_T_STR;
2330 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002331 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02002332 /* SSL_get_peer_certificate increase X509 * ref count */
2333 if (cert_peer)
2334 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002335
2336 return 1;
2337}
2338
Emeric Brunba841a12014-04-30 17:05:08 +02002339/* string, returns the certificate's key algorithm.
2340 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2341 * should be use.
2342 */
Emeric Brun521a0112012-10-22 12:22:55 +02002343static int
Emeric Brunba841a12014-04-30 17:05:08 +02002344smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002345 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002346{
Emeric Brunba841a12014-04-30 17:05:08 +02002347 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02002348 X509 *crt;
2349 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002350 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02002351
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002352 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02002353 return 0;
2354
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002355 conn = objt_conn(l4->si[0].end);
2356 if (!conn || conn->xprt != &ssl_sock)
2357 return 0;
2358
2359 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002360 smp->flags |= SMP_F_MAY_CHANGE;
2361 return 0;
2362 }
2363
Emeric Brunba841a12014-04-30 17:05:08 +02002364 if (cert_peer)
2365 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2366 else
2367 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002368 if (!crt)
2369 return 0;
2370
2371 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2372
2373 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002374 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02002375 /* SSL_get_peer_certificate increase X509 * ref count */
2376 if (cert_peer)
2377 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002378 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002379 }
Emeric Brun521a0112012-10-22 12:22:55 +02002380
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002381 smp->type = SMP_T_STR;
2382 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002383 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02002384 if (cert_peer)
2385 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002386
2387 return 1;
2388}
2389
Emeric Brun645ae792014-04-30 14:21:06 +02002390/* boolean, returns true if front conn. transport layer is SSL.
2391 * This function is also usable on backend conn if the fetch keyword 5th
2392 * char is 'b'.
2393 */
Willy Tarreau7875d092012-09-10 08:20:03 +02002394static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002395smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002396 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002397{
Emeric Brun645ae792014-04-30 14:21:06 +02002398 int back_conn = (kw[4] == 'b') ? 1 : 0;
2399 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002400
Willy Tarreau7875d092012-09-10 08:20:03 +02002401 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002402 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02002403 return 1;
2404}
2405
Emeric Brun2525b6b2012-10-18 15:59:43 +02002406/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02002407static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002408smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002409 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002410{
2411#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002412 struct connection *conn = objt_conn(l4->si[0].end);
2413
Willy Tarreau7875d092012-09-10 08:20:03 +02002414 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002415 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
2416 conn->xprt_ctx &&
2417 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02002418 return 1;
2419#else
2420 return 0;
2421#endif
2422}
2423
Emeric Brun645ae792014-04-30 14:21:06 +02002424/* string, returns the used cipher if front conn. transport layer is SSL.
2425 * This function is also usable on backend conn if the fetch keyword 5th
2426 * char is 'b'.
2427 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002428static int
2429smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002430 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002431{
Emeric Brun645ae792014-04-30 14:21:06 +02002432 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002433 struct connection *conn;
2434
Emeric Brun589fcad2012-10-16 14:13:26 +02002435 smp->flags = 0;
2436
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002437 if (!l4)
2438 return 0;
2439
Emeric Brun645ae792014-04-30 14:21:06 +02002440 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002441 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002442 return 0;
2443
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002444 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002445 if (!smp->data.str.str)
2446 return 0;
2447
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002448 smp->type = SMP_T_STR;
2449 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002450 smp->data.str.len = strlen(smp->data.str.str);
2451
2452 return 1;
2453}
2454
Emeric Brun645ae792014-04-30 14:21:06 +02002455/* integer, returns the algoritm's keysize if front conn. transport layer
2456 * is SSL.
2457 * This function is also usable on backend conn if the fetch keyword 5th
2458 * char is 'b'.
2459 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002460static int
2461smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002462 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002463{
Emeric Brun645ae792014-04-30 14:21:06 +02002464 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002465 struct connection *conn;
2466
Emeric Brun589fcad2012-10-16 14:13:26 +02002467 smp->flags = 0;
2468
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002469 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002470 return 0;
2471
Emeric Brun645ae792014-04-30 14:21:06 +02002472 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002473 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002474 return 0;
2475
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002476 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
2477 return 0;
2478
Emeric Brun589fcad2012-10-16 14:13:26 +02002479 smp->type = SMP_T_UINT;
2480
2481 return 1;
2482}
2483
Emeric Brun645ae792014-04-30 14:21:06 +02002484/* integer, returns the used keysize if front conn. transport layer is SSL.
2485 * This function is also usable on backend conn if the fetch keyword 5th
2486 * char is 'b'.
2487 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002488static int
2489smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002490 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002491{
Emeric Brun645ae792014-04-30 14:21:06 +02002492 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002493 struct connection *conn;
2494
Emeric Brun589fcad2012-10-16 14:13:26 +02002495 smp->flags = 0;
2496
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002497 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002498 return 0;
2499
Emeric Brun645ae792014-04-30 14:21:06 +02002500 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002501 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2502 return 0;
2503
2504 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02002505 if (!smp->data.uint)
2506 return 0;
2507
2508 smp->type = SMP_T_UINT;
2509
2510 return 1;
2511}
2512
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002513#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02002514static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002515smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002516 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002517{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002518 struct connection *conn;
2519
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002520 smp->flags = SMP_F_CONST;
2521 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002522
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002523 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002524 return 0;
2525
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002526 conn = objt_conn(l4->si[0].end);
2527 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2528 return 0;
2529
Willy Tarreaua33c6542012-10-15 13:19:06 +02002530 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002531 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02002532 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2533
2534 if (!smp->data.str.str)
2535 return 0;
2536
2537 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002538}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002539#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02002540
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002541#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002542static int
2543smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002544 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02002545{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002546 struct connection *conn;
2547
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002548 smp->flags = SMP_F_CONST;
2549 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02002550
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002551 if (!l4)
2552 return 0;
2553
2554 conn = objt_conn(l4->si[0].end);
2555 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02002556 return 0;
2557
2558 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002559 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02002560 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2561
2562 if (!smp->data.str.str)
2563 return 0;
2564
2565 return 1;
2566}
2567#endif
2568
Emeric Brun645ae792014-04-30 14:21:06 +02002569/* string, returns the used protocol if front conn. transport layer is SSL.
2570 * This function is also usable on backend conn if the fetch keyword 5th
2571 * char is 'b'.
2572 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02002573static int
Emeric Brun589fcad2012-10-16 14:13:26 +02002574smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002575 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002576{
Emeric Brun645ae792014-04-30 14:21:06 +02002577 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002578 struct connection *conn;
2579
Emeric Brun589fcad2012-10-16 14:13:26 +02002580 smp->flags = 0;
2581
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002582 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002583 return 0;
2584
Emeric Brun645ae792014-04-30 14:21:06 +02002585 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002586 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2587 return 0;
2588
2589 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002590 if (!smp->data.str.str)
2591 return 0;
2592
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002593 smp->type = SMP_T_STR;
2594 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002595 smp->data.str.len = strlen(smp->data.str.str);
2596
2597 return 1;
2598}
2599
Emeric Brun645ae792014-04-30 14:21:06 +02002600/* binary, returns the SSL session id if front conn. transport layer is SSL.
2601 * This function is also usable on backend conn if the fetch keyword 5th
2602 * char is 'b'.
2603 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002604static int
Emeric Brunfe68f682012-10-16 14:59:28 +02002605smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002606 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02002607{
2608#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02002609 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02002610 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002611 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02002612
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002613 smp->flags = SMP_F_CONST;
2614 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02002615
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002616 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02002617 return 0;
2618
Emeric Brun645ae792014-04-30 14:21:06 +02002619 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002620 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2621 return 0;
2622
2623 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02002624 if (!sess)
2625 return 0;
2626
2627 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
2628 if (!smp->data.str.str || !&smp->data.str.len)
2629 return 0;
2630
2631 return 1;
2632#else
2633 return 0;
2634#endif
2635}
2636
2637static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002638smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002639 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002640{
2641#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002642 struct connection *conn;
2643
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002644 smp->flags = SMP_F_CONST;
2645 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02002646
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002647 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02002648 return 0;
2649
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002650 conn = objt_conn(l4->si[0].end);
2651 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2652 return 0;
2653
2654 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02002655 if (!smp->data.str.str)
2656 return 0;
2657
Willy Tarreau7875d092012-09-10 08:20:03 +02002658 smp->data.str.len = strlen(smp->data.str.str);
2659 return 1;
2660#else
2661 return 0;
2662#endif
2663}
2664
David Sc1ad52e2014-04-08 18:48:47 -04002665static int
2666smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2667 const struct arg *args, struct sample *smp, const char *kw)
2668{
2669#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02002670 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04002671 struct connection *conn;
2672 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04002673 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04002674
2675 smp->flags = 0;
2676
2677 if (!l4)
2678 return 0;
2679
Emeric Brun645ae792014-04-30 14:21:06 +02002680 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04002681 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2682 return 0;
2683
2684 if (!(conn->flags & CO_FL_CONNECTED)) {
2685 smp->flags |= SMP_F_MAY_CHANGE;
2686 return 0;
2687 }
2688
2689 finished_trash = get_trash_chunk();
2690 if (!SSL_session_reused(conn->xprt_ctx))
2691 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2692 else
2693 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2694
2695 if (!finished_len)
2696 return 0;
2697
Emeric Brunb73a9b02014-04-30 18:49:19 +02002698 finished_trash->len = finished_len;
2699 smp->data.str = *finished_trash;
2700 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04002701
2702 return 1;
2703#else
2704 return 0;
2705#endif
2706}
2707
Emeric Brun2525b6b2012-10-18 15:59:43 +02002708/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002709static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002710smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002711 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002712{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002713 struct connection *conn;
2714
2715 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002716 return 0;
2717
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002718 conn = objt_conn(l4->si[0].end);
2719 if (!conn || conn->xprt != &ssl_sock)
2720 return 0;
2721
2722 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002723 smp->flags = SMP_F_MAY_CHANGE;
2724 return 0;
2725 }
2726
2727 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002728 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002729 smp->flags = 0;
2730
2731 return 1;
2732}
2733
Emeric Brun2525b6b2012-10-18 15:59:43 +02002734/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002735static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002736smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002737 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002738{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002739 struct connection *conn;
2740
2741 if (!l4)
2742 return 0;
2743
2744 conn = objt_conn(l4->si[0].end);
2745 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02002746 return 0;
2747
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002748 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002749 smp->flags = SMP_F_MAY_CHANGE;
2750 return 0;
2751 }
2752
2753 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002754 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002755 smp->flags = 0;
2756
2757 return 1;
2758}
2759
Emeric Brun2525b6b2012-10-18 15:59:43 +02002760/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02002761static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002762smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002763 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002764{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002765 struct connection *conn;
2766
2767 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002768 return 0;
2769
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002770 conn = objt_conn(l4->si[0].end);
2771 if (!conn || conn->xprt != &ssl_sock)
2772 return 0;
2773
2774 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002775 smp->flags = SMP_F_MAY_CHANGE;
2776 return 0;
2777 }
2778
2779 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002780 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002781 smp->flags = 0;
2782
2783 return 1;
2784}
2785
Emeric Brun2525b6b2012-10-18 15:59:43 +02002786/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002787static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002788smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002789 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002790{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002791 struct connection *conn;
2792
2793 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002794 return 0;
2795
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002796 conn = objt_conn(l4->si[0].end);
2797 if (!conn || conn->xprt != &ssl_sock)
2798 return 0;
2799
2800 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002801 smp->flags = SMP_F_MAY_CHANGE;
2802 return 0;
2803 }
2804
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002805 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002806 return 0;
2807
2808 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002809 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002810 smp->flags = 0;
2811
2812 return 1;
2813}
2814
Emeric Brunfb510ea2012-10-05 12:00:26 +02002815/* parse the "ca-file" bind keyword */
2816static 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 +02002817{
2818 if (!*args[cur_arg + 1]) {
2819 if (err)
2820 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
2821 return ERR_ALERT | ERR_FATAL;
2822 }
2823
Emeric Brunef42d922012-10-11 16:11:36 +02002824 if ((*args[cur_arg + 1] != '/') && global.ca_base)
2825 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
2826 else
2827 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002828
Emeric Brund94b3fe2012-09-20 18:23:56 +02002829 return 0;
2830}
2831
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002832/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002833static 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 +02002834{
2835 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002836 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002837 return ERR_ALERT | ERR_FATAL;
2838 }
2839
Emeric Brun76d88952012-10-05 15:47:31 +02002840 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002841 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002842 return 0;
2843}
2844
2845/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002846static 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 +02002847{
Willy Tarreau38011032013-08-13 16:59:39 +02002848 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02002849
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002850 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002851 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002852 return ERR_ALERT | ERR_FATAL;
2853 }
2854
Emeric Brunc8e8d122012-10-02 18:42:10 +02002855 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02002856 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02002857 memprintf(err, "'%s' : path too long", args[cur_arg]);
2858 return ERR_ALERT | ERR_FATAL;
2859 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02002860 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002861 if (ssl_sock_load_cert(path, conf, px, err) > 0)
2862 return ERR_ALERT | ERR_FATAL;
2863
2864 return 0;
2865 }
2866
Willy Tarreau4348fad2012-09-20 16:48:07 +02002867 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002868 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02002869
2870 return 0;
2871}
2872
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002873/* parse the "crt-list" bind keyword */
2874static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2875{
2876 if (!*args[cur_arg + 1]) {
2877 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
2878 return ERR_ALERT | ERR_FATAL;
2879 }
2880
Willy Tarreauad1731d2013-04-02 17:35:58 +02002881 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
2882 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002883 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002884 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002885
2886 return 0;
2887}
2888
Emeric Brunfb510ea2012-10-05 12:00:26 +02002889/* parse the "crl-file" bind keyword */
2890static 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 +02002891{
Emeric Brun051cdab2012-10-02 19:25:50 +02002892#ifndef X509_V_FLAG_CRL_CHECK
2893 if (err)
2894 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
2895 return ERR_ALERT | ERR_FATAL;
2896#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02002897 if (!*args[cur_arg + 1]) {
2898 if (err)
2899 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
2900 return ERR_ALERT | ERR_FATAL;
2901 }
Emeric Brun2b58d042012-09-20 17:10:03 +02002902
Emeric Brunef42d922012-10-11 16:11:36 +02002903 if ((*args[cur_arg + 1] != '/') && global.ca_base)
2904 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
2905 else
2906 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002907
Emeric Brun2b58d042012-09-20 17:10:03 +02002908 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02002909#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002910}
2911
2912/* parse the "ecdhe" bind keyword keywords */
2913static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2914{
2915#if OPENSSL_VERSION_NUMBER < 0x0090800fL
2916 if (err)
2917 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
2918 return ERR_ALERT | ERR_FATAL;
2919#elif defined(OPENSSL_NO_ECDH)
2920 if (err)
2921 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
2922 return ERR_ALERT | ERR_FATAL;
2923#else
2924 if (!*args[cur_arg + 1]) {
2925 if (err)
2926 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
2927 return ERR_ALERT | ERR_FATAL;
2928 }
2929
2930 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002931
2932 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02002933#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002934}
2935
Emeric Brun81c00f02012-09-21 14:31:21 +02002936/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
2937static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2938{
2939 int code;
2940 char *p = args[cur_arg + 1];
2941 unsigned long long *ignerr = &conf->crt_ignerr;
2942
2943 if (!*p) {
2944 if (err)
2945 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
2946 return ERR_ALERT | ERR_FATAL;
2947 }
2948
2949 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
2950 ignerr = &conf->ca_ignerr;
2951
2952 if (strcmp(p, "all") == 0) {
2953 *ignerr = ~0ULL;
2954 return 0;
2955 }
2956
2957 while (p) {
2958 code = atoi(p);
2959 if ((code <= 0) || (code > 63)) {
2960 if (err)
2961 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
2962 args[cur_arg], code, args[cur_arg + 1]);
2963 return ERR_ALERT | ERR_FATAL;
2964 }
2965 *ignerr |= 1ULL << code;
2966 p = strchr(p, ',');
2967 if (p)
2968 p++;
2969 }
2970
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002971 return 0;
2972}
2973
2974/* parse the "force-sslv3" bind keyword */
2975static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2976{
2977 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
2978 return 0;
2979}
2980
2981/* parse the "force-tlsv10" bind keyword */
2982static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2983{
2984 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02002985 return 0;
2986}
2987
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002988/* parse the "force-tlsv11" bind keyword */
2989static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2990{
2991#if SSL_OP_NO_TLSv1_1
2992 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
2993 return 0;
2994#else
2995 if (err)
2996 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
2997 return ERR_ALERT | ERR_FATAL;
2998#endif
2999}
3000
3001/* parse the "force-tlsv12" bind keyword */
3002static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3003{
3004#if SSL_OP_NO_TLSv1_2
3005 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3006 return 0;
3007#else
3008 if (err)
3009 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3010 return ERR_ALERT | ERR_FATAL;
3011#endif
3012}
3013
3014
Emeric Brun2d0c4822012-10-02 13:45:20 +02003015/* parse the "no-tls-tickets" bind keyword */
3016static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3017{
Emeric Brun89675492012-10-05 13:48:26 +02003018 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003019 return 0;
3020}
3021
Emeric Brun2d0c4822012-10-02 13:45:20 +02003022
Emeric Brun9b3009b2012-10-05 11:55:06 +02003023/* parse the "no-sslv3" bind keyword */
3024static 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 +02003025{
Emeric Brun89675492012-10-05 13:48:26 +02003026 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003027 return 0;
3028}
3029
Emeric Brun9b3009b2012-10-05 11:55:06 +02003030/* parse the "no-tlsv10" bind keyword */
3031static 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 +02003032{
Emeric Brun89675492012-10-05 13:48:26 +02003033 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003034 return 0;
3035}
3036
Emeric Brun9b3009b2012-10-05 11:55:06 +02003037/* parse the "no-tlsv11" bind keyword */
3038static 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 +02003039{
Emeric Brun89675492012-10-05 13:48:26 +02003040 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003041 return 0;
3042}
3043
Emeric Brun9b3009b2012-10-05 11:55:06 +02003044/* parse the "no-tlsv12" bind keyword */
3045static 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 +02003046{
Emeric Brun89675492012-10-05 13:48:26 +02003047 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003048 return 0;
3049}
3050
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003051/* parse the "npn" bind keyword */
3052static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3053{
3054#ifdef OPENSSL_NPN_NEGOTIATED
3055 char *p1, *p2;
3056
3057 if (!*args[cur_arg + 1]) {
3058 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3059 return ERR_ALERT | ERR_FATAL;
3060 }
3061
3062 free(conf->npn_str);
3063
3064 /* the NPN string is built as a suite of (<len> <name>)* */
3065 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3066 conf->npn_str = calloc(1, conf->npn_len);
3067 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3068
3069 /* replace commas with the name length */
3070 p1 = conf->npn_str;
3071 p2 = p1 + 1;
3072 while (1) {
3073 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3074 if (!p2)
3075 p2 = p1 + 1 + strlen(p1 + 1);
3076
3077 if (p2 - (p1 + 1) > 255) {
3078 *p2 = '\0';
3079 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3080 return ERR_ALERT | ERR_FATAL;
3081 }
3082
3083 *p1 = p2 - (p1 + 1);
3084 p1 = p2;
3085
3086 if (!*p2)
3087 break;
3088
3089 *(p2++) = '\0';
3090 }
3091 return 0;
3092#else
3093 if (err)
3094 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3095 return ERR_ALERT | ERR_FATAL;
3096#endif
3097}
3098
Willy Tarreauab861d32013-04-02 02:30:41 +02003099/* parse the "alpn" bind keyword */
3100static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3101{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003102#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003103 char *p1, *p2;
3104
3105 if (!*args[cur_arg + 1]) {
3106 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3107 return ERR_ALERT | ERR_FATAL;
3108 }
3109
3110 free(conf->alpn_str);
3111
3112 /* the ALPN string is built as a suite of (<len> <name>)* */
3113 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3114 conf->alpn_str = calloc(1, conf->alpn_len);
3115 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3116
3117 /* replace commas with the name length */
3118 p1 = conf->alpn_str;
3119 p2 = p1 + 1;
3120 while (1) {
3121 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3122 if (!p2)
3123 p2 = p1 + 1 + strlen(p1 + 1);
3124
3125 if (p2 - (p1 + 1) > 255) {
3126 *p2 = '\0';
3127 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3128 return ERR_ALERT | ERR_FATAL;
3129 }
3130
3131 *p1 = p2 - (p1 + 1);
3132 p1 = p2;
3133
3134 if (!*p2)
3135 break;
3136
3137 *(p2++) = '\0';
3138 }
3139 return 0;
3140#else
3141 if (err)
3142 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3143 return ERR_ALERT | ERR_FATAL;
3144#endif
3145}
3146
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003147/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003148static 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 +02003149{
Willy Tarreau81796be2012-09-22 19:11:47 +02003150 struct listener *l;
3151
Willy Tarreau4348fad2012-09-20 16:48:07 +02003152 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003153
3154 if (global.listen_default_ciphers && !conf->ciphers)
3155 conf->ciphers = strdup(global.listen_default_ciphers);
3156
Willy Tarreau81796be2012-09-22 19:11:47 +02003157 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003158 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003159
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003160 return 0;
3161}
3162
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003163/* parse the "strict-sni" bind keyword */
3164static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3165{
3166 conf->strict_sni = 1;
3167 return 0;
3168}
3169
Emeric Brund94b3fe2012-09-20 18:23:56 +02003170/* parse the "verify" bind keyword */
3171static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3172{
3173 if (!*args[cur_arg + 1]) {
3174 if (err)
3175 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3176 return ERR_ALERT | ERR_FATAL;
3177 }
3178
3179 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003180 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003181 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003182 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003183 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003184 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003185 else {
3186 if (err)
3187 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3188 args[cur_arg], args[cur_arg + 1]);
3189 return ERR_ALERT | ERR_FATAL;
3190 }
3191
3192 return 0;
3193}
3194
Willy Tarreau92faadf2012-10-10 23:04:25 +02003195/************** "server" keywords ****************/
3196
Emeric Brunef42d922012-10-11 16:11:36 +02003197/* parse the "ca-file" server keyword */
3198static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3199{
3200 if (!*args[*cur_arg + 1]) {
3201 if (err)
3202 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3203 return ERR_ALERT | ERR_FATAL;
3204 }
3205
3206 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3207 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3208 else
3209 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3210
3211 return 0;
3212}
3213
Willy Tarreau92faadf2012-10-10 23:04:25 +02003214/* parse the "check-ssl" server keyword */
3215static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3216{
3217 newsrv->check.use_ssl = 1;
3218 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3219 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3220 return 0;
3221}
3222
3223/* parse the "ciphers" server keyword */
3224static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3225{
3226 if (!*args[*cur_arg + 1]) {
3227 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3228 return ERR_ALERT | ERR_FATAL;
3229 }
3230
3231 free(newsrv->ssl_ctx.ciphers);
3232 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3233 return 0;
3234}
3235
Emeric Brunef42d922012-10-11 16:11:36 +02003236/* parse the "crl-file" server keyword */
3237static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3238{
3239#ifndef X509_V_FLAG_CRL_CHECK
3240 if (err)
3241 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3242 return ERR_ALERT | ERR_FATAL;
3243#else
3244 if (!*args[*cur_arg + 1]) {
3245 if (err)
3246 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
3247 return ERR_ALERT | ERR_FATAL;
3248 }
3249
3250 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3251 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3252 else
3253 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
3254
3255 return 0;
3256#endif
3257}
3258
Emeric Bruna7aa3092012-10-26 12:58:00 +02003259/* parse the "crt" server keyword */
3260static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3261{
3262 if (!*args[*cur_arg + 1]) {
3263 if (err)
3264 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
3265 return ERR_ALERT | ERR_FATAL;
3266 }
3267
3268 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
3269 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3270 else
3271 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
3272
3273 return 0;
3274}
Emeric Brunef42d922012-10-11 16:11:36 +02003275
Willy Tarreau92faadf2012-10-10 23:04:25 +02003276/* parse the "force-sslv3" server keyword */
3277static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3278{
3279 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
3280 return 0;
3281}
3282
3283/* parse the "force-tlsv10" server keyword */
3284static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3285{
3286 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
3287 return 0;
3288}
3289
3290/* parse the "force-tlsv11" server keyword */
3291static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3292{
3293#if SSL_OP_NO_TLSv1_1
3294 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
3295 return 0;
3296#else
3297 if (err)
3298 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
3299 return ERR_ALERT | ERR_FATAL;
3300#endif
3301}
3302
3303/* parse the "force-tlsv12" server keyword */
3304static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3305{
3306#if SSL_OP_NO_TLSv1_2
3307 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
3308 return 0;
3309#else
3310 if (err)
3311 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
3312 return ERR_ALERT | ERR_FATAL;
3313#endif
3314}
3315
3316/* parse the "no-sslv3" server keyword */
3317static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3318{
3319 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
3320 return 0;
3321}
3322
3323/* parse the "no-tlsv10" server keyword */
3324static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3325{
3326 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
3327 return 0;
3328}
3329
3330/* parse the "no-tlsv11" server keyword */
3331static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3332{
3333 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
3334 return 0;
3335}
3336
3337/* parse the "no-tlsv12" server keyword */
3338static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3339{
3340 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
3341 return 0;
3342}
3343
Emeric Brunf9c5c472012-10-11 15:28:34 +02003344/* parse the "no-tls-tickets" server keyword */
3345static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3346{
3347 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
3348 return 0;
3349}
3350
Willy Tarreau92faadf2012-10-10 23:04:25 +02003351/* parse the "ssl" server keyword */
3352static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3353{
3354 newsrv->use_ssl = 1;
3355 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3356 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3357 return 0;
3358}
3359
Emeric Brunef42d922012-10-11 16:11:36 +02003360/* parse the "verify" server keyword */
3361static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3362{
3363 if (!*args[*cur_arg + 1]) {
3364 if (err)
3365 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
3366 return ERR_ALERT | ERR_FATAL;
3367 }
3368
3369 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003370 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02003371 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003372 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02003373 else {
3374 if (err)
3375 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
3376 args[*cur_arg], args[*cur_arg + 1]);
3377 return ERR_ALERT | ERR_FATAL;
3378 }
3379
Evan Broderbe554312013-06-27 00:05:25 -07003380 return 0;
3381}
3382
3383/* parse the "verifyhost" server keyword */
3384static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3385{
3386 if (!*args[*cur_arg + 1]) {
3387 if (err)
3388 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
3389 return ERR_ALERT | ERR_FATAL;
3390 }
3391
3392 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
3393
Emeric Brunef42d922012-10-11 16:11:36 +02003394 return 0;
3395}
3396
Willy Tarreau7875d092012-09-10 08:20:03 +02003397/* Note: must not be declared <const> as its list will be overwritten.
3398 * Please take care of keeping this list alphabetically sorted.
3399 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003400static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02003401 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
3402 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
3403 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
3404 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02003405 { "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 +02003406 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
3407 { "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 +01003408 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3409 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3410 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003411 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3412 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3413 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3414 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3415 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3416 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3417 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3418 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003419 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3420 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003421 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3422 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3423 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3424 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3425 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3426 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3427 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3428 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02003429 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003430 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003431 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3432 { "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 +01003433 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003434 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3435 { "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 +02003436#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003437 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003438#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003439#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003440 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02003441#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003442 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02003443 { "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 +01003444 { "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 +01003445 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3446 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02003447 { NULL, NULL, 0, 0, 0 },
3448}};
3449
3450/* Note: must not be declared <const> as its list will be overwritten.
3451 * Please take care of keeping this list alphabetically sorted.
3452 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003453static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003454 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
3455 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01003456 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02003457}};
3458
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003459/* Note: must not be declared <const> as its list will be overwritten.
3460 * Please take care of keeping this list alphabetically sorted, doing so helps
3461 * all code contributors.
3462 * Optional keywords are also declared with a NULL ->parse() function so that
3463 * the config parser can report an appropriate error when a known keyword was
3464 * not enabled.
3465 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02003466static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02003467 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003468 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003469 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
3470 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003471 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003472 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
3473 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003474 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003475 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003476 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
3477 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
3478 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
3479 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02003480 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
3481 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
3482 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
3483 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003484 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003485 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003486 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003487 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003488 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003489 { NULL, NULL, 0 },
3490}};
Emeric Brun46591952012-05-18 15:47:34 +02003491
Willy Tarreau92faadf2012-10-10 23:04:25 +02003492/* Note: must not be declared <const> as its list will be overwritten.
3493 * Please take care of keeping this list alphabetically sorted, doing so helps
3494 * all code contributors.
3495 * Optional keywords are also declared with a NULL ->parse() function so that
3496 * the config parser can report an appropriate error when a known keyword was
3497 * not enabled.
3498 */
3499static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02003500 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003501 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
3502 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02003503 { "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 +02003504 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003505 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
3506 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
3507 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
3508 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
3509 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
3510 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
3511 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
3512 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02003513 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003514 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02003515 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07003516 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02003517 { NULL, NULL, 0, 0 },
3518}};
3519
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003520/* transport-layer operations for SSL sockets */
3521struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02003522 .snd_buf = ssl_sock_from_buf,
3523 .rcv_buf = ssl_sock_to_buf,
3524 .rcv_pipe = NULL,
3525 .snd_pipe = NULL,
3526 .shutr = NULL,
3527 .shutw = ssl_sock_shutw,
3528 .close = ssl_sock_close,
3529 .init = ssl_sock_init,
3530};
3531
3532__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02003533static void __ssl_sock_init(void)
3534{
Emeric Brun46591952012-05-18 15:47:34 +02003535 STACK_OF(SSL_COMP)* cm;
3536
Willy Tarreau610f04b2014-02-13 11:36:41 +01003537#ifdef LISTEN_DEFAULT_CIPHERS
3538 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
3539#endif
3540#ifdef CONNECT_DEFAULT_CIPHERS
3541 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
3542#endif
3543 if (global.listen_default_ciphers)
3544 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
3545 if (global.connect_default_ciphers)
3546 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
3547
Emeric Brun46591952012-05-18 15:47:34 +02003548 SSL_library_init();
3549 cm = SSL_COMP_get_compression_methods();
3550 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02003551 sample_register_fetches(&sample_fetch_keywords);
3552 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003553 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02003554 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02003555}
3556
3557/*
3558 * Local variables:
3559 * c-indent-level: 8
3560 * c-basic-offset: 8
3561 * End:
3562 */