Introducing simple purposes for the TLS stack, switches various options

This commit is contained in:
Martin Willi
2010-08-20 15:09:08 +02:00
parent 6291fbedcb
commit 96b2fbcc2c
9 changed files with 113 additions and 30 deletions
+6 -3
View File
@@ -441,10 +441,13 @@ static eap_tls_t *eap_tls_create(identification_t *server,
}, },
.is_server = is_server, .is_server = is_server,
); );
/* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */
this->tls = tls_create(is_server, server, peer, TRUE,
"client EAP encryption", NULL);
this->tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TLS, NULL);
if (!this->tls)
{
free(this);
return NULL;
}
return &this->public; return &this->public;
} }
+9 -3
View File
@@ -450,9 +450,15 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
}, },
.is_server = is_server, .is_server = is_server,
); );
/* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
this->tls = tls_create(is_server, server, peer, FALSE, this->tls = tls_create(is_server, server, peer,
"ttls keying material", application); TLS_PURPOSE_EAP_TTLS, application);
if (!this->tls)
{
application->destroy(application);
free(this);
return NULL;
}
return &this->public; return &this->public;
} }
+27 -6
View File
@@ -86,6 +86,11 @@ struct private_tls_t {
*/ */
tls_version_t version; tls_version_t version;
/**
* TLS stack purpose, as given to constructor
*/
tls_purpose_t purpose;
/** /**
* TLS record protection layer * TLS record protection layer
*/ */
@@ -147,6 +152,12 @@ METHOD(tls_t, set_version, void,
this->version = version; this->version = version;
} }
METHOD(tls_t, get_purpose, tls_purpose_t,
private_tls_t *this)
{
return this->purpose;
}
METHOD(tls_t, is_complete, bool, METHOD(tls_t, is_complete, bool,
private_tls_t *this) private_tls_t *this)
{ {
@@ -178,11 +189,20 @@ METHOD(tls_t, destroy, void,
* See header * See header
*/ */
tls_t *tls_create(bool is_server, identification_t *server, tls_t *tls_create(bool is_server, identification_t *server,
identification_t *peer, bool request_peer_auth, identification_t *peer, tls_purpose_t purpose,
char *msk_label, tls_application_t *application) tls_application_t *application)
{ {
private_tls_t *this; private_tls_t *this;
switch (purpose)
{
case TLS_PURPOSE_EAP_TLS:
case TLS_PURPOSE_EAP_TTLS:
break;
default:
return NULL;
}
INIT(this, INIT(this,
.public = { .public = {
.process = _process, .process = _process,
@@ -190,6 +210,7 @@ tls_t *tls_create(bool is_server, identification_t *server,
.is_server = _is_server, .is_server = _is_server,
.get_version = _get_version, .get_version = _get_version,
.set_version = _set_version, .set_version = _set_version,
.get_purpose = _get_purpose,
.is_complete = _is_complete, .is_complete = _is_complete,
.get_eap_msk = _get_eap_msk, .get_eap_msk = _get_eap_msk,
.destroy = _destroy, .destroy = _destroy,
@@ -199,19 +220,19 @@ tls_t *tls_create(bool is_server, identification_t *server,
.server = server->clone(server), .server = server->clone(server),
.peer = peer->clone(peer), .peer = peer->clone(peer),
.application = application, .application = application,
.purpose = purpose,
); );
this->crypto = tls_crypto_create(&this->public, msk_label); this->crypto = tls_crypto_create(&this->public);
if (is_server) if (is_server)
{ {
this->handshake = &tls_server_create(&this->public, this->crypto, this->handshake = &tls_server_create(&this->public, this->crypto,
this->server, this->peer, this->server, this->peer)->handshake;
request_peer_auth)->handshake;
} }
else else
{ {
this->handshake = &tls_peer_create(&this->public, this->crypto, this->handshake = &tls_peer_create(&this->public, this->crypto,
this->peer, this->server)->handshake; this->peer, this->server)->handshake;
} }
this->fragmentation = tls_fragmentation_create(this->handshake, this->fragmentation = tls_fragmentation_create(this->handshake,
this->application); this->application);
+21 -4
View File
@@ -29,6 +29,7 @@
typedef enum tls_version_t tls_version_t; typedef enum tls_version_t tls_version_t;
typedef enum tls_content_type_t tls_content_type_t; typedef enum tls_content_type_t tls_content_type_t;
typedef enum tls_handshake_type_t tls_handshake_type_t; typedef enum tls_handshake_type_t tls_handshake_type_t;
typedef enum tls_purpose_t tls_purpose_t;
typedef struct tls_t tls_t; typedef struct tls_t tls_t;
#include <library.h> #include <library.h>
@@ -87,6 +88,16 @@ enum tls_handshake_type_t {
*/ */
extern enum_name_t *tls_handshake_type_names; extern enum_name_t *tls_handshake_type_names;
/**
* Purpose the TLS stack is initiated for.
*/
enum tls_purpose_t {
/** authentication in EAP-TLS */
TLS_PURPOSE_EAP_TLS,
/** outer authentication and protection in EAP-TTLS */
TLS_PURPOSE_EAP_TTLS,
};
/** /**
* A bottom-up driven TLS stack, suitable for EAP implementations. * A bottom-up driven TLS stack, suitable for EAP implementations.
*/ */
@@ -138,6 +149,13 @@ struct tls_t {
*/ */
void (*set_version)(tls_t *this, tls_version_t version); void (*set_version)(tls_t *this, tls_version_t version);
/**
* Get the purpose of this TLS stack instance.
*
* @return purpose given during construction
*/
tls_purpose_t (*get_purpose)(tls_t *this);
/** /**
* Check if TLS negotiation completed successfully. * Check if TLS negotiation completed successfully.
* *
@@ -164,13 +182,12 @@ struct tls_t {
* @param is_server TRUE to act as server, FALSE for client * @param is_server TRUE to act as server, FALSE for client
* @param server server identity * @param server server identity
* @param peer peer identity * @param peer peer identity
* @param request_peer_auth TRUE to request certificate-based peer authentication * @param purpse purpose this TLS stack instance is used for
* @param msk_label ASCII string constant used as seed for MSK PRF
* @param application higher layer application or NULL if none * @param application higher layer application or NULL if none
* @return TLS stack * @return TLS stack
*/ */
tls_t *tls_create(bool is_server, identification_t *server, tls_t *tls_create(bool is_server, identification_t *server,
identification_t *peer, bool request_peer_auth, identification_t *peer, tls_purpose_t purpose,
char *msk_label, tls_application_t *application); tls_application_t *application);
#endif /** TLS_H_ @}*/ #endif /** TLS_H_ @}*/
-1
View File
@@ -23,7 +23,6 @@
typedef struct tls_application_t tls_application_t; typedef struct tls_application_t tls_application_t;
#include "tls.h"
#include "tls_reader.h" #include "tls_reader.h"
#include "tls_writer.h" #include "tls_writer.h"
+39 -5
View File
@@ -439,10 +439,30 @@ static void filter_suite(private_tls_crypto_t *this,
*count = remaining; *count = remaining;
} }
/**
* Purge NULL encryption cipher suites from list
*/
static void filter_null_suites(private_tls_crypto_t *this,
suite_algs_t suites[], int *count)
{
int i, remaining = 0;
for (i = 0; i < *count; i++)
{
if (suites[i].encr != ENCR_NULL)
{
suites[remaining] = suites[i];
remaining++;
}
}
*count = remaining;
}
/** /**
* Initialize the cipher suite list * Initialize the cipher suite list
*/ */
static void build_cipher_suite_list(private_tls_crypto_t *this) static void build_cipher_suite_list(private_tls_crypto_t *this,
bool require_encryption)
{ {
suite_algs_t suites[countof(suite_algs)]; suite_algs_t suites[countof(suite_algs)];
int count = countof(suite_algs), i; int count = countof(suite_algs), i;
@@ -452,6 +472,10 @@ static void build_cipher_suite_list(private_tls_crypto_t *this)
{ {
suites[i] = suite_algs[i]; suites[i] = suite_algs[i];
} }
if (require_encryption)
{
filter_null_suites(this, suites, &count);
}
/* filter suite list by each algorithm */ /* filter suite list by each algorithm */
filter_suite(this, suites, &count, offsetof(suite_algs_t, encr), filter_suite(this, suites, &count, offsetof(suite_algs_t, encr),
lib->crypto->create_crypter_enumerator); lib->crypto->create_crypter_enumerator);
@@ -872,7 +896,7 @@ METHOD(tls_crypto_t, destroy, void,
/** /**
* See header * See header
*/ */
tls_crypto_t *tls_crypto_create(tls_t *tls, char *msk_label) tls_crypto_t *tls_crypto_create(tls_t *tls)
{ {
private_tls_crypto_t *this; private_tls_crypto_t *this;
@@ -892,10 +916,20 @@ tls_crypto_t *tls_crypto_create(tls_t *tls, char *msk_label)
.destroy = _destroy, .destroy = _destroy,
}, },
.tls = tls, .tls = tls,
.msk_label = msk_label
); );
build_cipher_suite_list(this); switch (tls->get_purpose(tls))
{
case TLS_PURPOSE_EAP_TLS:
/* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */
this->msk_label = "client EAP encryption";
build_cipher_suite_list(this, FALSE);
break;
case TLS_PURPOSE_EAP_TTLS:
/* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
this->msk_label = "ttls keying material";
build_cipher_suite_list(this, TRUE);
break;
}
return &this->public; return &this->public;
} }
+1 -3
View File
@@ -359,9 +359,7 @@ struct tls_crypto_t {
/** /**
* Create a tls_crypto instance. * Create a tls_crypto instance.
*
* @param msk_label ASCII string constant used as seed for MSK PRF
*/ */
tls_crypto_t *tls_crypto_create(tls_t *tls, char *msk_label); tls_crypto_t *tls_crypto_create(tls_t *tls);
#endif /** TLS_CRYPTO_H_ @}*/ #endif /** TLS_CRYPTO_H_ @}*/
+9 -3
View File
@@ -629,8 +629,7 @@ METHOD(tls_handshake_t, destroy, void,
* See header * See header
*/ */
tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto, tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto,
identification_t *server, identification_t *peer, identification_t *server, identification_t *peer)
bool request_peer_auth)
{ {
private_tls_server_t *this; private_tls_server_t *this;
@@ -650,10 +649,17 @@ tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto,
.server = server, .server = server,
.peer = peer, .peer = peer,
.state = STATE_INIT, .state = STATE_INIT,
.request_peer_auth = request_peer_auth,
.peer_auth = auth_cfg_create(), .peer_auth = auth_cfg_create(),
.server_auth = auth_cfg_create(), .server_auth = auth_cfg_create(),
); );
switch (tls->get_purpose(tls))
{
case TLS_PURPOSE_EAP_TLS:
this->request_peer_auth = TRUE;
break;
case TLS_PURPOSE_EAP_TTLS:
break;
}
return &this->public; return &this->public;
} }
+1 -2
View File
@@ -43,7 +43,6 @@ struct tls_server_t {
* Create a tls_server instance. * Create a tls_server instance.
*/ */
tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto, tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto,
identification_t *server, identification_t *peer, identification_t *server, identification_t *peer);
bool request_peer_auth);
#endif /** TLS_SERVER_H_ @}*/ #endif /** TLS_SERVER_H_ @}*/