1/*
2** Zabbix
3** Copyright (C) 2001-2021 Zabbix SIA
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18**/
19
20package tls
21
22/*
23#cgo CFLAGS: -I${SRCDIR}/../../../../include -I${SRCDIR}/../../../../build/win32/include
24
25#cgo openssl LDFLAGS: -lssl -lcrypto -lwsock32 -lws2_32
26
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30#include <unistd.h>
31#include <ctype.h>
32#include "config.h"
33
34#define TLS_UNUSED(var)	(void)(var)
35
36const char	*tls_crypto_init_msg;
37
38#ifdef HAVE_OPENSSL
39#include <openssl/ssl.h>
40#include <openssl/err.h>
41#include <openssl/bio.h>
42#include <openssl/rand.h>
43
44#if defined(LIBRESSL_VERSION_NUMBER)
45#	error package zabbix.com/pkg/tls cannot be compiled with LibreSSL. Encryption is supported with OpenSSL.
46#elif !defined(HAVE_OPENSSL_WITH_PSK)
47#	error package zabbix.com/pkg/tls cannot be compiled with OpenSSL which has excluded PSK support.
48#elif defined(_WINDOWS) && OPENSSL_VERSION_NUMBER < 0x1010100fL	// On MS Windows OpenSSL 1.1.1 is required
49#	error on Microsoft Windows the package zabbix.com/pkg/tls requires OpenSSL 1.1.1 or newer.
50#elif OPENSSL_VERSION_NUMBER < 0x1000100fL
51	// OpenSSL before 1.0.1
52#	error package zabbix.com/pkg/tls cannot be compiled with this OpenSSL version.\
53		Supported versions are 1.0.1 and newer.
54#endif
55
56#if OPENSSL_VERSION_NUMBER < 0x1010000fL
57	// OpenSSL 1.0.1/1.0.2 (before 1.1.0)
58#include <openssl/x509v3.h>	// string_to_hex()
59#	define OPENSSL_hexstr2buf			string_to_hex
60#	define TLS_method				TLSv1_2_method
61#	define SSL_CTX_get_ciphers(ciphers)		((ciphers)->cipher_list)
62#	define OPENSSL_VERSION				SSLEAY_VERSION
63#	define OpenSSL_version				SSLeay_version
64#	define SSL_CTX_set_min_proto_version(ctx, TLSv)	1
65#endif
66
67#define TLS_EX_DATA_ERRBIO	0
68#define TLS_EX_DATA_IDENTITY	1
69#define TLS_EX_DATA_KEY		2
70
71typedef SSL_CTX * SSL_CTX_LP;
72
73typedef struct {
74	SSL *ssl;
75	BIO *in;
76	BIO *out;
77	BIO *err;
78	int ready;
79	char *psk_identity;
80	char *psk_key;
81} tls_t;
82
83#if OPENSSL_VERSION_NUMBER < 0x1010000fL
84        // OpenSSL 1.0.1/1.0.2 (before 1.1.0)
85#include <pthread.h>
86
87// exit codes
88#define ZBX_EXIT_LOCK_FAILED	2
89#define ZBX_EXIT_UNLOCK_FAILED	3
90
91static pthread_mutex_t	*mutexes = NULL;	// Mutexes for multi-threaded OpenSSL (see "man 3ssl threads"
92						// and example in crypto/threads/mttest.c).
93
94static void	zbx_mutex_lock(const char *filename, int line, int idx)
95{
96	if (0 != pthread_mutex_lock(mutexes + idx))
97	{
98		fprintf(stderr, "[file:'%s',line:%d] lock failed: [%d] %s\n", filename, line, errno, strerror(errno));
99		exit(ZBX_EXIT_LOCK_FAILED);
100	}
101}
102
103static void	zbx_mutex_unlock(const char *filename, int line, int idx)
104{
105	if (0 != pthread_mutex_unlock(mutexes + idx))
106	{
107		fprintf(stderr, "[file:'%s',line:%d] unlock failed: [%d] %s\n", filename, line, errno, strerror(errno));
108		exit(ZBX_EXIT_UNLOCK_FAILED);
109	}
110}
111
112static void	zbx_openssl_locking_cb(int mode, int n, const char *file, int line)
113{
114	if (0 != (mode & CRYPTO_LOCK))
115		zbx_mutex_lock(file, line, n);
116	else
117		zbx_mutex_unlock(file, line, n);
118}
119
120static int	zbx_allocate_mutexes(const char **error_msg)
121{
122	int	num_locks, i;
123
124	num_locks = CRYPTO_num_locks();
125
126	if (NULL == (mutexes = malloc((size_t)num_locks * sizeof(pthread_mutex_t))))
127	{
128		*error_msg = strdup("cannot allocate mutexes for OpenSSL library: out of memory");
129		return -1;
130	}
131
132	for (i = 0; i < num_locks; i++)
133	{
134		int	res;
135
136		if (0 != (res = pthread_mutex_init(mutexes + i, NULL)))
137		{
138			char	buf[128];
139
140			snprintf(buf, sizeof(buf), "cannot initialize mutex %d (out of %d) for OpenSSL library:"
141					" pthread_mutex_init() returned %d", i, num_locks, res);
142
143			*error_msg = strdup(buf);
144			return -1;
145		}
146	}
147
148	return 0;
149}
150#endif
151
152static int tls_init(void)
153{
154#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
155	// OpenSSL 1.1.0 or newer
156	if (1 != OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL))
157	{
158		tls_crypto_init_msg = "cannot initialize OpenSSL library";
159		return -1;
160	}
161#else	// OpenSSL 1.0.1/1.0.2 (before 1.1.0)
162	SSL_load_error_strings();
163	ERR_load_BIO_strings();
164	SSL_library_init();
165
166	if (0 != zbx_allocate_mutexes(&tls_crypto_init_msg))
167		return -1;
168
169	CRYPTO_set_locking_callback((void (*)(int, int, const char *, int))zbx_openssl_locking_cb);
170
171	// do not register our own threadid_func() callback, use OpenSSL default one
172#endif
173	if (1 != RAND_status())		// protect against not properly seeded PRNG
174	{
175		tls_crypto_init_msg = "cannot initialize PRNG";
176		return -1;
177	}
178
179	tls_crypto_init_msg = "OpenSSL library successfully initialized";
180	return 0;
181}
182
183static unsigned int tls_psk_client_cb(SSL *ssl, const char *hint, char *identity,
184	unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len)
185{
186	size_t		sz;
187	const char	*psk_identity, *psk_key;
188	BIO		*err;
189	unsigned char 	*key;
190	long		key_len;
191
192	TLS_UNUSED(hint);
193
194	if (NULL == (err = (BIO *)SSL_get_ex_data(ssl, TLS_EX_DATA_ERRBIO)))
195		return 0;
196
197	if (NULL == (psk_identity = (const char *)SSL_get_ex_data(ssl, TLS_EX_DATA_IDENTITY)))
198	{
199		BIO_printf(err, "no PSK identity configured");
200		return 0;
201	}
202
203	if (NULL == (psk_key = (const char *)SSL_get_ex_data(ssl, TLS_EX_DATA_KEY)))
204	{
205		BIO_printf(err, "no PSK key configured");
206		return 0;
207	}
208
209	sz = strlen(psk_identity) + 1;
210	if (sz > max_identity_len)
211	{
212		BIO_printf(err, "PSK identity too large");
213		return 0;
214	}
215
216	memcpy(identity, psk_identity, sz);
217
218	key = OPENSSL_hexstr2buf(psk_key, &key_len);
219	if (key == NULL)
220	{
221		BIO_printf(err, "invalid PSK key");
222		return 0;
223	}
224
225	if (key_len > (long)max_psk_len)
226	{
227		BIO_printf(err, "PSK key is too large");
228		OPENSSL_free(key);
229		return 0;
230	}
231
232	memcpy(psk, key, (size_t)key_len);
233	OPENSSL_free(key);
234	return (unsigned int)key_len;
235}
236
237static unsigned int tls_psk_server_cb(SSL *ssl, const char *identity, unsigned char *psk, unsigned int max_psk_len)
238{
239	const char	*psk_identity, *psk_key;
240	BIO		*err;
241	unsigned char	*key;
242	long		key_len;
243
244	if (NULL == (err = (BIO *)SSL_get_ex_data(ssl, TLS_EX_DATA_ERRBIO)))
245		return 0;
246
247	if (NULL == (psk_identity = (const char *)SSL_get_ex_data(ssl, TLS_EX_DATA_IDENTITY)))
248	{
249		BIO_printf(err, "no PSK identity configured");
250		return 0;
251	}
252
253	if (0 != strcmp(psk_identity, identity))
254	{
255		BIO_printf(err, "invalid PSK identity");
256		return 0;
257	}
258
259	if (NULL == (psk_key = (const char *)SSL_get_ex_data(ssl, TLS_EX_DATA_KEY)))
260	{
261		BIO_printf(err, "no PSK key configured");
262		return 0;
263	}
264
265	key = OPENSSL_hexstr2buf(psk_key, &key_len);
266	if (key == NULL)
267	{
268		BIO_printf(err, "invalid PSK key");
269		return 0;
270	}
271
272	if (key_len > (long)max_psk_len)
273	{
274		BIO_printf(err, "PSK key is too large");
275		return 0;
276	}
277
278	memcpy(psk, key, (size_t)key_len);
279	OPENSSL_free(key);
280	return (unsigned int)key_len;
281}
282
283static int	zbx_set_ecdhe_parameters(SSL_CTX *ctx)
284{
285	EC_KEY	*ecdh;
286	long	res;
287	int	ret = 0;
288
289	// use curve secp256r1/prime256v1/NIST P-256
290
291	if (NULL == (ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)))
292		return -1;
293
294	SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
295
296	if (1 != (res = SSL_CTX_set_tmp_ecdh(ctx, ecdh)))
297		ret = -1;
298
299	EC_KEY_free(ecdh);
300
301	return ret;
302}
303
304static void *tls_new_context(const char *ca_file, const char *crl_file, const char *cert_file, const char *key_file,
305		char **error)
306{
307#define TLS_CIPHER_CERT_ECDHE		"EECDH+aRSA+AES128:"
308#define TLS_CIPHER_CERT			"RSA+aRSA+AES128"
309
310#if defined(HAVE_OPENSSL_WITH_PSK)
311#if OPENSSL_VERSION_NUMBER >= 0x1010100fL	// OpenSSL 1.1.1 or newer
312	// TLS_AES_256_GCM_SHA384 is excluded from client ciphersuite list for PSK based connections.
313	// By default, in TLS 1.3 only *-SHA256 ciphersuites work with PSK.
314#	define TLS_1_3_CIPHERSUITES	"TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
315#endif
316#if OPENSSL_VERSION_NUMBER >= 0x1010000fL	// OpenSSL 1.1.0 or newer
317#	define TLS_CIPHER_PSK_ECDHE	"kECDHEPSK+AES128:"
318#	define TLS_CIPHER_PSK		"kPSK+AES128"
319#else						// OpenSSL 1.0.1/1.0.2 (before 1.1.0)
320#	define TLS_CIPHER_PSK_ECDHE	""
321#	define TLS_CIPHER_PSK		"PSK-AES128-CBC-SHA"
322#endif
323#endif
324	SSL_CTX		*ctx;
325	int		ret = -1;
326	const char	*ciphers;
327
328	if (NULL == (ctx = SSL_CTX_new(TLS_method())))
329		goto out;
330
331	if (1 != SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION))
332		goto out;
333
334	if (NULL != ca_file)
335	{
336		if (1 != SSL_CTX_load_verify_locations(ctx, ca_file, NULL))
337			goto out;
338
339		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
340
341		if (NULL != crl_file)
342		{
343			X509_STORE	*store_cert;
344			X509_LOOKUP	*lookup_cert;
345			int		count_cert;
346
347			store_cert = SSL_CTX_get_cert_store(ctx);
348
349			if (NULL == (lookup_cert = X509_STORE_add_lookup(store_cert, X509_LOOKUP_file())))
350				goto out;
351
352			if (0 >= (count_cert = X509_load_crl_file(lookup_cert, crl_file, X509_FILETYPE_PEM)))
353				goto out;
354
355			if (1 != X509_STORE_set_flags(store_cert, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL))
356				goto out;
357		}
358	}
359
360	if (NULL != cert_file && 1 != SSL_CTX_use_certificate_chain_file(ctx, cert_file))
361		goto out;
362
363	if (NULL != key_file && 1 != SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM))
364		goto out;
365
366	SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
367	SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_NO_TICKET);
368	SSL_CTX_clear_options(ctx, SSL_OP_LEGACY_SERVER_CONNECT);
369	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
370
371	// try to enable ECDH ciphersuites
372	if (0 == zbx_set_ecdhe_parameters(ctx))
373	{
374		if (NULL != ca_file)
375			ciphers = TLS_CIPHER_CERT_ECDHE TLS_CIPHER_CERT ":" TLS_CIPHER_PSK_ECDHE TLS_CIPHER_PSK;
376		else
377			ciphers = TLS_CIPHER_PSK_ECDHE TLS_CIPHER_PSK;
378	}
379	else
380	{
381		if (NULL != ca_file)
382			ciphers = TLS_CIPHER_CERT ":" TLS_CIPHER_PSK;
383		else
384			ciphers = TLS_CIPHER_PSK;
385	}
386
387#if OPENSSL_VERSION_NUMBER >= 0x1010100fL	// OpenSSL 1.1.1
388	if (1 != SSL_CTX_set_ciphersuites(ctx, TLS_1_3_CIPHERSUITES))
389		goto out;
390#endif
391
392	if (1 != SSL_CTX_set_cipher_list(ctx, ciphers))
393		goto out;
394
395	ret = 0;
396out:
397	if (-1 == ret)
398	{
399		int	sz;
400		BIO	*err;
401
402		err = BIO_new(BIO_s_mem());
403		BIO_set_nbio(err, 1);
404		ERR_print_errors(err);
405
406		sz = (int)BIO_ctrl_pending(err);
407		if (sz != 0)
408		{
409			*error = malloc((size_t)sz + 1);
410			BIO_read(err, *error, sz);
411			(*error)[sz] = '\0';
412		}
413		else
414			*error = strdup("unknown openssl error");
415
416		BIO_vfree(err);
417		if (NULL != ctx)
418		{
419			SSL_CTX_free(ctx);
420			ctx = NULL;
421		}
422	}
423	return ctx;
424}
425
426static void tls_free_context(SSL_CTX_LP ctx)
427{
428	SSL_CTX_free(ctx);
429}
430
431static int tls_new(SSL_CTX_LP ctx, const char *psk_identity, const char *psk_key, tls_t **ptls)
432{
433	tls_t	*tls;
434
435	*ptls = tls = malloc(sizeof(tls_t));
436	memset(tls, 0, sizeof(tls_t));
437
438	if (NULL != psk_identity)
439		tls->psk_identity = strdup(psk_identity);
440	if (NULL != psk_key)
441		tls->psk_key = strdup(psk_key);
442
443	tls->err = BIO_new(BIO_s_mem());
444	BIO_set_nbio(tls->err, 1);
445
446	if (NULL == (tls->ssl = SSL_new(ctx)))
447		return -1;
448
449	if (1 != SSL_set_ex_data(tls->ssl, TLS_EX_DATA_ERRBIO, (void *)tls->err))
450		return -1;
451
452	if (1 != SSL_set_ex_data(tls->ssl, TLS_EX_DATA_IDENTITY, (void *)tls->psk_identity))
453		return -1;
454
455	if (1 != SSL_set_ex_data(tls->ssl, TLS_EX_DATA_KEY, (void *)tls->psk_key))
456		return -1;
457
458	tls->in = BIO_new(BIO_s_mem());
459	tls->out = BIO_new(BIO_s_mem());
460	BIO_set_nbio(tls->in, 1);
461	BIO_set_nbio(tls->out, 1);
462	SSL_set_bio(tls->ssl, tls->in, tls->out);
463
464	return 0;
465}
466
467static tls_t *tls_new_client(SSL_CTX_LP ctx, const char *psk_identity, const char *psk_key)
468{
469	tls_t	*tls;
470	int	ret;
471
472	if (0 == tls_new(ctx, psk_identity, psk_key, &tls))
473	{
474		if (psk_identity != NULL && psk_key != NULL)
475			SSL_set_psk_client_callback(tls->ssl, tls_psk_client_cb);
476
477		SSL_set_connect_state(tls->ssl);
478		if (1 == (ret = SSL_connect(tls->ssl)) || SSL_ERROR_WANT_READ == SSL_get_error(tls->ssl, ret))
479			tls->ready = 1;
480	}
481	return tls;
482}
483
484static tls_t *tls_new_server(SSL_CTX_LP ctx, const char *psk_identity, const char *psk_key)
485{
486	tls_t	*tls;
487	int	ret;
488
489	if (0 == tls_new(ctx, psk_identity, psk_key, &tls))
490	{
491#if OPENSSL_VERSION_NUMBER >= 0x1010100fL	// OpenSSL 1.1.1 or newer, or LibreSSL
492		if (1 != SSL_set_session_id_context(tls->ssl, (const unsigned char *)"Zbx", sizeof("Zbx") - 1))
493			return tls;
494#endif
495		if (psk_identity != NULL && psk_key != NULL)
496			SSL_set_psk_server_callback(tls->ssl, tls_psk_server_cb);
497
498		SSL_set_accept_state(tls->ssl);
499
500		if (1 == (ret = SSL_accept(tls->ssl)) || SSL_ERROR_WANT_READ == SSL_get_error(tls->ssl, ret))
501			tls->ready = 1;
502	}
503	return tls;
504}
505
506static int tls_recv(tls_t *tls, char *buf, int size)
507{
508	if (BIO_ctrl_pending(tls->out))
509		return BIO_read(tls->out, buf, size);
510	return 0;
511}
512
513static int tls_send(tls_t *tls, char *buf, int size)
514{
515	return BIO_write(tls->in, buf, size);
516}
517
518static int tls_connected(tls_t *tls)
519{
520	return SSL_is_init_finished(tls->ssl);
521}
522
523static int tls_write(tls_t *tls, char *buf, int len)
524{
525	return SSL_write(tls->ssl, buf, len);
526}
527
528static int tls_read(tls_t *tls, char *buf, int len)
529{
530	int ret;
531	ret = SSL_read(tls->ssl, buf, len);
532	if (0 > ret) {
533		if (SSL_ERROR_WANT_READ == SSL_get_error(tls->ssl, ret))
534			return 0;
535		return ret;
536	}
537	return ret;
538}
539
540static int tls_handshake(tls_t *tls)
541{
542	int ret;
543	ret = SSL_do_handshake(tls->ssl);
544	if (0 > ret) {
545		if (SSL_ERROR_WANT_READ == SSL_get_error(tls->ssl, ret))
546			return 1;
547		return ret;
548	}
549	return 0;
550}
551
552static int tls_accept(tls_t *tls)
553{
554	int ret;
555	ret = SSL_accept(tls->ssl);
556	if (0 > ret) {
557		if (SSL_ERROR_WANT_READ == SSL_get_error(tls->ssl, ret))
558			return 1;
559		return ret;
560	}
561	return 0;
562}
563
564static size_t tls_error(tls_t *tls, char **buf)
565{
566	size_t	sz;
567
568	sz = BIO_ctrl_pending(tls->err);
569	if (sz == 0)
570	{
571		long	verify_result;
572
573		if (X509_V_OK != (verify_result = SSL_get_verify_result(tls->ssl)))
574			BIO_printf(tls->err, "%s: ", X509_verify_cert_error_string(verify_result));
575
576		ERR_print_errors(tls->err);
577		sz = BIO_ctrl_pending(tls->err);
578	}
579
580	if (sz != 0)
581	{
582		*buf = malloc(sz + 1);
583		BIO_read(tls->err, *buf, (int)sz);
584		(*buf)[sz] = '\0';
585	}
586	else
587		*buf = strdup("unknown error");
588
589	BIO_reset(tls->err);
590	return sz;
591}
592
593static int tls_ready(tls_t *tls)
594{
595	return tls->ready;
596}
597
598static int tls_close(tls_t *tls)
599{
600	int	ret;
601	if (0 > (ret = SSL_shutdown(tls->ssl)) && SSL_ERROR_WANT_READ == SSL_get_error(tls->ssl, ret))
602		return 0;
603	return ret;
604}
605
606static void tls_free(tls_t *tls)
607{
608	if (NULL != tls->ssl)
609		SSL_free(tls->ssl);
610	if (NULL != tls->err)
611		BIO_vfree(tls->err);
612	if (NULL != tls->psk_identity)
613		free(tls->psk_identity);
614	if (NULL != tls->psk_key)
615		free(tls->psk_key);
616	free(tls);
617}
618
619static int	tls_get_x509_name(tls_t *tls, X509_NAME *dn, char **name)
620{
621	BIO		*bio;
622	const char	*data;
623	size_t		len;
624	int		ret = -1;
625
626	if (NULL == (bio = BIO_new(BIO_s_mem())))
627	{
628		BIO_printf(tls->err, "cannot create OpenSSL BIO");
629		return -1;
630	}
631
632	if (0 > X509_NAME_print_ex(bio, dn, 0, XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB))
633	{
634		BIO_printf(tls->err, "cannot print distinguished name");
635	}
636	else
637	{
638		len = (size_t)BIO_get_mem_data(bio, &data);
639		*name = malloc(len + 1);
640		memcpy(*name, data, len);
641		(*name)[len] = '\0';
642		ret = 0;
643	}
644	BIO_vfree(bio);
645
646	return ret;
647}
648
649static int tls_validate_issuer_and_subject(tls_t *tls, const char *issuer, const char *subject)
650{
651	X509	*cert;
652	char *peer_issuer = NULL, *peer_subject = NULL;
653	int ret = -1;
654
655	if (NULL == (cert = SSL_get_peer_certificate(tls->ssl)))
656	{
657		BIO_printf(tls->err, "cannot obtain peer certificate");
658		goto out;
659	}
660
661	if (NULL != issuer)
662	{
663		if (0 != tls_get_x509_name(tls, X509_get_issuer_name(cert), &peer_issuer))
664			goto out;
665		if (0 != strcmp(issuer, peer_issuer))
666		{
667			BIO_printf(tls->err, "invalid certificate issuer %s", peer_issuer);
668			goto out;
669		}
670	}
671
672	if (NULL != subject)
673	{
674		if (0 != tls_get_x509_name(tls, X509_get_subject_name(cert), &peer_subject))
675			goto out;
676		if (0 != strcmp(subject, peer_subject))
677		{
678			BIO_printf(tls->err, "invalid certificate subject %s", peer_subject);
679			goto out;
680		}
681	}
682	ret = 0;
683out:
684	free(peer_issuer);
685	free(peer_subject);
686	X509_free(cert);
687	return ret;
688}
689
690#define TLS_MAX_BUF_LEN	2048
691
692static void tls_description(tls_t *tls, char **desc)
693{
694	X509	*cert;
695	char	*peer_issuer = NULL, *peer_subject = NULL, buf[TLS_MAX_BUF_LEN], *ptr = buf;
696
697	ptr += snprintf(ptr, sizeof(buf), "%s %s", SSL_get_version(tls->ssl), SSL_get_cipher(tls->ssl));
698
699	if ((sizeof(buf) - 1 > (size_t)(ptr - buf)) && NULL != (cert = SSL_get_peer_certificate(tls->ssl)))
700	{
701		if (0 == tls_get_x509_name(tls, X509_get_issuer_name(cert), &peer_issuer) &&
702			0 == tls_get_x509_name(tls, X509_get_subject_name(cert), &peer_subject))
703		{
704			// ensure buffer length for writing at least ', peer certificate issuer:" " subject:" "'
705			if (sizeof(buf) - (size_t)(ptr - buf) > 41)
706			{
707				snprintf(ptr, sizeof(buf) - (size_t)(ptr - buf),
708						", peer certificate issuer:\"%s\" subject:\"%s\"",
709						peer_issuer, peer_subject);
710			}
711		}
712	}
713	*desc = strdup(buf);
714	free(peer_issuer);
715	free(peer_subject);
716}
717
718//*****************************************************************************
719//                                                                           //
720// Function: tls_describe_ciphersuites                                       //
721//                                                                           //
722// Purpose: write names of enabled OpenSSL ciphersuites into dynamically     //
723//          allocated string                                                 //
724//                                                                           //
725//*****************************************************************************
726static void tls_describe_ciphersuites(SSL_CTX_LP ctx, char **desc)
727{
728#define TLS_CIPHERS_BUF_LEN	8192
729
730	int			i, num;
731	size_t			offset = 0;
732	STACK_OF(SSL_CIPHER)	*cipher_list;
733	char			buf[TLS_CIPHERS_BUF_LEN];
734
735	buf[0] = '\0';
736	cipher_list = SSL_CTX_get_ciphers(ctx);
737	num = sk_SSL_CIPHER_num(cipher_list);
738
739	for (i = 0; i < num; i++)
740	{
741		offset += (size_t)snprintf(buf + offset, sizeof(buf) - offset, " %s",
742				SSL_CIPHER_get_name(sk_SSL_CIPHER_value(cipher_list, i)));
743
744		if (sizeof(buf) - 2 <= offset)
745		{
746			const char	*msg = "...(truncated)";
747
748			snprintf(buf + sizeof(buf) - strlen(msg) - 1, strlen(msg) + 1, "%s", msg);
749			break;
750		}
751	}
752	*desc = strdup(buf);
753
754#undef TLS_CIPHERS_BUF_LEN
755}
756
757static const char	*tls_version(void)
758{
759	return OpenSSL_version(OPENSSL_VERSION);
760}
761
762static const char	*tls_version_static(void)
763{
764	return OPENSSL_VERSION_TEXT;
765}
766
767#elif defined(HAVE_GNUTLS)
768#	error zabbix_agent2 does not support GnuTLS library. Compile with OpenSSL\
769		(configure parameter --with-openssl) or without encryption support.
770#else // no crypto library requested, compile without encryption support
771
772typedef void * SSL_CTX_LP;
773
774typedef struct {
775} tls_t;
776
777static int tls_init(void)
778{
779	tls_crypto_init_msg = "encryption support was not compiled in";
780	return -1;
781}
782
783static void *tls_new_context(const char *ca_file, const char *crl_file, const char *cert_file, const char *key_file,
784		 char **error)
785{
786	TLS_UNUSED(ca_file);
787	TLS_UNUSED(crl_file);
788	TLS_UNUSED(cert_file);
789	TLS_UNUSED(key_file);
790	*error = strdup("built without OpenSSL");
791	return NULL;
792}
793
794static void tls_free_context(SSL_CTX_LP ctx)
795{
796	TLS_UNUSED(ctx);
797}
798
799static tls_t *tls_new_client(SSL_CTX_LP ctx, const char *psk_identity, const char *psk_key)
800{
801	TLS_UNUSED(ctx);
802	TLS_UNUSED(psk_identity);
803	TLS_UNUSED(psk_key);
804	return NULL;
805}
806
807static tls_t *tls_new_server(SSL_CTX_LP ctx, const char *psk_identity, const char *psk_key)
808{
809	TLS_UNUSED(ctx);
810	TLS_UNUSED(psk_identity);
811	TLS_UNUSED(psk_key);
812	return NULL;
813}
814
815static int tls_recv(tls_t *tls, char *buf, int size)
816{
817	TLS_UNUSED(tls);
818	TLS_UNUSED(buf);
819	TLS_UNUSED(size);
820	return 0;
821}
822
823static int tls_send(tls_t *tls, char *buf, int size)
824{
825	TLS_UNUSED(tls);
826	TLS_UNUSED(buf);
827	TLS_UNUSED(size);
828	return 0;
829}
830
831static int tls_connected(tls_t *tls)
832{
833	TLS_UNUSED(tls);
834	return 0;
835}
836
837static int tls_write(tls_t *tls, char *buf, int len)
838{
839	TLS_UNUSED(tls);
840	TLS_UNUSED(buf);
841	TLS_UNUSED(len);
842	return 0;
843}
844
845static int tls_read(tls_t *tls, char *buf, int len)
846{
847	TLS_UNUSED(tls);
848	TLS_UNUSED(buf);
849	TLS_UNUSED(len);
850	return 0;
851}
852
853static int tls_handshake(tls_t *tls)
854{
855	TLS_UNUSED(tls);
856	return 0;
857}
858
859static int tls_accept(tls_t *tls)
860{
861	TLS_UNUSED(tls);
862	return 0;
863}
864
865static size_t tls_error(tls_t *tls, char **buf)
866{
867	TLS_UNUSED(tls);
868	TLS_UNUSED(buf);
869	return 0;
870}
871
872static int tls_ready(tls_t *tls)
873{
874	TLS_UNUSED(tls);
875	return 0;
876}
877
878static int tls_close(tls_t *tls)
879{
880	TLS_UNUSED(tls);
881	return 0;
882}
883
884static void tls_free(tls_t *tls)
885{
886	TLS_UNUSED(tls);
887}
888
889static int tls_validate_issuer_and_subject(tls_t *tls, const char *issuer, const char *subject)
890{
891	TLS_UNUSED(tls);
892	TLS_UNUSED(issuer);
893	TLS_UNUSED(subject);
894	return 0;
895}
896
897static void tls_description(tls_t *tls, char **desc)
898{
899	TLS_UNUSED(tls);
900	TLS_UNUSED(desc);
901}
902
903static void tls_describe_ciphersuites(SSL_CTX_LP ciphers, char **desc)
904{
905	TLS_UNUSED(ciphers);
906	TLS_UNUSED(desc);
907}
908
909static const char	*tls_version(void)
910{
911	return NULL;
912}
913
914static const char	*tls_version_static(void)
915{
916	return NULL;
917}
918
919#endif
920
921*/
922import "C"
923
924import (
925	"errors"
926	"fmt"
927	"net"
928	"runtime"
929	"time"
930	"unsafe"
931
932	"zabbix.com/pkg/log"
933)
934
935// TLS initialization
936var supported bool      // is TLS compiled in and successfully initialized
937var supportedMsg string // reason why TLS is not supported
938
939func Supported() bool {
940	return supported
941}
942
943func SupportedErrMsg() string {
944	return supportedMsg
945}
946
947func init() {
948	supported = C.tls_init() != -1
949
950	if !supported {
951		supportedMsg = C.GoString(C.tls_crypto_init_msg)
952	}
953}
954
955func describeCiphersuites(context unsafe.Pointer) (desc string) {
956	var cDesc *C.char
957	C.tls_describe_ciphersuites(C.SSL_CTX_LP(context), &cDesc)
958	desc = C.GoString(cDesc)
959	C.free(unsafe.Pointer(cDesc))
960	return
961}
962
963type tlsConn struct {
964	conn          net.Conn
965	tls           unsafe.Pointer
966	buf           []byte
967	timeout       time.Duration
968	shiftDeadline bool
969}
970
971func (c *tlsConn) Error() (err error) {
972	var cBuf *C.char
973	var errmsg string
974	if c.tls != nil && 0 != C.tls_error((*C.tls_t)(c.tls), &cBuf) {
975		errmsg = C.GoString(cBuf)
976		C.free(unsafe.Pointer(cBuf))
977	} else {
978		errmsg = "unknown openssl error"
979	}
980	return errors.New(errmsg)
981}
982
983func (c *tlsConn) ready() bool {
984	return C.tls_ready((*C.tls_t)(c.tls)) == 1
985}
986
987// Note, don't use flushTLS() and recvTLS() concurrently
988func (c *tlsConn) flushTLS() (err error) {
989	for {
990		if cn := C.tls_recv((*C.tls_t)(c.tls), (*C.char)(unsafe.Pointer(&c.buf[0])), C.int(len(c.buf))); cn > 0 {
991			if c.shiftDeadline {
992				if err = c.conn.SetWriteDeadline(time.Now().Add(c.timeout)); err != nil {
993					return
994				}
995			}
996
997			if _, err = c.conn.Write(c.buf[:cn]); err != nil {
998				return
999			}
1000		} else {
1001			return
1002		}
1003	}
1004}
1005
1006// Note, don't use flushTLS() and recvTLS() concurrently
1007func (c *tlsConn) recvTLS() (err error) {
1008	var n int
1009	if c.shiftDeadline {
1010		if err = c.conn.SetReadDeadline(time.Now().Add(c.timeout)); err != nil {
1011			return
1012		}
1013	}
1014	if n, err = c.conn.Read(c.buf); err != nil {
1015		return
1016	}
1017	C.tls_send((*C.tls_t)(c.tls), (*C.char)(unsafe.Pointer(&c.buf[0])), C.int(n))
1018	return
1019}
1020
1021func (c *tlsConn) LocalAddr() net.Addr {
1022	return c.conn.LocalAddr()
1023}
1024
1025func (c *tlsConn) RemoteAddr() net.Addr {
1026	return c.conn.RemoteAddr()
1027}
1028
1029func (c *tlsConn) SetDeadline(t time.Time) error {
1030	return c.conn.SetDeadline(t)
1031}
1032
1033func (c *tlsConn) SetReadDeadline(t time.Time) error {
1034	return c.conn.SetReadDeadline(t)
1035}
1036
1037func (c *tlsConn) SetWriteDeadline(t time.Time) error {
1038	return c.conn.SetWriteDeadline(t)
1039}
1040
1041func (c *tlsConn) Close() (err error) {
1042	cr := C.tls_close((*C.tls_t)(c.tls))
1043	c.conn.Close()
1044	if cr < 0 {
1045		return c.Error()
1046	}
1047	return
1048}
1049
1050func (c *tlsConn) verifyIssuerSubject(cfg *Config) (err error) {
1051	if cfg.Connect == ConnCert && (cfg.ServerCertIssuer != "" || cfg.ServerCertSubject != "") {
1052		var cSubject, cIssuer *C.char
1053		if cfg.ServerCertIssuer != "" {
1054			cIssuer = C.CString(cfg.ServerCertIssuer)
1055			defer C.free(unsafe.Pointer(cSubject))
1056		}
1057		if cfg.ServerCertSubject != "" {
1058			cSubject = C.CString(cfg.ServerCertSubject)
1059			defer C.free(unsafe.Pointer(cSubject))
1060		}
1061		if 0 != C.tls_validate_issuer_and_subject((*C.tls_t)(c.tls), cIssuer, cSubject) {
1062			return c.Error()
1063		}
1064	}
1065	return
1066}
1067
1068func (c *tlsConn) String() (desc string) {
1069	var cDesc *C.char
1070	C.tls_description((*C.tls_t)(c.tls), &cDesc)
1071	desc = C.GoString(cDesc)
1072	C.free(unsafe.Pointer(cDesc))
1073	return
1074}
1075
1076// TLS connection client
1077type Client struct {
1078	tlsConn
1079}
1080
1081func (c *Client) checkConnection() (err error) {
1082	if C.tls_connected((*C.tls_t)(c.tls)) == C.int(1) {
1083		return
1084	}
1085	for C.tls_connected((*C.tls_t)(c.tls)) != C.int(1) {
1086		cRet := C.tls_handshake((*C.tls_t)(c.tls))
1087		if cRet == 0 {
1088			break
1089		}
1090		if cRet < 0 {
1091			return c.Error()
1092		}
1093		if err = c.flushTLS(); err != nil {
1094			return
1095		}
1096		if err = c.recvTLS(); err != nil {
1097			return
1098		}
1099	}
1100	err = c.flushTLS()
1101	return
1102}
1103
1104func (c *Client) Write(b []byte) (n int, err error) {
1105	if err = c.checkConnection(); err != nil {
1106		return
1107	}
1108	cRet := C.tls_write((*C.tls_t)(c.tls), (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
1109	if cRet <= 0 {
1110		return 0, c.Error()
1111	}
1112	if err = c.flushTLS(); err != nil {
1113		return
1114	}
1115	return len(b), nil
1116}
1117
1118func (c *Client) Read(b []byte) (n int, err error) {
1119	for {
1120		if err = c.checkConnection(); err != nil {
1121			return
1122		}
1123		cRet := C.tls_read((*C.tls_t)(c.tls), (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
1124		if cRet > 0 {
1125			return int(cRet), nil
1126		}
1127		if cRet < 0 {
1128			return 0, c.Error()
1129		}
1130		if err = c.recvTLS(); err != nil {
1131			return
1132		}
1133	}
1134}
1135
1136func NewClient(nc net.Conn, cfg *Config, timeout time.Duration, shiftDeadline bool) (conn net.Conn, err error) {
1137	if !supported {
1138		return nil, errors.New(SupportedErrMsg())
1139	}
1140
1141	if cfg.Connect == ConnUnencrypted {
1142		return nc, nil
1143	}
1144
1145	var cUser, cSecret *C.char
1146	context := defaultContext
1147	if cfg.Connect == ConnPSK {
1148		cUser = C.CString(cfg.PSKIdentity)
1149		cSecret = C.CString(cfg.PSKKey)
1150
1151		defer func() {
1152			C.free(unsafe.Pointer(cUser))
1153			C.free(unsafe.Pointer(cSecret))
1154		}()
1155		context = pskContext
1156	}
1157
1158	// for TLS we overwrite the timeoutMode and force it to move on every read or write
1159	c := &Client{
1160		tlsConn: tlsConn{
1161			conn:          nc,
1162			buf:           make([]byte, 4096),
1163			tls:           unsafe.Pointer(C.tls_new_client(C.SSL_CTX_LP(context), cUser, cSecret)),
1164			timeout:       timeout,
1165			shiftDeadline: shiftDeadline,
1166		},
1167	}
1168	runtime.SetFinalizer(c, func(c *Client) { C.tls_free((*C.tls_t)(c.tls)) })
1169
1170	if !c.ready() {
1171		return nil, c.Error()
1172	}
1173	if err = c.checkConnection(); err != nil {
1174		c.conn.Close()
1175		return
1176	}
1177	if err = c.verifyIssuerSubject(cfg); err != nil {
1178		c.Close()
1179		return
1180	}
1181
1182	log.Debugf("connection established using %s", c)
1183
1184	return c, nil
1185}
1186
1187// TLS connection server
1188type Server struct {
1189	tlsConn
1190}
1191
1192func (s *Server) checkConnection() (err error) {
1193	if C.tls_connected((*C.tls_t)(s.tls)) == C.int(1) {
1194		return
1195	}
1196	for {
1197		cRet := C.tls_accept((*C.tls_t)(s.tls))
1198		if cRet == 0 {
1199			break
1200		}
1201		if cRet < 0 {
1202			return s.Error()
1203		}
1204		if err = s.flushTLS(); err != nil {
1205			return
1206		}
1207		if err = s.recvTLS(); err != nil {
1208			return
1209		}
1210	}
1211	err = s.flushTLS()
1212	return
1213}
1214
1215func (s *Server) Write(b []byte) (n int, err error) {
1216	if err = s.checkConnection(); err != nil {
1217		return
1218	}
1219	cRet := C.tls_write((*C.tls_t)(s.tls), (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
1220	if cRet <= 0 {
1221		return 0, s.Error()
1222	}
1223
1224	return len(b), s.flushTLS()
1225}
1226
1227func (s *Server) Read(b []byte) (n int, err error) {
1228	for {
1229		if err = s.checkConnection(); err != nil {
1230			return
1231		}
1232		cRet := C.tls_read((*C.tls_t)(s.tls), (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
1233		if cRet > 0 {
1234			return int(cRet), nil
1235		}
1236		if cRet < 0 {
1237			return 0, s.Error()
1238		}
1239		if err = s.recvTLS(); err != nil {
1240			return
1241		}
1242	}
1243}
1244
1245func NewServer(nc net.Conn, cfg *Config, b []byte, timeout time.Duration, shiftDeadline bool) (conn net.Conn, err error) {
1246	if !supported {
1247		return nil, errors.New(SupportedErrMsg())
1248	}
1249
1250	var cUser, cSecret *C.char
1251	if cfg.Accept&ConnPSK != 0 {
1252		cUser = C.CString(cfg.PSKIdentity)
1253		cSecret = C.CString(cfg.PSKKey)
1254
1255		defer func() {
1256			C.free(unsafe.Pointer(cUser))
1257			C.free(unsafe.Pointer(cSecret))
1258		}()
1259	}
1260
1261	context := pskContext
1262	if cfg.Accept&ConnCert != 0 {
1263		context = defaultContext
1264	}
1265
1266	// for TLS we overwrite the timeoutMode and force it to move on every read or write
1267	s := &Server{
1268		tlsConn: tlsConn{
1269			conn:          nc,
1270			buf:           make([]byte, 4096),
1271			tls:           unsafe.Pointer(C.tls_new_server(C.SSL_CTX_LP(context), cUser, cSecret)),
1272			timeout:       timeout,
1273			shiftDeadline: shiftDeadline,
1274		},
1275	}
1276	runtime.SetFinalizer(s, func(s *Server) { C.tls_free((*C.tls_t)(s.tls)) })
1277
1278	if !s.ready() {
1279		return nil, s.Error()
1280	}
1281
1282	C.tls_send((*C.tls_t)(s.tls), (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
1283
1284	if err = s.checkConnection(); err != nil {
1285		s.conn.Close()
1286		return
1287	}
1288	if err = s.verifyIssuerSubject(cfg); err != nil {
1289		s.Close()
1290		return
1291	}
1292
1293	log.Debugf("connection established using %s", s)
1294
1295	return s, nil
1296}
1297
1298var pskContext, defaultContext unsafe.Pointer
1299
1300const (
1301	ConnUnencrypted = 1 << iota
1302	ConnPSK
1303	ConnCert
1304)
1305
1306type Config struct {
1307	Accept            int
1308	Connect           int
1309	PSKIdentity       string
1310	PSKKey            string
1311	CAFile            string
1312	CRLFile           string
1313	CertFile          string
1314	KeyFile           string
1315	ServerCertIssuer  string
1316	ServerCertSubject string
1317}
1318
1319func CopyrightMessage() (message string) {
1320	version := C.tls_version()
1321	if version == nil {
1322		return ""
1323	}
1324
1325	return fmt.Sprintf("\n\nThis product includes software developed by the OpenSSL Project\n"+
1326		"for use in the OpenSSL Toolkit (http://www.openssl.org/).\n\n"+
1327		"Compiled with %s\nRunning with %s\n", C.GoString(C.tls_version_static()), C.GoString(version))
1328}
1329
1330func Init(config *Config) (err error) {
1331	if !supported {
1332		return errors.New(SupportedErrMsg())
1333	}
1334	if pskContext != nil {
1335		C.tls_free_context(C.SSL_CTX_LP(pskContext))
1336	}
1337	if defaultContext != nil {
1338		C.tls_free_context(C.SSL_CTX_LP(defaultContext))
1339	}
1340
1341	var cErr, cCaFile, cCrlFile, cCertFile, cKeyFile, cNULL *C.char
1342	if (config.Accept|config.Connect)&ConnCert != 0 {
1343		cCaFile = C.CString(config.CAFile)
1344		cCertFile = C.CString(config.CertFile)
1345		cKeyFile = C.CString(config.KeyFile)
1346		defer C.free(unsafe.Pointer(cCaFile))
1347		defer C.free(unsafe.Pointer(cCertFile))
1348		defer C.free(unsafe.Pointer(cKeyFile))
1349
1350		if config.CRLFile != "" {
1351			cCrlFile = C.CString(config.CRLFile)
1352			defer C.free(unsafe.Pointer(cCrlFile))
1353		}
1354	}
1355
1356	if defaultContext = unsafe.Pointer(C.tls_new_context(cCaFile, cCrlFile, cCertFile, cKeyFile, &cErr)); defaultContext == nil {
1357		err = fmt.Errorf("cannot initialize default TLS context: %s", C.GoString(cErr))
1358		C.free(unsafe.Pointer(cErr))
1359		return
1360	}
1361
1362	if pskContext = unsafe.Pointer(C.tls_new_context(cNULL, cNULL, cNULL, cNULL, &cErr)); pskContext == nil {
1363		err = fmt.Errorf("cannot initialize PSK TLS context: %s", C.GoString(cErr))
1364		C.free(unsafe.Pointer(cErr))
1365		return
1366	}
1367
1368	log.Infof("OpenSSL library (%s) initialized", C.GoString(C.tls_version()))
1369	log.Debugf("default context ciphersuites:%s", describeCiphersuites(defaultContext))
1370	log.Debugf("psk context ciphersuites:%s", describeCiphersuites(pskContext))
1371
1372	return
1373}
1374