]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
libtls: Created tls_session object tls-session
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 18 Jul 2019 11:20:35 +0000 (13:20 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 19 Jul 2019 09:10:37 +0000 (11:10 +0200)
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.h
src/libtls/Makefile.am
src/libtls/tls_session.c [new file with mode: 0644]
src/libtls/tls_session.h [new file with mode: 0644]

index 8e69de095960e7c9a9490d6c1ab6483b66a215dd..63961c9800c4ec727f8d4c5d9b667dffaa983094 100644 (file)
 #include <credentials/sets/mem_cred.h>
 #include <daemon.h>
 
-#include <tls_socket.h>
-
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <tls_session.h>
 
 #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,
        );
index db19bd5756e7f9f2e4db27e9075bc0912e69384f..0acb987b45237d4f7bda36f22c2ba5a04c291452 100644 (file)
@@ -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;
 
index 4f809ba1adfa495ba57d4dbbf93b3f64e7f0c350..8d1ff79d213ea7205e0c13ff3d7ef38daf0ed710 100644 (file)
 
 /**
  * @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 <library.h>
-#include <tls_socket.h>
+#include <tls_session.h>
 
 #include <libxml/parser.h>
 
@@ -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_ @}*/
index b6496363c0f028548790d85835a0f84fc5320093..d9427861bd14f8a0b89a5551dd17b8f4f998a6b8 100644 (file)
@@ -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 (file)
index 0000000..9886bc9
--- /dev/null
@@ -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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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 <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#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 (file)
index 0000000..ec4d4e5
--- /dev/null
@@ -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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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