*/
bool is_server;
- /**
- * Server identity
- */
- identification_t *server;
-
- /**
- * Peer identity
- */
- identification_t *peer;
-
/**
* Negotiated TLS version
*/
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,
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);
},
.is_server = is_server,
.version = TLS_1_2,
- .server = server->clone(server),
- .peer = peer ? peer->clone(peer) : NULL,
.application = application,
.purpose = purpose,
);
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);
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);
*/
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.
*/
{
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:
{
DBG1(DBG_TLS, "no TLS peer certificate found for '%Y', "
"skipping client authentication", this->peer);
+ this->peer->destroy(this->peer);
this->peer = NULL;
}
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);
.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,
- .peer = peer,
- .server = server,
+ .peer = peer ? peer->clone(peer) : NULL,
+ .server = server->clone(server),
.peer_auth = auth_cfg_create(),
.server_auth = auth_cfg_create(),
);
/**
* 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,
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
{
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);
.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(),
/**
* 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,