Introducing simple purposes for the TLS stack, switches various options
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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_ @}*/
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_ @}*/
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_ @}*/
|
||||||
|
|||||||
Reference in New Issue
Block a user