From: Andreas Steffen Date: Thu, 18 Jul 2019 11:20:35 +0000 (+0200) Subject: libtls: Created tls_session object X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f9b37f00cd137c72cc6a498c2ba1eb6e6abbb35;p=thirdparty%2Fstrongswan.git libtls: Created tls_session object --- diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c index 8e69de0959..63961c9800 100644 --- a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c @@ -20,17 +20,11 @@ #include #include -#include - -#include -#include -#include -#include +#include #define IFMAP_NS "http://www.trustedcomputinggroup.org/2010/IFMAP/2" #define IFMAP_META_NS "http://www.trustedcomputinggroup.org/2010/IFMAP-METADATA/2" #define IFMAP_URI "https://localhost:8444/imap" -#define IFMAP_NO_FD -1 typedef struct private_tnc_ifmap_soap_t private_tnc_ifmap_soap_t; @@ -80,19 +74,9 @@ struct private_tnc_ifmap_soap_t { chunk_t user_pass; /** - * IF-MAP Server (IP address and port) - */ - host_t *host; - - /** - * TLS socket + * TLS session */ - tls_socket_t *tls; - - /** - * File descriptor for secure TCP socket - */ - int fd; + tls_session_t *tls; /** * In memory credential set @@ -706,12 +690,7 @@ METHOD(tnc_ifmap_soap_t, destroy, void, free(this->device_name); } DESTROY_IF(this->tls); - DESTROY_IF(this->host); - if (this->fd != IFMAP_NO_FD) - { - close(this->fd); - } lib->credmgr->remove_set(lib->credmgr, &this->creds->set); this->creds->destroy(this->creds); free(this->user_pass.ptr); @@ -728,6 +707,7 @@ static bool soap_init(private_tnc_ifmap_soap_t *this) certificate_t *cert; private_key_t *key; identification_t *server_id, *client_id = NULL; + host_t *host; /* getting configuration parameters from strongswan.conf */ server_uri = lib->settings->get_str(lib->settings, @@ -850,37 +830,23 @@ static bool soap_init(private_tnc_ifmap_soap_t *this) } } - /* open TCP socket and connect to MAP server */ - this->host = host_create_from_dns(server_str, 0, port); - if (!this->host) - { - DBG1(DBG_TNC, "resolving hostname %s failed", server_str); - free(server_str); - return FALSE; - } + /* resolve server hostname */ + host = host_create_from_dns(server_str, 0, port); free(server_str); - this->fd = socket(this->host->get_family(this->host), SOCK_STREAM, 0); - if (this->fd == IFMAP_NO_FD) + if (!host) { - DBG1(DBG_TNC, "opening socket failed: %s", strerror(errno)); + DBG1(DBG_TLS, "resolving server hostname %s failed", server_str); return FALSE; } - if (connect(this->fd, this->host->get_sockaddr(this->host), - *this->host->get_sockaddr_len(this->host)) == -1) - { - DBG1(DBG_TNC, "connecting to %#H failed: %s", - this->host, strerror(errno)); - return FALSE; - } + /* create TLS session */ + this->tls = tls_session_create(host, server_id, client_id, TLS_1_2); + host->destroy(host); - /* open TLS socket */ - this->tls = tls_socket_create(FALSE, server_id, client_id, this->fd, - NULL, TLS_1_2, FALSE); if (!this->tls) { - DBG1(DBG_TNC, "creating TLS socket failed"); + DBG1(DBG_TNC, "creating TLS session failed"); return FALSE; } @@ -909,7 +875,6 @@ tnc_ifmap_soap_t *tnc_ifmap_soap_create() .get_ref = _get_ref, .destroy = _destroy, }, - .fd = IFMAP_NO_FD, .creds = mem_cred_create(), .ref = 1, ); diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c index db19bd5756..0acb987b45 100644 --- a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c @@ -38,9 +38,9 @@ struct private_tnc_ifmap_soap_msg_t { tnc_ifmap_http_t *http; /** - * TLS socket + * TLS session */ - tls_socket_t *tls; + tls_session_t *tls; /** * XML Document @@ -78,7 +78,8 @@ METHOD(tnc_ifmap_soap_msg_t, post, bool, xmlNodePtr env, body, cur, response; xmlNsPtr ns; xmlChar *xml_str, *errorCode, *errorString; - int xml_len, len, written; + int xml_len, len; + bool success; chunk_t xml, http; char buf[4096] = { 0 }; status_t status; @@ -111,9 +112,9 @@ METHOD(tnc_ifmap_soap_msg_t, post, bool, { break; } - written = this->tls->write(this->tls, http.ptr, http.len); + success = this->tls->write(this->tls, http.ptr, http.len); free(http.ptr); - if (written != http.len) + if (!success) { status = FAILED; break; @@ -132,7 +133,7 @@ METHOD(tnc_ifmap_soap_msg_t, post, bool, do { /* reduce size so the buffer is null-terminated */ - len = this->tls->read(this->tls, buf, sizeof(buf)-1, TRUE); + len = this->tls->read(this->tls, buf, sizeof(buf)-1); if (len <= 0) { return FALSE; @@ -239,7 +240,7 @@ METHOD(tnc_ifmap_soap_msg_t, destroy, void, * See header */ tnc_ifmap_soap_msg_t *tnc_ifmap_soap_msg_create(char *uri, chunk_t user_pass, - tls_socket_t *tls) + tls_session_t *tls) { private_tnc_ifmap_soap_msg_t *this; diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.h index 4f809ba1ad..8d1ff79d21 100644 --- a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.h +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.h @@ -15,14 +15,14 @@ /** * @defgroup tnc_ifmap_soap_msg tnc_ifmap_soap_msg - * @{ @ingroup tnc_ifmap + * @{ @ingroup tnc_ifmap */ #ifndef TNC_IFMAP_SOAP_MSG_H_ #define TNC_IFMAP_SOAP_MSG_H_ #include -#include +#include #include @@ -54,9 +54,9 @@ struct tnc_ifmap_soap_msg_t { * * @param uri HTTPS URI with https:// prefix removed * @param user_pass Optional username:password for HTTP Basic Authentication - * @param tls TLS socket protecting the SOAP message + * @param tls TLS session protecting the SOAP message */ tnc_ifmap_soap_msg_t *tnc_ifmap_soap_msg_create(char *uri, chunk_t user_pass, - tls_socket_t *tls); + tls_session_t *tls); #endif /** TNC_IFMAP_SOAP_MSG_H_ @}*/ diff --git a/src/libtls/Makefile.am b/src/libtls/Makefile.am index b6496363c0..d9427861bd 100644 --- a/src/libtls/Makefile.am +++ b/src/libtls/Makefile.am @@ -9,7 +9,7 @@ libtls_la_SOURCES = \ tls_protection.c tls_compression.c tls_fragmentation.c tls_alert.c \ tls_crypto.c tls_prf.c tls_socket.c tls_eap.c tls_cache.c tls_peer.c \ tls_aead_expl.c tls_aead_impl.c tls_aead_null.c tls_aead.c \ - tls_server.c tls.c + tls_server.c tls_session.c tls.c libtls_la_LIBADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la @@ -23,7 +23,7 @@ tls_includedir = ${dev_headers}/tls nobase_tls_include_HEADERS = \ tls_protection.h tls_compression.h tls_fragmentation.h tls_alert.h \ tls_crypto.h tls_prf.h tls_socket.h tls_eap.h tls_cache.h tls_peer.h \ - tls_server.h tls_handshake.h tls_application.h tls_aead.h tls.h + tls_server.h tls_session.h tls_handshake.h tls_application.h tls_aead.h tls.h endif SUBDIRS = . tests diff --git a/src/libtls/tls_session.c b/src/libtls/tls_session.c new file mode 100644 index 0000000000..9886bc9d46 --- /dev/null +++ b/src/libtls/tls_session.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2019 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program 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 General Public License + * for more details. + */ + +#include "tls_session.h" +#include "tls_socket.h" + +#include +#include +#include +#include + +#define TLS_SESSION_NO_FD -1 + +typedef struct private_tls_session_t private_tls_session_t; + +/** + * Private data of an tls_session_t object. + */ +struct private_tls_session_t { + + /** + * Public tls_session_t interface. + */ + tls_session_t public; + + /** + * TLS socket + */ + tls_socket_t *tls; + + /** + * Underlying OS socket + */ + int fd; +}; + +METHOD(tls_session_t, read_, ssize_t, + private_tls_session_t *this, void *buf, size_t len) +{ + return this->tls->read(this->tls, buf, len, TRUE); +} + +METHOD(tls_session_t, write_, bool, + private_tls_session_t *this, void *buf, size_t len) +{ + return this->tls->write(this->tls, buf, len) != len; +} + +METHOD(tls_session_t, destroy, void, + private_tls_session_t *this) +{ + DESTROY_IF(this->tls); + + if (this->fd != TLS_SESSION_NO_FD) + { + close(this->fd); + } + free(this); +} + +/** + * See header + */ +tls_session_t *tls_session_create(host_t *host, identification_t *server_id, + identification_t *client_id, + tls_version_t max_version) +{ + private_tls_session_t *this; + + INIT(this, + .public = { + .read = _read_, + .write = _write_, + .destroy = _destroy, + }, + .fd = TLS_SESSION_NO_FD, + ); + + /* open TCP socket */ + this->fd = socket(host->get_family(host), SOCK_STREAM, 0); + if (this->fd == TLS_SESSION_NO_FD) + { + DBG1(DBG_TLS, "opening socket failed: %s", strerror(errno)); + destroy(this); + return NULL; + } + + if (connect(this->fd, host->get_sockaddr(host), + *host->get_sockaddr_len(host)) == -1) + { + DBG1(DBG_TLS, "connecting to %#H failed: %s", host, strerror(errno)); + destroy(this); + return NULL; + } + + this->tls = tls_socket_create(FALSE, server_id, client_id, this->fd, + NULL, max_version, FALSE); + if (!this->tls) + { + DBG1(DBG_TLS, "creating TLS socket failed"); + destroy(this); + return NULL; + } + + return &this->public; +} diff --git a/src/libtls/tls_session.h b/src/libtls/tls_session.h new file mode 100644 index 0000000000..ec4d4e54a9 --- /dev/null +++ b/src/libtls/tls_session.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program 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 General Public License + * for more details. + */ + +/** + * @defgroup tls_session tls_session + * @{ @ingroup libtls + */ + +#ifndef TLS_SESSION_H_ +#define TLS_SESSION_H_ + +#include "tls.h" + +typedef struct tls_session_t tls_session_t; + +/** + * TLS client session object + */ +struct tls_session_t { + + /** + * Read data from TLS session. + * + * @param buf buffer to write received data to + * @param len size of buffer + * @return number of bytes read, 0 on EOF, -1 on error + */ + ssize_t (*read)(tls_session_t *this, void *buf, size_t len); + + /** + * Write data to a TLS session + * + * @param buf data to send + * @param len number of bytes to write from buf + * @return TRUE if all bytes have been written + */ + bool (*write)(tls_session_t *this, void *buf, size_t len); + + /** + * Destroy a tls_session_t. + */ + void (*destroy)(tls_session_t *this); +}; + + +/** + * Create a tls_session instance. + * + * @param host_t server IP address and TCP port + * @param server_id server identity + * @param client_id client identity, NULL for no client authentication + * @param max_version maximum TLS version to negotiate + * @return TLS client session + */ +tls_session_t *tls_session_create(host_t *host, identification_t *server_id, + identification_t *client_id, + tls_version_t max_version); + +#endif /** TLS_SESSION_H_ @}*/ \ No newline at end of file