File: ssl_sock.h

package info (click to toggle)
haproxy 3.3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 24,600 kB
  • sloc: ansic: 275,217; sh: 3,607; xml: 1,756; python: 1,345; makefile: 1,162; perl: 168; cpp: 21
file content (280 lines) | stat: -rw-r--r-- 10,569 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/*
 * include/haproxy/ssl_sock.h
 * This file contains definition for ssl stream socket operations
 *
 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, version 2.1
 * exclusively.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _HAPROXY_SSL_SOCK_H
#define _HAPROXY_SSL_SOCK_H
#ifdef USE_OPENSSL


#include <haproxy/connection.h>
#include <haproxy/openssl-compat.h>
#include <haproxy/pool-t.h>
#include <haproxy/proxy-t.h>
#include <haproxy/quic_conn-t.h>
#include <haproxy/ssl_sock-t.h>
#include <haproxy/stats.h>
#include <haproxy/thread.h>

extern struct list tlskeys_reference;
extern struct eb_root ckchs_tree;
extern struct eb_root crtlists_tree;
extern struct eb_root cafile_tree;
extern int sctl_ex_index;
extern struct global_ssl global_ssl;
extern struct ssl_crtlist_kw ssl_crtlist_kws[];
extern struct methodVersions methodVersions[];
__decl_thread(extern HA_SPINLOCK_T ckch_lock);
extern struct pool_head *pool_head_ssl_capture;
extern int ssl_app_data_index;
#ifdef USE_QUIC
extern int ssl_qc_app_data_index;
#endif /* USE_QUIC */
extern unsigned int openssl_engines_initialized;
extern int nb_engines;
extern struct xprt_ops ssl_sock;
extern int ssl_capture_ptr_index;
extern int ssl_keylog_index;
extern int ssl_client_sni_index;
extern struct pool_head *pool_head_ssl_keylog;
extern struct pool_head *pool_head_ssl_keylog_str;
extern struct list openssl_providers;
extern struct stats_module ssl_stats_module;

uint64_t ssl_sock_sni_hash(const struct ist sni);
int ssl_sock_prep_ctx_and_inst(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
			       SSL_CTX *ctx, struct ckch_inst *ckch_inst, char **err);
int ssl_sock_prep_srv_ctx_and_inst(const struct server *srv, SSL_CTX *ctx,
				   struct ckch_inst *ckch_inst);
int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf);
int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf);
void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf);
int ssl_sock_prepare_srv_ctx(struct server *srv);
void ssl_sock_free_srv_ctx(struct server *srv);
void ssl_sock_free_all_ctx(struct bind_conf *bind_conf);
int ssl_sock_get_alpn(const struct connection *conn, void *xprt_ctx,
                      const char **str, int *len);
int ssl_bio_and_sess_init(struct connection *conn, SSL_CTX *ssl_ctx,
                          SSL **ssl, BIO **bio, BIO_METHOD *bio_meth, void *ctx);
int ssl_sock_srv_try_reuse_sess(struct ssl_sock_ctx *ctx, struct server *srv);
const char *ssl_sock_get_sni(struct connection *conn);
const char *ssl_sock_get_cert_sig(struct connection *conn);
const char *ssl_sock_get_cipher_name(struct connection *conn);
const char *ssl_sock_get_proto_version(struct connection *conn);
int ssl_sock_parse_alpn(char *arg, char **alpn_str, int *alpn_len, char **err);
void ssl_sock_set_alpn(struct connection *conn, const unsigned char *, int);
void ssl_sock_set_servername(struct connection *conn, const char *hostname);

int ssl_sock_get_cert_used_sess(struct connection *conn);
int ssl_sock_get_cert_used_conn(struct connection *conn);
int ssl_sock_get_remote_common_name(struct connection *conn,
				    struct buffer *out);
int ssl_sock_get_pkey_algo(struct connection *conn, struct buffer *out);
unsigned int ssl_sock_get_verify_result(struct connection *conn);
void ssl_sock_update_counters(SSL *ssl,
                              struct ssl_counters *counters,
                              struct ssl_counters *counters_px, int backend);
void ssl_sock_handle_hs_error(struct connection *conn);
#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
int ssl_sock_update_tlskey_ref(struct tls_keys_ref *ref,
				struct buffer *tlskey);
int ssl_sock_update_tlskey(char *filename, struct buffer *tlskey, char **err);
struct tls_keys_ref *tlskeys_ref_lookup(const char *filename);
struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id);
#endif
#ifndef OPENSSL_NO_DH
HASSL_DH *ssl_sock_get_dh_from_bio(BIO *bio);
int ssl_sock_load_global_dh_param_from_file(const char *filename);
void ssl_free_dh(void);
#endif
void ssl_free_engines(void);
#ifdef HAVE_SSL_PROVIDERS
void ssl_unload_providers(void);
#endif

#ifdef HAVE_SSL_CLIENT_HELLO_CB
int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv);
# if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx);
# else /* ! OPENSSL_IS_BORINGSSL */
int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg);
# endif
#else /* ! HAVE_SSL_CLIENT_HELLO_CB */
int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv);
#endif
#ifdef USE_OPENSSL_WOLFSSL
int ssl_sock_switchctx_wolfSSL_cbk(WOLFSSL* ssl, void* arg);
#endif

int increment_sslconn();
void ssl_sock_load_cert_sni(struct ckch_inst *ckch_inst, struct bind_conf *bind_conf);
struct sni_ctx *ssl_sock_chose_sni_ctx(struct bind_conf *s, struct connection *conn,
                                       const char *servername, int have_rsa_sig, int have_ecdsa_sig);
