From 2de481e32b95c558b96237c25a15bf2baa375e93 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 28 Feb 2013 11:39:55 +0100 Subject: Delegate tls_t.get_{peer,server}_id to handshake layer This allows to get updated peer identities if the peer can't authenticate, or does when it is optional. --- src/libtls/tls_server.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src/libtls/tls_server.c') diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c index ec42b67fc..a85a00c4a 100644 --- a/src/libtls/tls_server.c +++ b/src/libtls/tls_server.c @@ -367,6 +367,11 @@ static status_t process_certificate(private_tls_server_t *this, DBG1(DBG_TLS, "received TLS peer certificate '%Y'", cert->get_subject(cert)); first = FALSE; + if (this->peer == NULL) + { /* apply identity to authenticate */ + this->peer = cert->get_subject(cert); + this->peer = this->peer->clone(this->peer); + } } else { @@ -1045,11 +1050,25 @@ METHOD(tls_handshake_t, finished, bool, return this->state == STATE_FINISHED_SENT; } +METHOD(tls_handshake_t, get_peer_id, identification_t*, + private_tls_server_t *this) +{ + return this->peer; +} + +METHOD(tls_handshake_t, get_server_id, identification_t*, + private_tls_server_t *this) +{ + return this->server; +} + METHOD(tls_handshake_t, destroy, void, private_tls_server_t *this) { DESTROY_IF(this->private); DESTROY_IF(this->dh); + DESTROY_IF(this->peer); + this->server->destroy(this->server); this->peer_auth->destroy(this->peer_auth); this->server_auth->destroy(this->server_auth); free(this->hashsig.ptr); @@ -1075,14 +1094,16 @@ tls_server_t *tls_server_create(tls_t *tls, .cipherspec_changed = _cipherspec_changed, .change_cipherspec = _change_cipherspec, .finished = _finished, + .get_peer_id = _get_peer_id, + .get_server_id = _get_server_id, .destroy = _destroy, }, }, .tls = tls, .crypto = crypto, .alert = alert, - .server = server, - .peer = peer, + .server = server->clone(server), + .peer = peer ? peer->clone(peer) : NULL, .state = STATE_INIT, .peer_auth = auth_cfg_create(), .server_auth = auth_cfg_create(), -- cgit v1.2.3 From 807f2facd0283ef19eb33deb59d1128e691647f3 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 28 Feb 2013 12:34:53 +0100 Subject: Request a TLS client certificate even if no peer identity is given This allows a peer to perform client authentication if it wants, but skip it if not. --- src/libtls/tls_server.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/libtls/tls_server.c') diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c index a85a00c4a..6615a37ed 100644 --- a/src/libtls/tls_server.c +++ b/src/libtls/tls_server.c @@ -984,11 +984,7 @@ METHOD(tls_handshake_t, build, status_t, } /* otherwise fall through to next state */ case STATE_KEY_EXCHANGE_SENT: - if (this->peer) - { - return send_certificate_request(this, type, writer); - } - /* otherwise fall through to next state */ + return send_certificate_request(this, type, writer); case STATE_CERTREQ_SENT: return send_hello_done(this, type, writer); case STATE_CIPHERSPEC_CHANGED_OUT: -- cgit v1.2.3 From 1db6bf2f3f8fe0240a63dbd7c79323140daa622e Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 6 Mar 2013 14:39:51 +0100 Subject: If TLS peer authentication not required, the client does nonetheless, allow it to fail --- src/libtls/tls_server.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'src/libtls/tls_server.c') diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c index 6615a37ed..aeb5a714f 100644 --- a/src/libtls/tls_server.c +++ b/src/libtls/tls_server.c @@ -79,6 +79,11 @@ struct private_tls_server_t { */ identification_t *peer; + /** + * Is it acceptable if we couldn't verify the peer certificate? + */ + bool peer_auth_optional; + /** * State we are in */ @@ -371,6 +376,7 @@ static status_t process_certificate(private_tls_server_t *this, { /* apply identity to authenticate */ this->peer = cert->get_subject(cert); this->peer = this->peer->clone(this->peer); + this->peer_auth_optional = TRUE; } } else @@ -555,13 +561,22 @@ static status_t process_cert_verify(private_tls_server_t *this, { DBG1(DBG_TLS, "no trusted certificate found for '%Y' to verify TLS peer", this->peer); - this->alert->add(this->alert, TLS_FATAL, TLS_CERTIFICATE_UNKNOWN); - return NEED_MORE; + if (!this->peer_auth_optional) + { /* client authentication is required */ + this->alert->add(this->alert, TLS_FATAL, TLS_CERTIFICATE_UNKNOWN); + return NEED_MORE; + } + /* reset peer identity, we couldn't authenticate it */ + this->peer->destroy(this->peer); + this->peer = NULL; + this->state = STATE_KEY_EXCHANGE_RECEIVED; + } + else + { + this->state = STATE_CERT_VERIFY_RECEIVED; } - this->crypto->append_handshake(this->crypto, TLS_CERTIFICATE_VERIFY, reader->peek(reader)); - this->state = STATE_CERT_VERIFY_RECEIVED; return NEED_MORE; } -- cgit v1.2.3