summaryrefslogtreecommitdiff
path: root/src/rexmpp_tls.c
diff options
context:
space:
mode:
authordefanor <defanor@uberspace.net>2023-06-14 08:26:57 +0300
committerdefanor <defanor@uberspace.net>2023-06-14 08:26:57 +0300
commit931847c9c0d170410ec210ab558f3bbf6902355b (patch)
tree4d7bf90b30dc985edfbc09a5d0007b4aac8da533 /src/rexmpp_tls.c
parent2d4110996bea53a9568b750d00d4dcdcc3907bc6 (diff)
Use more pointers to other structures from struct rexmpp
Instead of including them. Those structures can vary depending on configuration options, while for bindings it is easier if they stay the same, and are mere pointers. Besides, some of them may refer to opaque Rust-only structures in the future.
Diffstat (limited to 'src/rexmpp_tls.c')
-rw-r--r--src/rexmpp_tls.c173
1 files changed, 88 insertions, 85 deletions
diff --git a/src/rexmpp_tls.c b/src/rexmpp_tls.c
index 7919556..96c042a 100644
--- a/src/rexmpp_tls.c
+++ b/src/rexmpp_tls.c
@@ -25,15 +25,15 @@
#if defined(USE_OPENSSL)
rexmpp_tls_err_t rexmpp_process_openssl_ret (rexmpp_t *s, int ret) {
- int err = SSL_get_error(s->tls.openssl_conn, ret);
- s->tls.openssl_direction = REXMPP_OPENSSL_NONE;
+ int err = SSL_get_error(s->tls->openssl_conn, ret);
+ s->tls->openssl_direction = REXMPP_OPENSSL_NONE;
if (ret == 1) {
return REXMPP_TLS_SUCCESS;
} else if (err == SSL_ERROR_WANT_READ) {
- s->tls.openssl_direction = REXMPP_OPENSSL_READ;
+ s->tls->openssl_direction = REXMPP_OPENSSL_READ;
return REXMPP_TLS_E_AGAIN;
} else if (err == SSL_ERROR_WANT_WRITE) {
- s->tls.openssl_direction = REXMPP_OPENSSL_WRITE;
+ s->tls->openssl_direction = REXMPP_OPENSSL_WRITE;
return REXMPP_TLS_E_AGAIN;
} else {
rexmpp_log(s, LOG_ERR, "OpenSSL error %d", err);
@@ -43,27 +43,28 @@ rexmpp_tls_err_t rexmpp_process_openssl_ret (rexmpp_t *s, int ret) {
#endif
int rexmpp_tls_init (rexmpp_t *s) {
+ s->tls = malloc(sizeof(struct rexmpp_tls));
#if defined(USE_GNUTLS)
int err;
- s->tls.tls_session_data = NULL;
- s->tls.tls_session_data_size = 0;
+ s->tls->tls_session_data = NULL;
+ s->tls->tls_session_data_size = 0;
- err = gnutls_certificate_allocate_credentials(&(s->tls.gnutls_cred));
+ err = gnutls_certificate_allocate_credentials(&(s->tls->gnutls_cred));
if (err) {
rexmpp_log(s, LOG_CRIT, "gnutls credentials allocation error: %s",
gnutls_strerror(err));
return 1;
}
- err = gnutls_certificate_set_x509_system_trust(s->tls.gnutls_cred);
+ err = gnutls_certificate_set_x509_system_trust(s->tls->gnutls_cred);
if (err < 0) {
rexmpp_log(s, LOG_CRIT, "Certificates loading error: %s",
gnutls_strerror(err));
return 1;
}
#ifdef ENABLE_CALLS
- err = gnutls_certificate_allocate_credentials(&(s->jingle.dtls_cred));
+ err = gnutls_certificate_allocate_credentials(&(s->tls->dtls_cred));
if (err) {
- gnutls_certificate_free_credentials(s->tls.gnutls_cred);
+ gnutls_certificate_free_credentials(s->tls->gnutls_cred);
rexmpp_log(s, LOG_CRIT, "gnutls credentials allocation error: %s",
gnutls_strerror(err));
return 1;
@@ -73,23 +74,23 @@ int rexmpp_tls_init (rexmpp_t *s) {
#elif defined(USE_OPENSSL)
SSL_library_init();
SSL_load_error_strings();
- s->tls.openssl_direction = REXMPP_OPENSSL_NONE;
- s->tls.openssl_conn = NULL;
- s->tls.openssl_ctx = SSL_CTX_new(TLS_client_method());
- if (s->tls.openssl_ctx == NULL) {
+ s->tls->openssl_direction = REXMPP_OPENSSL_NONE;
+ s->tls->openssl_conn = NULL;
+ s->tls->openssl_ctx = SSL_CTX_new(TLS_client_method());
+ if (s->tls->openssl_ctx == NULL) {
rexmpp_log(s, LOG_CRIT, "OpenSSL context creation error");
return 1;
}
- SSL_CTX_set_verify(s->tls.openssl_ctx, SSL_VERIFY_PEER, NULL);
- if (SSL_CTX_set_default_verify_paths(s->tls.openssl_ctx) == 0) {
+ SSL_CTX_set_verify(s->tls->openssl_ctx, SSL_VERIFY_PEER, NULL);
+ if (SSL_CTX_set_default_verify_paths(s->tls->openssl_ctx) == 0) {
rexmpp_log(s, LOG_CRIT, "Failed to set default verify paths for OpenSSL context");
- SSL_CTX_free(s->tls.openssl_ctx);
- s->tls.openssl_ctx = NULL;
+ SSL_CTX_free(s->tls->openssl_ctx);
+ s->tls->openssl_ctx = NULL;
return 1;
}
return 0;
#else
- (void)s;
+ s->tls = NULL;
return 0;
#endif
}
@@ -99,13 +100,13 @@ void rexmpp_tls_cleanup (rexmpp_t *s) {
if (s->tls_state != REXMPP_TLS_INACTIVE &&
s->tls_state != REXMPP_TLS_AWAITING_DIRECT) {
#if defined(USE_GNUTLS)
- gnutls_deinit(s->tls.gnutls_session);
+ gnutls_deinit(s->tls->gnutls_session);
#elif defined(USE_OPENSSL)
- if (s->tls.openssl_conn != NULL) {
- SSL_free(s->tls.openssl_conn);
- s->tls.openssl_conn = NULL;
+ if (s->tls->openssl_conn != NULL) {
+ SSL_free(s->tls->openssl_conn);
+ s->tls->openssl_conn = NULL;
}
- s->tls.openssl_direction = REXMPP_OPENSSL_NONE;
+ s->tls->openssl_direction = REXMPP_OPENSSL_NONE;
#else
(void)s;
#endif
@@ -114,22 +115,24 @@ void rexmpp_tls_cleanup (rexmpp_t *s) {
void rexmpp_tls_deinit (rexmpp_t *s) {
#if defined(USE_GNUTLS)
- gnutls_certificate_free_credentials(s->tls.gnutls_cred);
- if (s->tls.tls_session_data != NULL) {
- free(s->tls.tls_session_data);
- s->tls.tls_session_data = NULL;
+ gnutls_certificate_free_credentials(s->tls->gnutls_cred);
+ if (s->tls->tls_session_data != NULL) {
+ free(s->tls->tls_session_data);
+ s->tls->tls_session_data = NULL;
}
#ifdef ENABLE_CALLS
- gnutls_certificate_free_credentials(s->jingle.dtls_cred);
+ gnutls_certificate_free_credentials(s->tls->dtls_cred);
#endif
#elif defined(USE_OPENSSL)
- if (s->tls.openssl_ctx != NULL) {
- SSL_CTX_free(s->tls.openssl_ctx);
+ if (s->tls->openssl_ctx != NULL) {
+ SSL_CTX_free(s->tls->openssl_ctx);
}
- s->tls.openssl_ctx = NULL;
-#else
- (void)s;
+ s->tls->openssl_ctx = NULL;
#endif
+ if (s->tls != NULL) {
+ free(s->tls);
+ s->tls = NULL;
+ }
}
rexmpp_tls_err_t
@@ -138,33 +141,33 @@ rexmpp_tls_connect (rexmpp_t *s) {
if (s->tls_state != REXMPP_TLS_HANDSHAKE) {
gnutls_datum_t xmpp_client_protocol = {"xmpp-client", strlen("xmpp-client")};
rexmpp_log(s, LOG_DEBUG, "starting TLS");
- gnutls_init(&s->tls.gnutls_session, GNUTLS_CLIENT);
- gnutls_session_set_ptr(s->tls.gnutls_session, s);
- gnutls_alpn_set_protocols(s->tls.gnutls_session, &xmpp_client_protocol, 1, 0);
- gnutls_server_name_set(s->tls.gnutls_session, GNUTLS_NAME_DNS,
+ gnutls_init(&s->tls->gnutls_session, GNUTLS_CLIENT);
+ gnutls_session_set_ptr(s->tls->gnutls_session, s);
+ gnutls_alpn_set_protocols(s->tls->gnutls_session, &xmpp_client_protocol, 1, 0);
+ gnutls_server_name_set(s->tls->gnutls_session, GNUTLS_NAME_DNS,
s->initial_jid.domain,
strlen(s->initial_jid.domain));
- gnutls_set_default_priority(s->tls.gnutls_session);
- gnutls_credentials_set(s->tls.gnutls_session, GNUTLS_CRD_CERTIFICATE,
- s->tls.gnutls_cred);
- gnutls_transport_set_int(s->tls.gnutls_session, s->server_socket);
- gnutls_handshake_set_timeout(s->tls.gnutls_session,
+ gnutls_set_default_priority(s->tls->gnutls_session);
+ gnutls_credentials_set(s->tls->gnutls_session, GNUTLS_CRD_CERTIFICATE,
+ s->tls->gnutls_cred);
+ gnutls_transport_set_int(s->tls->gnutls_session, s->server_socket);
+ gnutls_handshake_set_timeout(s->tls->gnutls_session,
GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
- if (s->tls.tls_session_data != NULL) {
- int ret = gnutls_session_set_data(s->tls.gnutls_session,
- s->tls.tls_session_data,
- s->tls.tls_session_data_size);
+ if (s->tls->tls_session_data != NULL) {
+ int ret = gnutls_session_set_data(s->tls->gnutls_session,
+ s->tls->tls_session_data,
+ s->tls->tls_session_data_size);
if (ret != GNUTLS_E_SUCCESS) {
rexmpp_log(s, LOG_WARNING, "Failed to set TLS session data: %s",
gnutls_strerror(ret));
- free(s->tls.tls_session_data);
- s->tls.tls_session_data = NULL;
- s->tls.tls_session_data_size = 0;
+ free(s->tls->tls_session_data);
+ s->tls->tls_session_data = NULL;
+ s->tls->tls_session_data_size = 0;
}
}
}
- int ret = gnutls_handshake(s->tls.gnutls_session);
+ int ret = gnutls_handshake(s->tls->gnutls_session);
if (ret == GNUTLS_E_AGAIN) {
rexmpp_log(s, LOG_DEBUG, "Waiting for TLS handshake to complete");
return REXMPP_TLS_E_AGAIN;
@@ -190,7 +193,7 @@ rexmpp_tls_connect (rexmpp_t *s) {
service/source host
(<https://tools.ietf.org/html/rfc7712#section-5.1>,
<https://tools.ietf.org/html/rfc7673#section-6>). */
- ret = dane_verify_session_crt(NULL, s->tls.gnutls_session, s->server_host,
+ ret = dane_verify_session_crt(NULL, s->tls->gnutls_session, s->server_host,
"tcp", s->server_port, 0, 0, &status);
if (ret) {
rexmpp_log(s, LOG_WARNING, "DANE verification error: %s",
@@ -212,7 +215,7 @@ rexmpp_tls_connect (rexmpp_t *s) {
}
}
- ret = gnutls_certificate_verify_peers3(s->tls.gnutls_session,
+ ret = gnutls_certificate_verify_peers3(s->tls->gnutls_session,
s->initial_jid.domain,
&status);
if (ret || status) {
@@ -224,23 +227,23 @@ rexmpp_tls_connect (rexmpp_t *s) {
} else {
rexmpp_log(s, LOG_ERR, "Untrusted certificate");
}
- gnutls_bye(s->tls.gnutls_session, GNUTLS_SHUT_RDWR);
+ gnutls_bye(s->tls->gnutls_session, GNUTLS_SHUT_RDWR);
return REXMPP_TLS_E_OTHER;
}
- if (gnutls_session_is_resumed(s->tls.gnutls_session)) {
+ if (gnutls_session_is_resumed(s->tls->gnutls_session)) {
rexmpp_log(s, LOG_INFO, "TLS session is resumed");
} else {
- if (s->tls.tls_session_data != NULL) {
+ if (s->tls->tls_session_data != NULL) {
rexmpp_log(s, LOG_DEBUG, "TLS session is not resumed");
- free(s->tls.tls_session_data);
- s->tls.tls_session_data = NULL;
+ free(s->tls->tls_session_data);
+ s->tls->tls_session_data = NULL;
}
- gnutls_session_get_data(s->tls.gnutls_session, NULL,
- &s->tls.tls_session_data_size);
- s->tls.tls_session_data = malloc(s->tls.tls_session_data_size);
- ret = gnutls_session_get_data(s->tls.gnutls_session, s->tls.tls_session_data,
- &s->tls.tls_session_data_size);
+ gnutls_session_get_data(s->tls->gnutls_session, NULL,
+ &s->tls->tls_session_data_size);
+ s->tls->tls_session_data = malloc(s->tls->tls_session_data_size);
+ ret = gnutls_session_get_data(s->tls->gnutls_session, s->tls->tls_session_data,
+ &s->tls->tls_session_data_size);
if (ret != GNUTLS_E_SUCCESS) {
rexmpp_log(s, LOG_ERR, "Failed to get TLS session data: %s",
gnutls_strerror(ret));
@@ -256,26 +259,26 @@ rexmpp_tls_connect (rexmpp_t *s) {
}
#elif defined(USE_OPENSSL)
if (s->tls_state != REXMPP_TLS_HANDSHAKE) {
- s->tls.openssl_conn = SSL_new(s->tls.openssl_ctx);
- if (s->tls.openssl_conn == NULL) {
+ s->tls->openssl_conn = SSL_new(s->tls->openssl_ctx);
+ if (s->tls->openssl_conn == NULL) {
rexmpp_log(s, LOG_ERR, "Failed to create an OpenSSL connection object");
return REXMPP_TLS_E_OTHER;
}
- if (SSL_set_fd(s->tls.openssl_conn, s->server_socket) == 0) {
+ if (SSL_set_fd(s->tls->openssl_conn, s->server_socket) == 0) {
rexmpp_log(s, LOG_ERR, "Failed to set a file descriptor for OpenSSL connection");
return REXMPP_TLS_E_OTHER;
}
- if (SSL_set1_host(s->tls.openssl_conn, s->initial_jid.domain) == 0) {
+ if (SSL_set1_host(s->tls->openssl_conn, s->initial_jid.domain) == 0) {
rexmpp_log(s, LOG_ERR, "Failed to set a hostname for OpenSSL connection");
return REXMPP_TLS_E_OTHER;
}
/* For SNI */
- if (SSL_set_tlsext_host_name(s->tls.openssl_conn, s->initial_jid.domain) == 0) {
+ if (SSL_set_tlsext_host_name(s->tls->openssl_conn, s->initial_jid.domain) == 0) {
rexmpp_log(s, LOG_ERR, "Failed to set a tlsext hostname for OpenSSL connection");
return REXMPP_TLS_E_OTHER;
}
}
- return rexmpp_process_openssl_ret(s, SSL_connect(s->tls.openssl_conn));
+ return rexmpp_process_openssl_ret(s, SSL_connect(s->tls->openssl_conn));
#else
rexmpp_log(s, LOG_ERR, "rexmpp is compiled without TLS support");
return REXMPP_TLS_E_OTHER;
@@ -285,7 +288,7 @@ rexmpp_tls_connect (rexmpp_t *s) {
rexmpp_tls_err_t
rexmpp_tls_disconnect (rexmpp_t *s) {
#if defined(USE_GNUTLS)
- int ret = gnutls_bye(s->tls.gnutls_session, GNUTLS_SHUT_RDWR);
+ int ret = gnutls_bye(s->tls->gnutls_session, GNUTLS_SHUT_RDWR);
if (ret == GNUTLS_E_SUCCESS) {
return REXMPP_TLS_SUCCESS;
} else {
@@ -294,9 +297,9 @@ rexmpp_tls_disconnect (rexmpp_t *s) {
return REXMPP_TLS_E_OTHER;
}
#elif defined(USE_OPENSSL)
- int ret = SSL_shutdown(s->tls.openssl_conn);
+ int ret = SSL_shutdown(s->tls->openssl_conn);
if (ret == 0) {
- s->tls.openssl_direction = REXMPP_OPENSSL_READ;
+ s->tls->openssl_direction = REXMPP_OPENSSL_READ;
return REXMPP_TLS_E_AGAIN;
} else {
return rexmpp_process_openssl_ret(s, ret);
@@ -312,7 +315,7 @@ rexmpp_tls_send (rexmpp_t *s, void *data, size_t data_size, ssize_t *written)
{
#if defined(USE_GNUTLS)
*written = -1;
- ssize_t ret = gnutls_record_send(s->tls.gnutls_session,
+ ssize_t ret = gnutls_record_send(s->tls->gnutls_session,
data,
data_size);
if (ret >= 0) {
@@ -326,7 +329,7 @@ rexmpp_tls_send (rexmpp_t *s, void *data, size_t data_size, ssize_t *written)
}
#elif defined(USE_OPENSSL)
*written = -1;
- int ret = SSL_write_ex(s->tls.openssl_conn, data, data_size, written);
+ int ret = SSL_write_ex(s->tls->openssl_conn, data, data_size, written);
if (ret > 0) {
return REXMPP_TLS_SUCCESS;
} else {
@@ -345,7 +348,7 @@ rexmpp_tls_err_t
rexmpp_tls_recv (rexmpp_t *s, void *data, size_t data_size, ssize_t *received) {
#if defined(USE_GNUTLS)
*received = -1;
- ssize_t ret = gnutls_record_recv(s->tls.gnutls_session, data, data_size);
+ ssize_t ret = gnutls_record_recv(s->tls->gnutls_session, data, data_size);
if (ret >= 0) {
*received = ret;
return REXMPP_TLS_SUCCESS;
@@ -357,7 +360,7 @@ rexmpp_tls_recv (rexmpp_t *s, void *data, size_t data_size, ssize_t *received) {
}
#elif defined(USE_OPENSSL)
*received = -1;
- int ret = SSL_read_ex(s->tls.openssl_conn, data, data_size, received);
+ int ret = SSL_read_ex(s->tls->openssl_conn, data, data_size, received);
if (ret > 0) {
return REXMPP_TLS_SUCCESS;
} else {
@@ -374,18 +377,18 @@ rexmpp_tls_recv (rexmpp_t *s, void *data, size_t data_size, ssize_t *received) {
int rexmpp_tls_fds (rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) {
#if defined(USE_GNUTLS)
- if (gnutls_record_get_direction(s->tls.gnutls_session) == 0) {
+ if (gnutls_record_get_direction(s->tls->gnutls_session) == 0) {
FD_SET(s->server_socket, read_fds);
} else {
FD_SET(s->server_socket, write_fds);
}
return s->server_socket + 1;
#elif defined(USE_OPENSSL)
- if (s->tls.openssl_direction == REXMPP_OPENSSL_READ) {
+ if (s->tls->openssl_direction == REXMPP_OPENSSL_READ) {
FD_SET(s->server_socket, read_fds);
return s->server_socket + 1;
}
- if (s->tls.openssl_direction == REXMPP_OPENSSL_WRITE) {
+ if (s->tls->openssl_direction == REXMPP_OPENSSL_WRITE) {
FD_SET(s->server_socket, write_fds);
return s->server_socket + 1;
}
@@ -404,12 +407,12 @@ rexmpp_tls_set_x509_key_file (rexmpp_t *s,
const char *key_file)
{
#if defined(USE_GNUTLS)
- int ret = gnutls_certificate_set_x509_key_file(s->tls.gnutls_cred,
+ int ret = gnutls_certificate_set_x509_key_file(s->tls->gnutls_cred,
cert_file,
key_file,
GNUTLS_X509_FMT_PEM);
#ifdef ENABLE_CALLS
- gnutls_certificate_set_x509_key_file(s->jingle.dtls_cred,
+ gnutls_certificate_set_x509_key_file(s->tls->dtls_cred,
cert_file,
key_file,
GNUTLS_X509_FMT_PEM);
@@ -422,13 +425,13 @@ rexmpp_tls_set_x509_key_file (rexmpp_t *s,
return REXMPP_TLS_E_OTHER;
}
#elif defined(USE_OPENSSL)
- if (SSL_CTX_use_certificate_file(s->tls.openssl_ctx,
+ if (SSL_CTX_use_certificate_file(s->tls->openssl_ctx,
cert_file,
SSL_FILETYPE_PEM) != 1) {
rexmpp_log(s, LOG_ERR, "Failed to set a certificate file");
return REXMPP_TLS_E_OTHER;
}
- if (SSL_CTX_use_PrivateKey_file(s->tls.openssl_ctx,
+ if (SSL_CTX_use_PrivateKey_file(s->tls->openssl_ctx,
key_file,
SSL_FILETYPE_PEM) != 1) {
rexmpp_log(s, LOG_ERR, "Failed to set a key file");
@@ -448,12 +451,12 @@ rexmpp_tls_set_x509_trust_file (rexmpp_t *s,
const char *cert_file)
{
#if defined(USE_GNUTLS)
- gnutls_certificate_set_x509_trust_file(s->tls.gnutls_cred,
+ gnutls_certificate_set_x509_trust_file(s->tls->gnutls_cred,
cert_file,
GNUTLS_X509_FMT_PEM);
return REXMPP_TLS_SUCCESS;
#elif defined(USE_OPENSSL)
- if (SSL_CTX_load_verify_locations(s->tls.openssl_ctx, cert_file, NULL) != 1) {
+ if (SSL_CTX_load_verify_locations(s->tls->openssl_ctx, cert_file, NULL) != 1) {
rexmpp_log(s, LOG_ERR, "Failed to set a trusted certificate file");
return REXMPP_TLS_E_OTHER;
}