optional certificate-based peer authentication on TLS server side

This commit is contained in:
Andreas Steffen 2010-08-15 13:02:57 +02:00
parent 758d7283fb
commit b51ac45c48
6 changed files with 49 additions and 23 deletions

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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
{ {

View File

@ -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_ @}*/

View File

@ -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(),
); );

View File

@ -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_ @}*/