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.
This commit is contained in:
+4
-18
@@ -106,16 +106,6 @@ struct private_tls_t {
|
||||
*/
|
||||
bool is_server;
|
||||
|
||||
/**
|
||||
* Server identity
|
||||
*/
|
||||
identification_t *server;
|
||||
|
||||
/**
|
||||
* Peer identity
|
||||
*/
|
||||
identification_t *peer;
|
||||
|
||||
/**
|
||||
* Negotiated TLS version
|
||||
*/
|
||||
@@ -362,13 +352,13 @@ METHOD(tls_t, is_server, bool,
|
||||
METHOD(tls_t, get_server_id, identification_t*,
|
||||
private_tls_t *this)
|
||||
{
|
||||
return this->server;
|
||||
return this->handshake->get_server_id(this->handshake);
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_peer_id, identification_t*,
|
||||
private_tls_t *this)
|
||||
{
|
||||
return this->peer;
|
||||
return this->handshake->get_peer_id(this->handshake);
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_version, tls_version_t,
|
||||
@@ -433,8 +423,6 @@ METHOD(tls_t, destroy, void,
|
||||
this->fragmentation->destroy(this->fragmentation);
|
||||
this->crypto->destroy(this->crypto);
|
||||
this->handshake->destroy(this->handshake);
|
||||
DESTROY_IF(this->peer);
|
||||
this->server->destroy(this->server);
|
||||
DESTROY_IF(this->application);
|
||||
this->alert->destroy(this->alert);
|
||||
|
||||
@@ -480,8 +468,6 @@ tls_t *tls_create(bool is_server, identification_t *server,
|
||||
},
|
||||
.is_server = is_server,
|
||||
.version = TLS_1_2,
|
||||
.server = server->clone(server),
|
||||
.peer = peer ? peer->clone(peer) : NULL,
|
||||
.application = application,
|
||||
.purpose = purpose,
|
||||
);
|
||||
@@ -491,12 +477,12 @@ tls_t *tls_create(bool is_server, identification_t *server,
|
||||
if (is_server)
|
||||
{
|
||||
this->handshake = &tls_server_create(&this->public, this->crypto,
|
||||
this->alert, this->server, this->peer)->handshake;
|
||||
this->alert, server, peer)->handshake;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->handshake = &tls_peer_create(&this->public, this->crypto,
|
||||
this->alert, this->peer, this->server)->handshake;
|
||||
this->alert, peer, server)->handshake;
|
||||
}
|
||||
this->fragmentation = tls_fragmentation_create(this->handshake, this->alert,
|
||||
this->application);
|
||||
|
||||
+4
-4
@@ -193,16 +193,16 @@ struct tls_t {
|
||||
bool (*is_server)(tls_t *this);
|
||||
|
||||
/**
|
||||
* Return the server identity
|
||||
* Return the server identity.
|
||||
*
|
||||
* @return Server identity
|
||||
* @return server identity
|
||||
*/
|
||||
identification_t* (*get_server_id)(tls_t *this);
|
||||
|
||||
/**
|
||||
* Return the peer identity
|
||||
* Return the peer identity.
|
||||
*
|
||||
* @return Peer identity
|
||||
* @return peer identity
|
||||
*/
|
||||
identification_t* (*get_peer_id)(tls_t *this);
|
||||
|
||||
|
||||
@@ -83,6 +83,20 @@ struct tls_handshake_t {
|
||||
*/
|
||||
bool (*finished)(tls_handshake_t *this);
|
||||
|
||||
/**
|
||||
* Get the peer identity authenticated/to authenticate during handshake.
|
||||
*
|
||||
* @return peer identity
|
||||
*/
|
||||
identification_t* (*get_peer_id)(tls_handshake_t *this);
|
||||
|
||||
/**
|
||||
* Get the server identity authenticated/to authenticate during handshake.
|
||||
*
|
||||
* @return server identity
|
||||
*/
|
||||
identification_t* (*get_server_id)(tls_handshake_t *this);
|
||||
|
||||
/**
|
||||
* Destroy a tls_handshake_t.
|
||||
*/
|
||||
|
||||
+21
-2
@@ -665,6 +665,8 @@ METHOD(tls_handshake_t, process, status_t,
|
||||
{
|
||||
return process_certreq(this, reader);
|
||||
}
|
||||
/* no cert request, server does not want to authenticate us */
|
||||
DESTROY_IF(this->peer);
|
||||
this->peer = NULL;
|
||||
/* fall through since TLS_CERTIFICATE_REQUEST is optional */
|
||||
case STATE_CERTREQ_RECEIVED:
|
||||
@@ -850,6 +852,7 @@ static status_t send_certificate(private_tls_peer_t *this,
|
||||
{
|
||||
DBG1(DBG_TLS, "no TLS peer certificate found for '%Y', "
|
||||
"skipping client authentication", this->peer);
|
||||
this->peer->destroy(this->peer);
|
||||
this->peer = NULL;
|
||||
}
|
||||
|
||||
@@ -1132,11 +1135,25 @@ METHOD(tls_handshake_t, finished, bool,
|
||||
return this->state == STATE_FINISHED_RECEIVED;
|
||||
}
|
||||
|
||||
METHOD(tls_handshake_t, get_peer_id, identification_t*,
|
||||
private_tls_peer_t *this)
|
||||
{
|
||||
return this->peer;
|
||||
}
|
||||
|
||||
METHOD(tls_handshake_t, get_server_id, identification_t*,
|
||||
private_tls_peer_t *this)
|
||||
{
|
||||
return this->server;
|
||||
}
|
||||
|
||||
METHOD(tls_handshake_t, destroy, void,
|
||||
private_tls_peer_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);
|
||||
@@ -1161,6 +1178,8 @@ tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto, tls_alert_t *alert
|
||||
.cipherspec_changed = _cipherspec_changed,
|
||||
.change_cipherspec = _change_cipherspec,
|
||||
.finished = _finished,
|
||||
.get_peer_id = _get_peer_id,
|
||||
.get_server_id = _get_server_id,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
@@ -1168,8 +1187,8 @@ tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto, tls_alert_t *alert
|
||||
.tls = tls,
|
||||
.crypto = crypto,
|
||||
.alert = alert,
|
||||
.peer = peer,
|
||||
.server = server,
|
||||
.peer = peer ? peer->clone(peer) : NULL,
|
||||
.server = server->clone(server),
|
||||
.peer_auth = auth_cfg_create(),
|
||||
.server_auth = auth_cfg_create(),
|
||||
);
|
||||
|
||||
@@ -41,11 +41,15 @@ struct tls_peer_t {
|
||||
|
||||
/**
|
||||
* Create a tls_peer instance.
|
||||
*
|
||||
*
|
||||
* If a peer identity is given, but the client does not get requested or is
|
||||
* otherwise unable to perform client authentication, NULL is returned in
|
||||
* tls_handshake_t.get_peer_id() instead of the peer identity.
|
||||
*
|
||||
* @param tls TLS stack
|
||||
* @param crypto TLS crypto helper
|
||||
* @param alert TLS alert handler
|
||||
* @param peer peer identity
|
||||
* @param peer peer identity, NULL to skip client authentication
|
||||
* @param server server identity
|
||||
*/
|
||||
tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto, tls_alert_t *alert,
|
||||
|
||||
+23
-2
@@ -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(),
|
||||
|
||||
@@ -42,11 +42,16 @@ struct tls_server_t {
|
||||
/**
|
||||
* Create a tls_server instance.
|
||||
*
|
||||
* If a peer identity is given, the client must authenticate with a valid
|
||||
* certificate for this identity, or the connection fails. If peer is NULL,
|
||||
* but the client authenticates nonetheless, the authenticated identity
|
||||
* gets returned by tls_handshake_t.get_peer_id().
|
||||
*
|
||||
* @param tls TLS stack
|
||||
* @param crypto TLS crypto helper
|
||||
* @param alert TLS alert handler
|
||||
* @param server server identity
|
||||
* @param peer peer identity
|
||||
* @param peer peer identity, or NULL
|
||||
*/
|
||||
tls_server_t *tls_server_create(tls_t *tls,
|
||||
tls_crypto_t *crypto, tls_alert_t *alert,
|
||||
|
||||
Reference in New Issue
Block a user