Implemented sending of Certificate, ClientKeyExchange, CertificateVerify and ChangeCipherSpec as peer
This commit is contained in:
@@ -408,7 +408,7 @@ static eap_tls_t *eap_tls_create(identification_t *server,
|
||||
.peer = peer->clone(peer),
|
||||
.server = server->clone(server),
|
||||
.is_server = is_server,
|
||||
.tls = tls_create(is_server),
|
||||
.tls = tls_create(is_server, server, peer),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
|
||||
@@ -143,7 +143,8 @@ METHOD(tls_t, destroy, void,
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tls_t *tls_create(bool is_server)
|
||||
tls_t *tls_create(bool is_server, identification_t *server,
|
||||
identification_t *peer)
|
||||
{
|
||||
private_tls_t *this;
|
||||
|
||||
@@ -162,13 +163,13 @@ tls_t *tls_create(bool is_server)
|
||||
|
||||
if (is_server)
|
||||
{
|
||||
this->handshake = &tls_server_create(&this->public,
|
||||
this->crypto)->handshake;
|
||||
this->handshake = &tls_server_create(&this->public, this->crypto,
|
||||
server, peer)->handshake;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->handshake = &tls_peer_create(&this->public,
|
||||
this->crypto)->handshake;
|
||||
this->handshake = &tls_peer_create(&this->public, this->crypto,
|
||||
peer, server)->handshake;
|
||||
}
|
||||
this->fragmentation = tls_fragmentation_create(this->handshake);
|
||||
this->compression = tls_compression_create(this->fragmentation);
|
||||
|
||||
@@ -178,8 +178,11 @@ struct tls_t {
|
||||
* Create a tls instance.
|
||||
*
|
||||
* @param is_server TRUE to act as server, FALSE for client
|
||||
* @param server server identity
|
||||
* @param peer peer identity
|
||||
* @return TLS stack
|
||||
*/
|
||||
tls_t *tls_create(bool is_server);
|
||||
tls_t *tls_create(bool is_server, identification_t *server,
|
||||
identification_t *peer);
|
||||
|
||||
#endif /** TLS_H_ @}*/
|
||||
|
||||
@@ -141,8 +141,8 @@ METHOD(tls_fragmentation_t, process, status_t,
|
||||
switch (type)
|
||||
{
|
||||
case TLS_CHANGE_CIPHER_SPEC:
|
||||
/* TODO: handle ChangeCipherSpec */
|
||||
status = FAILED;
|
||||
this->handshake->change_cipherspec(this->handshake);
|
||||
status = NEED_MORE;
|
||||
break;
|
||||
case TLS_ALERT:
|
||||
/* TODO: handle Alert */
|
||||
@@ -171,6 +171,13 @@ METHOD(tls_fragmentation_t, build, status_t,
|
||||
tls_writer_t *writer, *msg;
|
||||
status_t status;
|
||||
|
||||
if (this->handshake->cipherspec_changed(this->handshake))
|
||||
{
|
||||
*type = TLS_CHANGE_CIPHER_SPEC;
|
||||
*data = chunk_clone(chunk_from_chars(0x01));
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
if (!this->output.len)
|
||||
{
|
||||
msg = tls_writer_create(64);
|
||||
|
||||
@@ -59,6 +59,18 @@ struct tls_handshake_t {
|
||||
status_t (*build)(tls_handshake_t *this,
|
||||
tls_handshake_type_t *type, tls_writer_t *writer);
|
||||
|
||||
/**
|
||||
* Check if the cipher spec for outgoing messages has changed.
|
||||
*
|
||||
* @return TRUE if cipher spec changed
|
||||
*/
|
||||
bool (*cipherspec_changed)(tls_handshake_t *this);
|
||||
|
||||
/**
|
||||
* Change the cipher spec for incoming messages.
|
||||
*/
|
||||
void (*change_cipherspec)(tls_handshake_t *this);
|
||||
|
||||
/**
|
||||
* Destroy a tls_handshake_t.
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,11 @@ typedef enum {
|
||||
STATE_INIT,
|
||||
STATE_HELLO_SENT,
|
||||
STATE_HELLO_DONE,
|
||||
STATE_CERT_SENT,
|
||||
STATE_KEY_EXCHANGE_SENT,
|
||||
STATE_VERIFY_SENT,
|
||||
STATE_CIPHERSPEC_CHANGED,
|
||||
STATE_FINISHED_SENT,
|
||||
} peer_state_t;
|
||||
|
||||
/**
|
||||
@@ -47,12 +52,56 @@ struct private_tls_peer_t {
|
||||
*/
|
||||
tls_crypto_t *crypto;
|
||||
|
||||
/**
|
||||
* Peer identity
|
||||
*/
|
||||
identification_t *peer;
|
||||
|
||||
/**
|
||||
* Server identity
|
||||
*/
|
||||
identification_t *server;
|
||||
|
||||
/**
|
||||
* State we are in
|
||||
*/
|
||||
peer_state_t state;
|
||||
|
||||
/**
|
||||
* All handshake data concatentated
|
||||
*/
|
||||
chunk_t handshake;
|
||||
|
||||
/**
|
||||
* Auth helper for peer authentication
|
||||
*/
|
||||
auth_cfg_t *peer_auth;
|
||||
|
||||
/**
|
||||
* Auth helper for server authentication
|
||||
*/
|
||||
auth_cfg_t *server_auth;
|
||||
|
||||
/**
|
||||
* Peer private key
|
||||
*/
|
||||
private_key_t *private;
|
||||
};
|
||||
|
||||
/**
|
||||
* Append a handshake message to the handshake data buffer
|
||||
*/
|
||||
static void append_handshake(private_tls_peer_t *this,
|
||||
tls_handshake_type_t type, chunk_t data)
|
||||
{
|
||||
u_int32_t header;
|
||||
|
||||
/* reconstruct handshake header */
|
||||
header = htonl(data.len | (type << 24));
|
||||
this->handshake = chunk_cat("mcc", this->handshake,
|
||||
chunk_from_thing(header), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a server hello message
|
||||
*/
|
||||
@@ -64,6 +113,8 @@ static status_t process_server_hello(private_tls_peer_t *this,
|
||||
u_int32_t gmt;
|
||||
chunk_t random, session, ext = chunk_empty;
|
||||
|
||||
append_handshake(this, TLS_SERVER_HELLO, reader->peek(reader));
|
||||
|
||||
if (!reader->read_uint16(reader, &version) ||
|
||||
!reader->read_uint32(reader, &gmt) ||
|
||||
!reader->read_data(reader, 28, &random) ||
|
||||
@@ -91,6 +142,9 @@ static status_t process_certificate(private_tls_peer_t *this,
|
||||
certificate_t *cert;
|
||||
tls_reader_t *certs;
|
||||
chunk_t data;
|
||||
bool first = TRUE;
|
||||
|
||||
append_handshake(this, TLS_CERTIFICATE, reader->peek(reader));
|
||||
|
||||
if (!reader->read_data24(reader, &data))
|
||||
{
|
||||
@@ -105,11 +159,28 @@ static status_t process_certificate(private_tls_peer_t *this,
|
||||
return FAILED;
|
||||
}
|
||||
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||
BUILD_BLOB_ASN1_DER, data, BUILD_END);
|
||||
BUILD_BLOB_ASN1_DER, data, BUILD_END);
|
||||
if (cert)
|
||||
{
|
||||
DBG1(DBG_IKE, "got certificate: %Y", cert->get_subject(cert));
|
||||
cert->destroy(cert);
|
||||
if (first)
|
||||
{
|
||||
this->server_auth->add(this->server_auth,
|
||||
AUTH_RULE_SUBJECT_CERT, cert);
|
||||
DBG1(DBG_IKE, "received TLS server certificate '%Y'",
|
||||
cert->get_subject(cert));
|
||||
first = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IKE, "received TLS intermediate certificate '%Y'",
|
||||
cert->get_subject(cert));
|
||||
this->server_auth->add(this->server_auth,
|
||||
AUTH_RULE_IM_CERT, cert);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IKE, "parsing TLS certificate failed, skipped");
|
||||
}
|
||||
}
|
||||
certs->destroy(certs);
|
||||
@@ -124,6 +195,9 @@ static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
|
||||
chunk_t types, hashsig, data;
|
||||
tls_reader_t *authorities;
|
||||
identification_t *id;
|
||||
certificate_t *cert;
|
||||
|
||||
append_handshake(this, TLS_CERTIFICATE_REQUEST, reader->peek(reader));
|
||||
|
||||
if (!reader->read_data8(reader, &types))
|
||||
{
|
||||
@@ -135,6 +209,7 @@ static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
/* TODO: store supported hashsig algorithms */
|
||||
}
|
||||
if (!reader->read_data16(reader, &data))
|
||||
{
|
||||
@@ -149,13 +224,34 @@ static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
|
||||
return FAILED;
|
||||
}
|
||||
id = identification_create_from_encoding(ID_DER_ASN1_DN, data);
|
||||
DBG1(DBG_IKE, "received certificate request for %Y", id);
|
||||
cert = charon->credentials->get_cert(charon->credentials,
|
||||
CERT_X509, KEY_ANY, id, TRUE);
|
||||
if (cert)
|
||||
{
|
||||
DBG1(DBG_IKE, "received cert request for '%Y", id);
|
||||
this->peer_auth->add(this->peer_auth, AUTH_RULE_CA_CERT, cert);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IKE, "received cert request for unknown CA '%Y'", id);
|
||||
}
|
||||
id->destroy(id);
|
||||
}
|
||||
authorities->destroy(authorities);
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Hello Done message
|
||||
*/
|
||||
static status_t process_hello_done(private_tls_peer_t *this,
|
||||
tls_reader_t *reader)
|
||||
{
|
||||
append_handshake(this, TLS_SERVER_HELLO_DONE, reader->peek(reader));
|
||||
this->state = STATE_HELLO_DONE;
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
METHOD(tls_handshake_t, process, status_t,
|
||||
private_tls_peer_t *this, tls_handshake_type_t type, tls_reader_t *reader)
|
||||
{
|
||||
@@ -171,8 +267,7 @@ METHOD(tls_handshake_t, process, status_t,
|
||||
case TLS_CERTIFICATE_REQUEST:
|
||||
return process_certreq(this, reader);
|
||||
case TLS_SERVER_HELLO_DONE:
|
||||
this->state = STATE_HELLO_DONE;
|
||||
return NEED_MORE;
|
||||
return process_hello_done(this, reader);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -223,6 +318,192 @@ static status_t send_hello(private_tls_peer_t *this,
|
||||
|
||||
*type = TLS_CLIENT_HELLO;
|
||||
this->state = STATE_HELLO_SENT;
|
||||
append_handshake(this, *type, writer->get_buf(writer));
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Certificate
|
||||
*/
|
||||
static status_t send_certificate(private_tls_peer_t *this,
|
||||
tls_handshake_type_t *type, tls_writer_t *writer)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
certificate_t *cert;
|
||||
auth_rule_t rule;
|
||||
tls_writer_t *certs;
|
||||
chunk_t data;
|
||||
|
||||
this->private = charon->credentials->get_private(charon->credentials,
|
||||
KEY_ANY, this->peer, this->peer_auth);
|
||||
if (!this->private)
|
||||
{
|
||||
DBG1(DBG_IKE, "no TLS peer certificate found for '%Y'", this->peer);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* generate certificate payload */
|
||||
certs = tls_writer_create(256);
|
||||
cert = this->peer_auth->get(this->peer_auth, AUTH_RULE_SUBJECT_CERT);
|
||||
if (cert)
|
||||
{
|
||||
DBG1(DBG_IKE, "sending TLS peer certificate '%Y'",
|
||||
cert->get_subject(cert));
|
||||
data = cert->get_encoding(cert);
|
||||
certs->write_data24(certs, data);
|
||||
free(data.ptr);
|
||||
}
|
||||
enumerator = this->peer_auth->create_enumerator(this->peer_auth);
|
||||
while (enumerator->enumerate(enumerator, &rule, &cert))
|
||||
{
|
||||
if (rule == AUTH_RULE_IM_CERT)
|
||||
{
|
||||
DBG1(DBG_IKE, "sending TLS intermediate certificate '%Y'",
|
||||
cert->get_subject(cert));
|
||||
data = cert->get_encoding(cert);
|
||||
certs->write_data24(certs, data);
|
||||
free(data.ptr);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
writer->write_data24(writer, certs->get_buf(certs));
|
||||
certs->destroy(certs);
|
||||
|
||||
*type = TLS_CERTIFICATE;
|
||||
this->state = STATE_CERT_SENT;
|
||||
append_handshake(this, *type, writer->get_buf(writer));
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send client key exchange
|
||||
*/
|
||||
static status_t send_key_exchange(private_tls_peer_t *this,
|
||||
tls_handshake_type_t *type, tls_writer_t *writer)
|
||||
{
|
||||
public_key_t *public = NULL, *current;
|
||||
enumerator_t *enumerator;
|
||||
auth_cfg_t *auth;
|
||||
rng_t *rng;
|
||||
char premaster[48];
|
||||
chunk_t encrypted;
|
||||
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
|
||||
if (!rng)
|
||||
{
|
||||
DBG1(DBG_IKE, "no suitable RNG found for TLS premaster secret");
|
||||
return FAILED;
|
||||
}
|
||||
rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2);
|
||||
rng->destroy(rng);
|
||||
htoun16(premaster, TLS_1_2);
|
||||
|
||||
enumerator = charon->credentials->create_public_enumerator(
|
||||
charon->credentials, KEY_ANY, this->server, this->server_auth);
|
||||
while (enumerator->enumerate(enumerator, ¤t, &auth))
|
||||
{
|
||||
public = current->get_ref(current);
|
||||
break;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (!public)
|
||||
{
|
||||
DBG1(DBG_IKE, "no TLS public key found for server '%Y'", this->server);
|
||||
return FAILED;
|
||||
}
|
||||
if (!public->encrypt(public, chunk_from_thing(premaster), &encrypted))
|
||||
{
|
||||
public->destroy(public);
|
||||
DBG1(DBG_IKE, "encrypting TLS premaster secret failed");
|
||||
return FAILED;
|
||||
}
|
||||
public->destroy(public);
|
||||
|
||||
writer->write_data16(writer, encrypted);
|
||||
free(encrypted.ptr);
|
||||
|
||||
*type = TLS_CLIENT_KEY_EXCHANGE;
|
||||
this->state = STATE_KEY_EXCHANGE_SENT;
|
||||
append_handshake(this, *type, writer->get_buf(writer));
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send certificate verify
|
||||
*/
|
||||
static status_t send_certificate_verify(private_tls_peer_t *this,
|
||||
tls_handshake_type_t *type, tls_writer_t *writer)
|
||||
{
|
||||
chunk_t signature;
|
||||
|
||||
if (!this->private)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
if (this->tls->get_version(this->tls) >= TLS_1_2)
|
||||
{
|
||||
if (!this->private->sign(this->private, SIGN_RSA_EMSA_PKCS1_SHA1,
|
||||
this->handshake, &signature))
|
||||
{
|
||||
DBG1(DBG_IKE, "creating TLS Certificate Verify signature failed");
|
||||
return FAILED;
|
||||
}
|
||||
/* TODO: signature scheme to hashsign algorithm mapping */
|
||||
writer->write_uint8(writer, 2); /* sha1 */
|
||||
writer->write_uint8(writer, 1); /* RSA */
|
||||
}
|
||||
else
|
||||
{
|
||||
hasher_t *md5, *sha1;
|
||||
char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1];
|
||||
|
||||
md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
|
||||
if (!md5)
|
||||
{
|
||||
DBG1(DBG_IKE, "unable to sign %N Verify, MD5 not supported",
|
||||
tls_version_names, this->tls->get_version(this->tls));
|
||||
return FAILED;
|
||||
}
|
||||
md5->get_hash(md5, this->handshake, buf);
|
||||
md5->destroy(md5);
|
||||
sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||
if (!sha1)
|
||||
{
|
||||
DBG1(DBG_IKE, "unable to sign %N Verify, SHA1 not supported",
|
||||
tls_version_names, this->tls->get_version(this->tls));
|
||||
return FAILED;
|
||||
}
|
||||
sha1->get_hash(sha1, this->handshake, buf + HASH_SIZE_MD5);
|
||||
sha1->destroy(sha1);
|
||||
|
||||
if (!this->private->sign(this->private, SIGN_RSA_EMSA_PKCS1_NULL,
|
||||
chunk_from_thing(buf), &signature))
|
||||
{
|
||||
DBG1(DBG_IKE, "creating TLS Certificate Verify signature failed");
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
writer->write_data16(writer, signature);
|
||||
free(signature.ptr);
|
||||
chunk_free(&this->handshake);
|
||||
|
||||
*type = TLS_CERTIFICATE_VERIFY;
|
||||
this->state = STATE_VERIFY_SENT;
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Finished
|
||||
*/
|
||||
static status_t send_finished(private_tls_peer_t *this,
|
||||
tls_handshake_type_t *type, tls_writer_t *writer)
|
||||
{
|
||||
*type = TLS_FINISHED;
|
||||
this->state = STATE_FINISHED_SENT;
|
||||
/* TODO: finished message */
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
@@ -233,21 +514,51 @@ METHOD(tls_handshake_t, build, status_t,
|
||||
{
|
||||
case STATE_INIT:
|
||||
return send_hello(this, type, writer);
|
||||
case STATE_HELLO_DONE:
|
||||
return send_certificate(this, type, writer);
|
||||
case STATE_CERT_SENT:
|
||||
return send_key_exchange(this, type, writer);
|
||||
case STATE_KEY_EXCHANGE_SENT:
|
||||
return send_certificate_verify(this, type, writer);
|
||||
case STATE_CIPHERSPEC_CHANGED:
|
||||
return send_finished(this, type, writer);
|
||||
default:
|
||||
return INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(tls_handshake_t, cipherspec_changed, bool,
|
||||
private_tls_peer_t *this)
|
||||
{
|
||||
if (this->state == STATE_VERIFY_SENT)
|
||||
{
|
||||
this->state = STATE_CIPHERSPEC_CHANGED;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(tls_handshake_t, change_cipherspec, void,
|
||||
private_tls_peer_t *this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
METHOD(tls_handshake_t, destroy, void,
|
||||
private_tls_peer_t *this)
|
||||
{
|
||||
DESTROY_IF(this->private);
|
||||
free(this->handshake.ptr);
|
||||
this->peer_auth->destroy(this->peer_auth);
|
||||
this->server_auth->destroy(this->server_auth);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto)
|
||||
tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto,
|
||||
identification_t *peer, identification_t *server)
|
||||
{
|
||||
private_tls_peer_t *this;
|
||||
|
||||
@@ -255,11 +566,17 @@ tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto)
|
||||
.public.handshake = {
|
||||
.process = _process,
|
||||
.build = _build,
|
||||
.cipherspec_changed = _cipherspec_changed,
|
||||
.change_cipherspec = _change_cipherspec,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.state = STATE_INIT,
|
||||
.tls = tls,
|
||||
.crypto = crypto,
|
||||
.peer = peer,
|
||||
.server = server,
|
||||
.peer_auth = auth_cfg_create(),
|
||||
.server_auth = auth_cfg_create(),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
|
||||
@@ -26,6 +26,8 @@ typedef struct tls_peer_t tls_peer_t;
|
||||
#include "tls_handshake.h"
|
||||
#include "tls_crypto.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* TLS handshake protocol handler as peer.
|
||||
*/
|
||||
@@ -40,6 +42,7 @@ struct tls_peer_t {
|
||||
/**
|
||||
* Create a tls_peer instance.
|
||||
*/
|
||||
tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto);
|
||||
tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto,
|
||||
identification_t *peer, identification_t *server);
|
||||
|
||||
#endif /** TLS_PEER_H_ @}*/
|
||||
|
||||
@@ -41,6 +41,12 @@ METHOD(tls_reader_t, remaining, u_int32_t,
|
||||
return this->buf.len;
|
||||
}
|
||||
|
||||
METHOD(tls_reader_t, peek, chunk_t,
|
||||
private_tls_reader_t *this)
|
||||
{
|
||||
return this->buf;
|
||||
}
|
||||
|
||||
METHOD(tls_reader_t, read_uint8, bool,
|
||||
private_tls_reader_t *this, u_int8_t *res)
|
||||
{
|
||||
@@ -175,6 +181,7 @@ tls_reader_t *tls_reader_create(chunk_t data)
|
||||
INIT(this,
|
||||
.public = {
|
||||
.remaining = _remaining,
|
||||
.peek = _peek,
|
||||
.read_uint8 = _read_uint8,
|
||||
.read_uint16 = _read_uint16,
|
||||
.read_uint24 = _read_uint24,
|
||||
|
||||
@@ -37,6 +37,13 @@ struct tls_reader_t {
|
||||
*/
|
||||
u_int32_t (*remaining)(tls_reader_t *this);
|
||||
|
||||
/**
|
||||
* Peek the remaining data, not consuming any bytes.
|
||||
*
|
||||
* @return remaining data
|
||||
*/
|
||||
chunk_t (*peek)(tls_reader_t *this);
|
||||
|
||||
/**
|
||||
* Read a 8-bit integer from the buffer, advance.
|
||||
*
|
||||
|
||||
@@ -38,6 +38,16 @@ struct private_tls_server_t {
|
||||
* TLS crypto context
|
||||
*/
|
||||
tls_crypto_t *crypto;
|
||||
|
||||
/**
|
||||
* Server identity
|
||||
*/
|
||||
identification_t *server;
|
||||
|
||||
/**
|
||||
* Peer identity
|
||||
*/
|
||||
identification_t *peer;
|
||||
};
|
||||
|
||||
|
||||
@@ -53,6 +63,18 @@ METHOD(tls_handshake_t, build, status_t,
|
||||
return INVALID_STATE;
|
||||
}
|
||||
|
||||
METHOD(tls_handshake_t, cipherspec_changed, bool,
|
||||
private_tls_server_t *this)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(tls_handshake_t, change_cipherspec, void,
|
||||
private_tls_server_t *this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
METHOD(tls_handshake_t, destroy, void,
|
||||
private_tls_server_t *this)
|
||||
{
|
||||
@@ -62,7 +84,8 @@ METHOD(tls_handshake_t, destroy, void,
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
private_tls_server_t *this;
|
||||
|
||||
@@ -70,10 +93,14 @@ tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto)
|
||||
.public.handshake = {
|
||||
.process = _process,
|
||||
.build = _build,
|
||||
.cipherspec_changed = _cipherspec_changed,
|
||||
.change_cipherspec = _change_cipherspec,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.tls = tls,
|
||||
.crypto = crypto,
|
||||
.server = server,
|
||||
.peer = peer,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
|
||||
@@ -26,6 +26,8 @@ typedef struct tls_server_t tls_server_t;
|
||||
#include "tls_handshake.h"
|
||||
#include "tls_crypto.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* TLS handshake protocol handler as peer.
|
||||
*/
|
||||
@@ -40,6 +42,7 @@ struct tls_server_t {
|
||||
/**
|
||||
* 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);
|
||||
|
||||
#endif /** TLS_SERVER_H_ @}*/
|
||||
|
||||
Reference in New Issue
Block a user