optional certificate-based peer authentication on TLS server side
This commit is contained in:
parent
758d7283fb
commit
b51ac45c48
|
@ -433,8 +433,8 @@ 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 */
|
/* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */
|
||||||
this->tls = tls_create(is_server, server, peer, "client EAP encryption",
|
this->tls = tls_create(is_server, server, peer, TRUE,
|
||||||
NULL);
|
"client EAP encryption", NULL);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
|
@ -441,8 +441,8 @@ 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 */
|
/* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
|
||||||
this->tls = tls_create(is_server, server, peer, "ttls keying material",
|
this->tls = tls_create(is_server, server, peer, FALSE,
|
||||||
application);
|
"ttls keying material", application);
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,8 +178,8 @@ 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, char *msk_label,
|
identification_t *peer, bool request_peer_auth,
|
||||||
tls_application_t *application)
|
char *msk_label, tls_application_t *application)
|
||||||
{
|
{
|
||||||
private_tls_t *this;
|
private_tls_t *this;
|
||||||
|
|
||||||
|
@ -205,7 +205,8 @@ tls_t *tls_create(bool is_server, identification_t *server,
|
||||||
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)->handshake;
|
this->server, this->peer,
|
||||||
|
request_peer_auth)->handshake;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -161,15 +161,16 @@ struct tls_t {
|
||||||
/**
|
/**
|
||||||
* Create a tls instance.
|
* Create a tls instance.
|
||||||
*
|
*
|
||||||
* @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 msk_label ASCII string constant used as seed for MSK PRF
|
* @param request_peer_auth TRUE to request certificate-based peer authentication
|
||||||
* @param application higher layer application or NULL if none
|
* @param msk_label ASCII string constant used as seed for MSK PRF
|
||||||
* @return TLS stack
|
* @param application higher layer application or NULL if none
|
||||||
|
* @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, char *msk_label,
|
identification_t *peer, bool request_peer_auth,
|
||||||
tls_application_t *application);
|
char *msk_label, tls_application_t *application);
|
||||||
|
|
||||||
#endif /** TLS_H_ @}*/
|
#endif /** TLS_H_ @}*/
|
||||||
|
|
|
@ -83,6 +83,11 @@ 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
|
||||||
*/
|
*/
|
||||||
|
@ -332,8 +337,12 @@ METHOD(tls_handshake_t, process, status_t,
|
||||||
{
|
{
|
||||||
return process_certificate(this, reader);
|
return process_certificate(this, reader);
|
||||||
}
|
}
|
||||||
expected = TLS_CERTIFICATE;
|
if (this->request_peer_auth)
|
||||||
break;
|
{
|
||||||
|
expected = TLS_CERTIFICATE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* otherwise fall through to next state */
|
||||||
case STATE_CERT_RECEIVED:
|
case STATE_CERT_RECEIVED:
|
||||||
if (type == TLS_CLIENT_KEY_EXCHANGE)
|
if (type == TLS_CLIENT_KEY_EXCHANGE)
|
||||||
{
|
{
|
||||||
|
@ -346,8 +355,15 @@ METHOD(tls_handshake_t, process, status_t,
|
||||||
{
|
{
|
||||||
return process_cert_verify(this, reader);
|
return process_cert_verify(this, reader);
|
||||||
}
|
}
|
||||||
expected = TLS_CERTIFICATE_VERIFY;
|
if (this->request_peer_auth)
|
||||||
break;
|
{
|
||||||
|
expected = TLS_CERTIFICATE_VERIFY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return INVALID_STATE;
|
||||||
|
}
|
||||||
case STATE_CIPHERSPEC_CHANGED_IN:
|
case STATE_CIPHERSPEC_CHANGED_IN:
|
||||||
if (type == TLS_FINISHED)
|
if (type == TLS_FINISHED)
|
||||||
{
|
{
|
||||||
|
@ -547,7 +563,11 @@ 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:
|
||||||
return send_certificate_request(this, type, writer);
|
if (this->request_peer_auth)
|
||||||
|
{
|
||||||
|
return send_certificate_request(this, type, writer);
|
||||||
|
}
|
||||||
|
/* otherwise fall through to next state */
|
||||||
case STATE_CERTREQ_SENT:
|
case STATE_CERTREQ_SENT:
|
||||||
return send_hello_done(this, type, writer);
|
return send_hello_done(this, type, writer);
|
||||||
case STATE_CIPHERSPEC_CHANGED_OUT:
|
case STATE_CIPHERSPEC_CHANGED_OUT:
|
||||||
|
@ -574,7 +594,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->state == STATE_CERT_VERIFY_RECEIVED)
|
if ((this->request_peer_auth && this->state == STATE_CERT_VERIFY_RECEIVED) ||
|
||||||
|
(!this->request_peer_auth && 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;
|
||||||
|
@ -602,7 +623,8 @@ 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;
|
||||||
|
|
||||||
|
@ -620,6 +642,7 @@ 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(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -43,6 +43,7 @@ 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_ @}*/
|
||||||
|
|
Loading…
Reference in New Issue