#ifdef SSL_MODE_ASYNC
void ssl_async_fd_handler(int fd);
void ssl_async_fd_free(int fd);
#endif
struct issuer_chain* ssl_get0_issuer_chain(X509 *cert);
int ssl_load_global_issuer_from_BIO(BIO *in, char *fp, char **err);
int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, int is_default, char **err);
int ssl_sock_load_srv_cert(char *path, struct server *server, int create_if_none, char **err);
int ssl_sock_passwd_cb(char *buf, int size, int rwflag, void *userdata);
void ssl_free_global_issuers(void);
int ssl_initialize_random(void);
int ssl_sock_load_cert_list_file(char *file, int dir, struct bind_conf *bind_conf, struct proxy *curproxy, char **err);
int ssl_init_single_engine(const char *engine_id, const char *def_algorithms);
int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store);
#ifdef HAVE_SSL_PROVIDERS
int ssl_init_provider(const char *provider_name);
#endif
#if (defined(HAVE_SSL_OCSP) && !defined OPENSSL_IS_BORINGSSL)
int ssl_get_ocspresponse_detail(unsigned char *ocsp_certid, struct buffer *out);
int ssl_ocsp_response_print(struct buffer *ocsp_response, struct buffer *out);
#endif

#if (HA_OPENSSL_VERSION_NUMBER < 0x3000000fL)
DH *ssl_get_tmp_dh_cbk(SSL *ssl, int export, int keylen);
#else
void ssl_sock_set_tmp_dh_from_pkey(SSL_CTX *ctx, EVP_PKEY *pkey);
#endif

/* ssl shctx macro */

#define sh_ssl_sess_tree_delete(s)     ebmb_delete(&(s)->key);

#define sh_ssl_sess_tree_insert(s)     (struct sh_ssl_sess_hdr *)ebmb_insert(sh_ssl_sess_tree, \
                                                                    &(s)->key, SSL_MAX_SSL_SESSION_ID_LENGTH);

#define sh_ssl_sess_tree_lookup(k)     (struct sh_ssl_sess_hdr *)ebmb_lookup(sh_ssl_sess_tree, \
                                                                    (k), SSL_MAX_SSL_SESSION_ID_LENGTH);

/* Registers the function <func> in order to be called on SSL/TLS protocol
 * message processing.
 */
int ssl_sock_register_msg_callback(ssl_sock_msg_callback_func func);

SSL *ssl_sock_get_ssl_object(struct connection *conn);

static inline int cert_ignerr_bitfield_get(const unsigned long long *bitfield, int bit_index)
{
	int byte_index = bit_index >> 6;
	int val = 0;

	if (byte_index < IGNERR_BF_SIZE)
		val = bitfield[byte_index] & (1ULL << (bit_index & 0x3F));

	return val != 0;
}

static inline void cert_ignerr_bitfield_set(unsigned long long *bitfield, int bit_index)
{
	int byte_index = bit_index >> 6;

	if (byte_index < IGNERR_BF_SIZE)
		bitfield[byte_index] |= (1ULL << (bit_index & 0x3F));
}

static inline void cert_ignerr_bitfield_set_all(unsigned long long *bitfield)
{
	memset(bitfield, -1, IGNERR_BF_SIZE*sizeof(*bitfield));
}

/* Listener only function.
 * Return the listener attached to <s> SSL object.
 */
static inline struct listener *ssl_sock_get_listener(const SSL *s)
{
	struct connection *conn = SSL_get_ex_data(s, ssl_app_data_index);
#ifdef USE_QUIC
	struct quic_conn *qc = SSL_get_ex_data(s, ssl_qc_app_data_index);
#endif

	if (conn)
		return __objt_listener(conn->target);
#ifdef USE_QUIC
	else if (qc)
		return qc->li;
#endif
	return NULL;
}

/* Return the connection from <s> SSL object.
 * Note that for QUIC, this function must be called with very much attention.
 * Indeed, for QUIC frontends, qc->conn is not always initialized.
 * For QUIC backends, this is always the case if the SSL object is released
 * at the same time as the connection.
 */
static inline struct connection *ssl_sock_get_conn(const SSL *s, struct ssl_sock_ctx **ctx)
{
	struct connection *ret = NULL;
	struct connection *conn = SSL_get_ex_data(s, ssl_app_data_index);
#ifdef USE_QUIC
	struct quic_conn *qc = SSL_get_ex_data(s, ssl_qc_app_data_index);
#endif

	if (conn) {
		ret = conn;
		if (ctx)
			*ctx = conn_get_ssl_sock_ctx(conn);
	}
#ifdef USE_QUIC
	else if (qc) {
		ret = qc->conn;
		if (ctx)
			*ctx = qc->xprt_ctx;
	}
#endif
	return ret;
}

/* Set at <counters> and <counters_px> addresses the SSL statistical counters */
static inline void ssl_sock_get_stats_counters(struct connection *conn,
                                               struct ssl_counters **counters,
                                               struct ssl_counters **counters_px)
{
	switch (obj_type(conn->target)) {
	case OBJ_TYPE_LISTENER: {
		struct listener *li = __objt_listener(conn->target);
		*counters = EXTRA_COUNTERS_GET(li->extra_counters, &ssl_stats_module);
		*counters_px = EXTRA_COUNTERS_GET(li->bind_conf->frontend->extra_counters_fe,
		                                 &ssl_stats_module);
		break;
	}
	case OBJ_TYPE_SERVER: {
		struct server *srv = __objt_server(conn->target);
		*counters = EXTRA_COUNTERS_GET(srv->extra_counters, &ssl_stats_module);
		*counters_px = EXTRA_COUNTERS_GET(srv->proxy->extra_counters_be,
		                                 &ssl_stats_module);
		break;
	}
	default:
		break;
	}
}

#endif /* USE_OPENSSL */
#endif /* _HAPROXY_SSL_SOCK_H */

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */