Added TLS crypto helper, currently supports cipher suite selection
authorMartin Willi <martin@revosec.ch>
Mon, 25 Jan 2010 11:21:57 +0000 (11:21 +0000)
committerMartin Willi <martin@revosec.ch>
Tue, 3 Aug 2010 13:39:24 +0000 (15:39 +0200)
src/charon/plugins/eap_tls/Makefile.am
src/charon/plugins/eap_tls/tls/tls.c
src/charon/plugins/eap_tls/tls/tls_crypto.c [new file with mode: 0644]
src/charon/plugins/eap_tls/tls/tls_crypto.h [new file with mode: 0644]
src/charon/plugins/eap_tls/tls/tls_peer.c
src/charon/plugins/eap_tls/tls/tls_peer.h
src/charon/plugins/eap_tls/tls/tls_server.c
src/charon/plugins/eap_tls/tls/tls_server.h

index a69f885..ff42d02 100644 (file)
@@ -10,6 +10,7 @@ libstrongswan_eap_tls_la_SOURCES = eap_tls_plugin.h eap_tls_plugin.c \
        tls/tls_protection.h tls/tls_protection.c \
        tls/tls_compression.h tls/tls_compression.c \
        tls/tls_fragmentation.h tls/tls_fragmentation.c \
+       tls/tls_crypto.h tls/tls_crypto.c \
        tls/tls_peer.h tls/tls_peer.c \
        tls/tls_server.h tls/tls_server.c \
        tls/tls_handshake.h
index 9c11bc7..9912393 100644 (file)
@@ -18,6 +18,7 @@
 #include "tls_protection.h"
 #include "tls_compression.h"
 #include "tls_fragmentation.h"
+#include "tls_crypto.h"
 #include "tls_server.h"
 #include "tls_peer.h"
 
@@ -87,6 +88,11 @@ struct private_tls_t {
        tls_fragmentation_t *fragmentation;
 
        /**
+        * TLS crypto helper context
+        */
+       tls_crypto_t *crypto;
+
+       /**
         * TLS handshake protocol handler
         */
        tls_handshake_t *handshake;
@@ -110,6 +116,7 @@ METHOD(tls_t, destroy, void,
        this->protection->destroy(this->protection);
        this->compression->destroy(this->compression);
        this->fragmentation->destroy(this->fragmentation);
+       this->crypto->destroy(this->crypto);
        this->handshake->destroy(this->handshake);
 
        free(this);
@@ -129,15 +136,16 @@ tls_t *tls_create(bool is_server)
                        .destroy = _destroy,
                },
                .is_server = is_server,
+               .crypto = tls_crypto_create(),
        );
 
        if (is_server)
        {
-               this->handshake = &tls_server_create()->handshake;
+               this->handshake = &tls_server_create(this->crypto)->handshake;
        }
        else
        {
-               this->handshake = &tls_peer_create()->handshake;
+               this->handshake = &tls_peer_create(this->crypto)->handshake;
        }
        this->fragmentation = tls_fragmentation_create(this->handshake);
        this->compression = tls_compression_create(this->fragmentation);
