Pass NULL peer identity to omit TLS peer authentication, added eap-ttls.request_peer_auth option
This commit is contained in:
@@ -405,6 +405,11 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
|
|||||||
.is_server = is_server,
|
.is_server = is_server,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (is_server && !lib->settings->get_bool(lib->settings,
|
||||||
|
"charon.plugins.eap-ttls.request_peer_auth", FALSE))
|
||||||
|
{ /* don't request peer authentication */
|
||||||
|
peer = NULL;
|
||||||
|
}
|
||||||
this->tls = tls_create(is_server, server, peer,
|
this->tls = tls_create(is_server, server, peer,
|
||||||
TLS_PURPOSE_EAP_TTLS, application);
|
TLS_PURPOSE_EAP_TTLS, application);
|
||||||
if (!this->tls)
|
if (!this->tls)
|
||||||
|
|||||||
+2
-2
@@ -268,7 +268,7 @@ METHOD(tls_t, destroy, void,
|
|||||||
this->fragmentation->destroy(this->fragmentation);
|
this->fragmentation->destroy(this->fragmentation);
|
||||||
this->crypto->destroy(this->crypto);
|
this->crypto->destroy(this->crypto);
|
||||||
this->handshake->destroy(this->handshake);
|
this->handshake->destroy(this->handshake);
|
||||||
this->peer->destroy(this->peer);
|
DESTROY_IF(this->peer);
|
||||||
this->server->destroy(this->server);
|
this->server->destroy(this->server);
|
||||||
DESTROY_IF(this->application);
|
DESTROY_IF(this->application);
|
||||||
this->alert->destroy(this->alert);
|
this->alert->destroy(this->alert);
|
||||||
@@ -309,7 +309,7 @@ tls_t *tls_create(bool is_server, identification_t *server,
|
|||||||
.is_server = is_server,
|
.is_server = is_server,
|
||||||
.version = TLS_1_2,
|
.version = TLS_1_2,
|
||||||
.server = server->clone(server),
|
.server = server->clone(server),
|
||||||
.peer = peer->clone(peer),
|
.peer = peer ? peer->clone(peer) : NULL,
|
||||||
.application = application,
|
.application = application,
|
||||||
.purpose = purpose,
|
.purpose = purpose,
|
||||||
);
|
);
|
||||||
|
|||||||
+2
-6
@@ -96,12 +96,8 @@ enum tls_purpose_t {
|
|||||||
TLS_PURPOSE_EAP_TLS,
|
TLS_PURPOSE_EAP_TLS,
|
||||||
/** outer authentication and protection in EAP-TTLS */
|
/** outer authentication and protection in EAP-TTLS */
|
||||||
TLS_PURPOSE_EAP_TTLS,
|
TLS_PURPOSE_EAP_TTLS,
|
||||||
/** EAP-TTLS with client authentication */
|
/** non-EAP TLS */
|
||||||
TLS_PURPOSE_EAP_TTLS_CLIENT_AUTH,
|
|
||||||
/** non-EAP TLS without client authentication */
|
|
||||||
TLS_PURPOSE_GENERIC,
|
TLS_PURPOSE_GENERIC,
|
||||||
/** non-EAP TLS with client authentication */
|
|
||||||
TLS_PURPOSE_GENERIC_CLIENT_AUTH,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -185,7 +181,7 @@ 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, NULL for no client authentication
|
||||||
* @param purpse purpose this TLS stack instance is used for
|
* @param purpse purpose this TLS stack instance is used for
|
||||||
* @param application higher layer application or NULL if none
|
* @param application higher layer application or NULL if none
|
||||||
* @return TLS stack
|
* @return TLS stack
|
||||||
|
|||||||
@@ -929,13 +929,11 @@ tls_crypto_t *tls_crypto_create(tls_t *tls)
|
|||||||
build_cipher_suite_list(this, FALSE);
|
build_cipher_suite_list(this, FALSE);
|
||||||
break;
|
break;
|
||||||
case TLS_PURPOSE_EAP_TTLS:
|
case TLS_PURPOSE_EAP_TTLS:
|
||||||
case TLS_PURPOSE_EAP_TTLS_CLIENT_AUTH:
|
|
||||||
/* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
|
/* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
|
||||||
this->msk_label = "ttls keying material";
|
this->msk_label = "ttls keying material";
|
||||||
build_cipher_suite_list(this, TRUE);
|
build_cipher_suite_list(this, TRUE);
|
||||||
break;
|
break;
|
||||||
case TLS_PURPOSE_GENERIC:
|
case TLS_PURPOSE_GENERIC:
|
||||||
case TLS_PURPOSE_GENERIC_CLIENT_AUTH:
|
|
||||||
build_cipher_suite_list(this, TRUE);
|
build_cipher_suite_list(this, TRUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-15
@@ -63,7 +63,7 @@ struct private_tls_peer_t {
|
|||||||
tls_alert_t *alert;
|
tls_alert_t *alert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Peer identity
|
* Peer identity, NULL for no client authentication
|
||||||
*/
|
*/
|
||||||
identification_t *peer;
|
identification_t *peer;
|
||||||
|
|
||||||
@@ -87,11 +87,6 @@ struct private_tls_peer_t {
|
|||||||
*/
|
*/
|
||||||
char server_random[32];
|
char server_random[32];
|
||||||
|
|
||||||
/**
|
|
||||||
* Does the server request a peer authentication?
|
|
||||||
*/
|
|
||||||
bool peer_auth_requested;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auth helper for peer authentication
|
* Auth helper for peer authentication
|
||||||
*/
|
*/
|
||||||
@@ -219,7 +214,7 @@ static status_t process_certificate(private_tls_peer_t *this,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a Certificate message
|
* Process a Certificate Request message
|
||||||
*/
|
*/
|
||||||
static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
|
static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
|
||||||
{
|
{
|
||||||
@@ -228,6 +223,13 @@ static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
|
|||||||
identification_t *id;
|
identification_t *id;
|
||||||
certificate_t *cert;
|
certificate_t *cert;
|
||||||
|
|
||||||
|
if (!this->peer)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TLS, "server requested a certificate, but client "
|
||||||
|
"authentication disabled");
|
||||||
|
this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
|
||||||
|
return NEED_MORE;
|
||||||
|
}
|
||||||
this->crypto->append_handshake(this->crypto,
|
this->crypto->append_handshake(this->crypto,
|
||||||
TLS_CERTIFICATE_REQUEST, reader->peek(reader));
|
TLS_CERTIFICATE_REQUEST, reader->peek(reader));
|
||||||
|
|
||||||
@@ -351,9 +353,9 @@ METHOD(tls_handshake_t, process, status_t,
|
|||||||
case STATE_CERT_RECEIVED:
|
case STATE_CERT_RECEIVED:
|
||||||
if (type == TLS_CERTIFICATE_REQUEST)
|
if (type == TLS_CERTIFICATE_REQUEST)
|
||||||
{
|
{
|
||||||
this->peer_auth_requested = TRUE;
|
|
||||||
return process_certreq(this, reader);
|
return process_certreq(this, reader);
|
||||||
}
|
}
|
||||||
|
this->peer = NULL;
|
||||||
/* fall through since TLS_CERTIFICATE_REQUEST is optional */
|
/* fall through since TLS_CERTIFICATE_REQUEST is optional */
|
||||||
case STATE_CERTREQ_RECEIVED:
|
case STATE_CERTREQ_RECEIVED:
|
||||||
if (type == TLS_SERVER_HELLO_DONE)
|
if (type == TLS_SERVER_HELLO_DONE)
|
||||||
@@ -441,13 +443,15 @@ static status_t send_certificate(private_tls_peer_t *this,
|
|||||||
tls_writer_t *certs;
|
tls_writer_t *certs;
|
||||||
chunk_t data;
|
chunk_t data;
|
||||||
|
|
||||||
this->private = lib->credmgr->get_private(lib->credmgr,
|
if (this->peer)
|
||||||
|
{
|
||||||
|
this->private = lib->credmgr->get_private(lib->credmgr,
|
||||||
KEY_ANY, this->peer, this->peer_auth);
|
KEY_ANY, this->peer, this->peer_auth);
|
||||||
|
}
|
||||||
if (!this->private)
|
if (!this->private)
|
||||||
{
|
{
|
||||||
DBG1(DBG_TLS, "no TLS peer certificate found for '%Y'", this->peer);
|
DBG1(DBG_TLS, "no TLS peer certificate found for '%Y'", this->peer);
|
||||||
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
|
return FAILED;
|
||||||
return NEED_MORE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate certificate payload */
|
/* generate certificate payload */
|
||||||
@@ -601,7 +605,7 @@ METHOD(tls_handshake_t, build, status_t,
|
|||||||
case STATE_INIT:
|
case STATE_INIT:
|
||||||
return send_client_hello(this, type, writer);
|
return send_client_hello(this, type, writer);
|
||||||
case STATE_HELLO_DONE:
|
case STATE_HELLO_DONE:
|
||||||
if (this->peer_auth_requested)
|
if (this->peer)
|
||||||
{
|
{
|
||||||
return send_certificate(this, type, writer);
|
return send_certificate(this, type, writer);
|
||||||
}
|
}
|
||||||
@@ -609,7 +613,7 @@ METHOD(tls_handshake_t, build, status_t,
|
|||||||
case STATE_CERT_SENT:
|
case STATE_CERT_SENT:
|
||||||
return send_key_exchange(this, type, writer);
|
return send_key_exchange(this, type, writer);
|
||||||
case STATE_KEY_EXCHANGE_SENT:
|
case STATE_KEY_EXCHANGE_SENT:
|
||||||
if (this->peer_auth_requested)
|
if (this->peer)
|
||||||
{
|
{
|
||||||
return send_certificate_verify(this, type, writer);
|
return send_certificate_verify(this, type, writer);
|
||||||
}
|
}
|
||||||
@@ -627,8 +631,8 @@ METHOD(tls_handshake_t, build, status_t,
|
|||||||
METHOD(tls_handshake_t, cipherspec_changed, bool,
|
METHOD(tls_handshake_t, cipherspec_changed, bool,
|
||||||
private_tls_peer_t *this)
|
private_tls_peer_t *this)
|
||||||
{
|
{
|
||||||
if ((this->peer_auth_requested && this->state == STATE_VERIFY_SENT) ||
|
if ((this->peer && this->state == STATE_VERIFY_SENT) ||
|
||||||
(!this->peer_auth_requested && this->state == STATE_KEY_EXCHANGE_SENT))
|
(!this->peer && this->state == STATE_KEY_EXCHANGE_SENT))
|
||||||
{
|
{
|
||||||
this->crypto->change_cipher(this->crypto, FALSE);
|
this->crypto->change_cipher(this->crypto, FALSE);
|
||||||
this->state = STATE_CIPHERSPEC_CHANGED_OUT;
|
this->state = STATE_CIPHERSPEC_CHANGED_OUT;
|
||||||
|
|||||||
+6
-22
@@ -70,7 +70,7 @@ struct private_tls_server_t {
|
|||||||
identification_t *server;
|
identification_t *server;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Peer identity
|
* Peer identity, NULL for no client authentication
|
||||||
*/
|
*/
|
||||||
identification_t *peer;
|
identification_t *peer;
|
||||||
|
|
||||||
@@ -89,11 +89,6 @@ struct private_tls_server_t {
|
|||||||
*/
|
*/
|
||||||
char server_random[32];
|
char server_random[32];
|
||||||
|
|
||||||
/**
|
|
||||||
* Does the server request a peer authentication?
|
|
||||||
*/
|
|
||||||
bool request_peer_auth;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auth helper for peer authentication
|
* Auth helper for peer authentication
|
||||||
*/
|
*/
|
||||||
@@ -359,7 +354,7 @@ METHOD(tls_handshake_t, process, status_t,
|
|||||||
{
|
{
|
||||||
return process_certificate(this, reader);
|
return process_certificate(this, reader);
|
||||||
}
|
}
|
||||||
if (this->request_peer_auth)
|
if (this->peer)
|
||||||
{
|
{
|
||||||
expected = TLS_CERTIFICATE;
|
expected = TLS_CERTIFICATE;
|
||||||
break;
|
break;
|
||||||
@@ -377,7 +372,7 @@ METHOD(tls_handshake_t, process, status_t,
|
|||||||
{
|
{
|
||||||
return process_cert_verify(this, reader);
|
return process_cert_verify(this, reader);
|
||||||
}
|
}
|
||||||
if (this->request_peer_auth)
|
if (this->peer)
|
||||||
{
|
{
|
||||||
expected = TLS_CERTIFICATE_VERIFY;
|
expected = TLS_CERTIFICATE_VERIFY;
|
||||||
break;
|
break;
|
||||||
@@ -591,7 +586,7 @@ METHOD(tls_handshake_t, build, status_t,
|
|||||||
case STATE_HELLO_SENT:
|
case STATE_HELLO_SENT:
|
||||||
return send_certificate(this, type, writer);
|
return send_certificate(this, type, writer);
|
||||||
case STATE_CERT_SENT:
|
case STATE_CERT_SENT:
|
||||||
if (this->request_peer_auth)
|
if (this->peer)
|
||||||
{
|
{
|
||||||
return send_certificate_request(this, type, writer);
|
return send_certificate_request(this, type, writer);
|
||||||
}
|
}
|
||||||
@@ -622,8 +617,8 @@ METHOD(tls_handshake_t, cipherspec_changed, bool,
|
|||||||
METHOD(tls_handshake_t, change_cipherspec, bool,
|
METHOD(tls_handshake_t, change_cipherspec, bool,
|
||||||
private_tls_server_t *this)
|
private_tls_server_t *this)
|
||||||
{
|
{
|
||||||
if ((this->request_peer_auth && this->state == STATE_CERT_VERIFY_RECEIVED) ||
|
if ((this->peer && this->state == STATE_CERT_VERIFY_RECEIVED) ||
|
||||||
(!this->request_peer_auth && this->state == STATE_KEY_EXCHANGE_RECEIVED))
|
(!this->peer && this->state == STATE_KEY_EXCHANGE_RECEIVED))
|
||||||
{
|
{
|
||||||
this->crypto->change_cipher(this->crypto, TRUE);
|
this->crypto->change_cipher(this->crypto, TRUE);
|
||||||
this->state = STATE_CIPHERSPEC_CHANGED_IN;
|
this->state = STATE_CIPHERSPEC_CHANGED_IN;
|
||||||
@@ -677,16 +672,5 @@ tls_server_t *tls_server_create(tls_t *tls,
|
|||||||
.server_auth = auth_cfg_create(),
|
.server_auth = auth_cfg_create(),
|
||||||
);
|
);
|
||||||
|
|
||||||
switch (tls->get_purpose(tls))
|
|
||||||
{
|
|
||||||
case TLS_PURPOSE_EAP_TLS:
|
|
||||||
case TLS_PURPOSE_EAP_TTLS_CLIENT_AUTH:
|
|
||||||
case TLS_PURPOSE_GENERIC_CLIENT_AUTH:
|
|
||||||
this->request_peer_auth = TRUE;
|
|
||||||
break;
|
|
||||||
case TLS_PURPOSE_EAP_TTLS:
|
|
||||||
case TLS_PURPOSE_GENERIC:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user