From: Martin Willi Date: Mon, 25 Jan 2010 11:21:57 +0000 (+0000) Subject: Added TLS crypto helper, currently supports cipher suite selection X-Git-Tag: 4.5.0~658 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=536dbc00b94d73de59f6ecad16c90370efc95d63;p=thirdparty%2Fstrongswan.git Added TLS crypto helper, currently supports cipher suite selection --- diff --git a/src/charon/plugins/eap_tls/Makefile.am b/src/charon/plugins/eap_tls/Makefile.am index a69f8857c2..ff42d024da 100644 --- a/src/charon/plugins/eap_tls/Makefile.am +++ b/src/charon/plugins/eap_tls/Makefile.am @@ -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 diff --git a/src/charon/plugins/eap_tls/tls/tls.c b/src/charon/plugins/eap_tls/tls/tls.c index 9c11bc796c..9912393691 100644 --- a/src/charon/plugins/eap_tls/tls/tls.c +++ b/src/charon/plugins/eap_tls/tls/tls.c @@ -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" @@ -86,6 +87,11 @@ struct private_tls_t { */ tls_fragmentation_t *fragmentation; + /** + * TLS crypto helper context + */ + tls_crypto_t *crypto; + /** * TLS handshake protocol handler */ @@ -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 index 0000000000..10add151c2 --- /dev/null +++ b/src/charon/plugins/eap_tls/tls/tls_crypto.c @@ -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 . + * + * 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 index 0000000000..538ab1de00 --- /dev/null +++ b/src/charon/plugins/eap_tls/tls/tls_crypto.h @@ -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 . + * + * 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_ @}*/ diff --git a/src/charon/plugins/eap_tls/tls/tls_peer.c b/src/charon/plugins/eap_tls/tls/tls_peer.c index 3fc3d6a164..737f9b34d6 100644 --- a/src/charon/plugins/eap_tls/tls/tls_peer.c +++ b/src/charon/plugins/eap_tls/tls/tls_peer.c @@ -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; diff --git a/src/charon/plugins/eap_tls/tls/tls_peer.h b/src/charon/plugins/eap_tls/tls/tls_peer.h index 036e418949..cef792a0b8 100644 --- a/src/charon/plugins/eap_tls/tls/tls_peer.h +++ b/src/charon/plugins/eap_tls/tls/tls_peer.h @@ -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_ @}*/ diff --git a/src/charon/plugins/eap_tls/tls/tls_server.c b/src/charon/plugins/eap_tls/tls/tls_server.c index 63a1e00857..101be5c608 100644 --- a/src/charon/plugins/eap_tls/tls/tls_server.c +++ b/src/charon/plugins/eap_tls/tls/tls_server.c @@ -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; diff --git a/src/charon/plugins/eap_tls/tls/tls_server.h b/src/charon/plugins/eap_tls/tls/tls_server.h index 12b822bee1..7e83c31c78 100644 --- a/src/charon/plugins/eap_tls/tls/tls_server.h +++ b/src/charon/plugins/eap_tls/tls/tls_server.h @@ -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_ @}*/