diff --git a/src/charon/plugins/eap_tls/tls/tls_crypto.c b/src/charon/plugins/eap_tls/tls/tls_crypto.c
new file mode 100644 (file)
index 0000000..10add15
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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_crypto.h"
+
+typedef struct private_tls_crypto_t private_tls_crypto_t;
+
+/**
+ * Private data of an tls_crypto_t object.
+ */
+struct private_tls_crypto_t {
+
+       /**
+        * Public tls_crypto_t interface.
+        */
+       tls_crypto_t public;
+};
+
+METHOD(tls_crypto_t, get_cipher_suites, int,
+       private_tls_crypto_t *this, tls_cipher_suite_t **suites)
+{
+       encryption_algorithm_t encr;
+       integrity_algorithm_t mac;
+       enumerator_t *encrs, *macs;
+       tls_cipher_suite_t buf[64];
+       int count = 0, i, j, res = 0;
+
+       /* we assume that we support RSA, but no DHE yet */
+       macs = lib->crypto->create_signer_enumerator(lib->crypto);
+       while (macs->enumerate(macs, &mac))
+       {
+               switch (mac)
+               {
+                       case AUTH_HMAC_SHA1_160:
+                               buf[count++] = TLS_RSA_WITH_NULL_SHA;
+                               break;
+                       case AUTH_HMAC_SHA2_256_256:
+                               buf[count++] = TLS_RSA_WITH_NULL_SHA256;
+                               break;
+                       case AUTH_HMAC_MD5_128:
+                               buf[count++] = TLS_RSA_WITH_NULL_MD5;
+                               break;
+                       default:
+                               break;
+               }
+               encrs = lib->crypto->create_crypter_enumerator(lib->crypto);
+               while (encrs->enumerate(encrs, &encr))
+               {
+                       switch (encr)
+                       {
+                               case ENCR_AES_CBC:
+                                       switch (mac)
+                                       {
+                                               case AUTH_HMAC_SHA1_160:
+                                                       buf[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
+                                                       buf[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
+                                                       break;
+                                               case AUTH_HMAC_SHA2_256_256:
+                                                       buf[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
+                                                       buf[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
+                                                       break;
+                                               default:
+                                                       break;
+                                       }
+                                       break;
+                               case ENCR_3DES:
+                                       switch (mac)
+                                       {
+                                               case AUTH_HMAC_SHA1_160:
+                                                       buf[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
+                                                       break;
+                                               default:
+                                                       break;
+                                       }
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+               encrs->destroy(encrs);
+       }
+       macs->destroy(macs);
+
+       /* remove duplicates */
+       *suites = malloc(sizeof(tls_cipher_suite_t) * count);
+       for (i = 0; i < count; i++)
+       {
+               bool match = FALSE;
+
+               for (j = 0; j < res; j++)
+               {
+                       if (buf[i] == (*suites)[j])
+                       {
+                               match = TRUE;
+                               break;
+                       }
+               }
+               if (!match)
+               {
+                       (*suites)[res++] = buf[i];
+               }
+       }
+       return res;
+}
+
+
+METHOD(tls_crypto_t, destroy, void,
+       private_tls_crypto_t *this)
+{
+       free(this);
+}
+
+/**
+ * See header
+ */
+tls_crypto_t *tls_crypto_create()
+{
+       private_tls_crypto_t *this;
+
+       INIT(this,
+               .public = {
+                       .get_cipher_suites = _get_cipher_suites,
+                       .destroy = _destroy,
+               },
+       );
+
+       return &this->public;
+}
diff --git a/src/charon/plugins/eap_tls/tls/tls_crypto.h b/src/charon/plugins/eap_tls/tls/tls_crypto.h
new file mode 100644 (file)
index 0000000..538ab1d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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_crypto tls_crypto
+ * @{ @ingroup tls
+ */
+
+#ifndef TLS_CRYPTO_H_
+#define TLS_CRYPTO_H_
+
+typedef struct tls_crypto_t tls_crypto_t;
+
+#include "tls.h"
+
+/**
+ * TLS crypto helper functions.
+ */
+struct tls_crypto_t {
+
+       /**
+        * Get a list of supported TLS cipher suites.
+        *
+        * @param suites                allocated list of suites
+        * @return                              number of suites returned
+        */
+       int (*get_cipher_suites)(tls_crypto_t *this, tls_cipher_suite_t **suites);
+
+       /**
+        * Destroy a tls_crypto_t.
+        */
+       void (*destroy)(tls_crypto_t *this);
+};
+
+/**
+ * Create a tls_crypto instance.
+ */
+tls_crypto_t *tls_crypto_create();
+
+#endif /** TLS_CRYPTO_H_ @}*/
index 3fc3d6a..737f9b3 100644 (file)
@@ -30,6 +30,11 @@ struct private_tls_peer_t {
         * Public tls_peer_t interface.
         */
        tls_peer_t public;
+
+       /**
+        * TLS crypto context
+        */
+       tls_crypto_t *crypto;
 };
 
 METHOD(tls_handshake_t, process, status_t,
@@ -53,7 +58,7 @@ METHOD(tls_handshake_t, destroy, void,
 /**
  * See header
  */
-tls_peer_t *tls_peer_create()
+tls_peer_t *tls_peer_create(tls_crypto_t *crypto)
 {
        private_tls_peer_t *this;
 
@@ -63,6 +68,7 @@ tls_peer_t *tls_peer_create()
                        .build = _build,
                        .destroy = _destroy,
                },
+               .crypto = crypto,
        );
 
        return &this->public;
index 036e418..cef792a 100644 (file)
@@ -24,6 +24,7 @@
 typedef struct tls_peer_t tls_peer_t;
 
 #include "tls_handshake.h"
+#include "tls_crypto.h"
 
 /**
  * TLS handshake protocol handler as peer.
@@ -39,6 +40,6 @@ struct tls_peer_t {
 /**
  * Create a tls_peer instance.
  */
-tls_peer_t *tls_peer_create();
+tls_peer_t *tls_peer_create(tls_crypto_t *crypto);
 
 #endif /** TLS_PEER_H_ @}*/
index 63a1e00..101be5c 100644 (file)
@@ -28,6 +28,11 @@ struct private_tls_server_t {
         * Public tls_server_t interface.
         */
        tls_server_t public;
+
+       /**
+        * TLS crypto context
+        */
+       tls_crypto_t *crypto;
 };
 
 
@@ -52,7 +57,7 @@ METHOD(tls_handshake_t, destroy, void,
 /**
  * See header
  */
-tls_server_t *tls_server_create()
+tls_server_t *tls_server_create(tls_crypto_t *crypto)
 {
        private_tls_server_t *this;
 
@@ -62,6 +67,7 @@ tls_server_t *tls_server_create()
                        .build = _build,
                        .destroy = _destroy,
                },
+               .crypto = crypto,
        );
 
        return &this->public;
index 12b822b..7e83c31 100644 (file)
@@ -24,6 +24,7 @@
 typedef struct tls_server_t tls_server_t;
 
 #include "tls_handshake.h"
+#include "tls_crypto.h"
 
 /**
  * TLS handshake protocol handler as peer.
@@ -39,6 +40,6 @@ struct tls_server_t {
 /**
  * Create a tls_server instance.
  */
-tls_server_t *tls_server_create();
+tls_server_t *tls_server_create(tls_crypto_t *crypto);
 
 #endif /** TLS_SERVER_H_ @}*/