mirror of
https://github.com/strongswan/strongswan.git
synced 2025-11-22 00:01:45 -05:00
Use stricter state handling while processing TLS messages
This commit is contained in:
parent
dc9f34be4d
commit
8fef06a683
@ -24,8 +24,11 @@ typedef struct private_tls_peer_t private_tls_peer_t;
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
STATE_INIT,
|
STATE_INIT,
|
||||||
STATE_HELLO_SENT,
|
STATE_HELLO_SENT,
|
||||||
|
STATE_HELLO_RECEIVED,
|
||||||
STATE_HELLO_DONE,
|
STATE_HELLO_DONE,
|
||||||
STATE_CERT_SENT,
|
STATE_CERT_SENT,
|
||||||
|
STATE_CERT_RECEIVED,
|
||||||
|
STATE_CERTREQ_RECEIVED,
|
||||||
STATE_KEY_EXCHANGE_SENT,
|
STATE_KEY_EXCHANGE_SENT,
|
||||||
STATE_VERIFY_SENT,
|
STATE_VERIFY_SENT,
|
||||||
STATE_CIPHERSPEC_CHANGED_OUT,
|
STATE_CIPHERSPEC_CHANGED_OUT,
|
||||||
@ -132,6 +135,7 @@ static status_t process_server_hello(private_tls_peer_t *this,
|
|||||||
DBG1(DBG_IKE, "received cipher suite inacceptable");
|
DBG1(DBG_IKE, "received cipher suite inacceptable");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
this->state = STATE_HELLO_RECEIVED;
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +191,7 @@ static status_t process_certificate(private_tls_peer_t *this,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
certs->destroy(certs);
|
certs->destroy(certs);
|
||||||
|
this->state = STATE_CERT_RECEIVED;
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +247,7 @@ static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
|
|||||||
id->destroy(id);
|
id->destroy(id);
|
||||||
}
|
}
|
||||||
authorities->destroy(authorities);
|
authorities->destroy(authorities);
|
||||||
|
this->state = STATE_CERTREQ_RECEIVED;
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,45 +296,60 @@ static status_t process_finished(private_tls_peer_t *this, tls_reader_t *reader)
|
|||||||
METHOD(tls_handshake_t, process, status_t,
|
METHOD(tls_handshake_t, process, status_t,
|
||||||
private_tls_peer_t *this, tls_handshake_type_t type, tls_reader_t *reader)
|
private_tls_peer_t *this, tls_handshake_type_t type, tls_reader_t *reader)
|
||||||
{
|
{
|
||||||
|
tls_handshake_type_t expected;
|
||||||
|
|
||||||
switch (this->state)
|
switch (this->state)
|
||||||
{
|
{
|
||||||
case STATE_HELLO_SENT:
|
case STATE_HELLO_SENT:
|
||||||
switch (type)
|
if (type == TLS_SERVER_HELLO)
|
||||||
{
|
{
|
||||||
case TLS_SERVER_HELLO:
|
return process_server_hello(this, reader);
|
||||||
return process_server_hello(this, reader);
|
|
||||||
case TLS_CERTIFICATE:
|
|
||||||
return process_certificate(this, reader);
|
|
||||||
case TLS_CERTIFICATE_REQUEST:
|
|
||||||
return process_certreq(this, reader);
|
|
||||||
case TLS_SERVER_HELLO_DONE:
|
|
||||||
return process_hello_done(this, reader);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
expected = TLS_SERVER_HELLO;
|
||||||
|
break;
|
||||||
|
case STATE_HELLO_RECEIVED:
|
||||||
|
if (type == TLS_CERTIFICATE)
|
||||||
|
{
|
||||||
|
return process_certificate(this, reader);
|
||||||
|
}
|
||||||
|
expected = TLS_CERTIFICATE;
|
||||||
|
break;
|
||||||
|
case STATE_CERT_RECEIVED:
|
||||||
|
if (type == TLS_CERTIFICATE_REQUEST)
|
||||||
|
{
|
||||||
|
return process_certreq(this, reader);
|
||||||
|
}
|
||||||
|
expected = TLS_CERTIFICATE_REQUEST;
|
||||||
|
break;
|
||||||
|
case STATE_CERTREQ_RECEIVED:
|
||||||
|
if (type == TLS_SERVER_HELLO_DONE)
|
||||||
|
{
|
||||||
|
return process_hello_done(this, reader);
|
||||||
|
}
|
||||||
|
expected = TLS_SERVER_HELLO_DONE;
|
||||||
break;
|
break;
|
||||||
case STATE_CIPHERSPEC_CHANGED_IN:
|
case STATE_CIPHERSPEC_CHANGED_IN:
|
||||||
switch (type)
|
if (type == TLS_FINISHED)
|
||||||
{
|
{
|
||||||
case TLS_FINISHED:
|
return process_finished(this, reader);
|
||||||
return process_finished(this, reader);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
expected = TLS_FINISHED;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
DBG1(DBG_IKE, "TLS %N not expected in current state",
|
||||||
|
tls_handshake_type_names, type);
|
||||||
|
return FAILED;
|
||||||
}
|
}
|
||||||
DBG1(DBG_IKE, "received TLS handshake message %N, ignored",
|
DBG1(DBG_IKE, "TLS %N expected, but received %N",
|
||||||
tls_handshake_type_names, type);
|
tls_handshake_type_names, expected, tls_handshake_type_names, type);
|
||||||
return NEED_MORE;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a client hello
|
* Send a client hello
|
||||||
*/
|
*/
|
||||||
static status_t send_hello(private_tls_peer_t *this,
|
static status_t send_client_hello(private_tls_peer_t *this,
|
||||||
tls_handshake_type_t *type, tls_writer_t *writer)
|
tls_handshake_type_t *type, tls_writer_t *writer)
|
||||||
{
|
{
|
||||||
tls_cipher_suite_t *suite;
|
tls_cipher_suite_t *suite;
|
||||||
int count, i;
|
int count, i;
|
||||||
@ -527,7 +548,7 @@ METHOD(tls_handshake_t, build, status_t,
|
|||||||
switch (this->state)
|
switch (this->state)
|
||||||
{
|
{
|
||||||
case STATE_INIT:
|
case STATE_INIT:
|
||||||
return send_hello(this, type, writer);
|
return send_client_hello(this, type, writer);
|
||||||
case STATE_HELLO_DONE:
|
case STATE_HELLO_DONE:
|
||||||
return send_certificate(this, type, writer);
|
return send_certificate(this, type, writer);
|
||||||
case STATE_CERT_SENT:
|
case STATE_CERT_SENT:
|
||||||
@ -536,8 +557,6 @@ METHOD(tls_handshake_t, build, status_t,
|
|||||||
return send_certificate_verify(this, type, writer);
|
return send_certificate_verify(this, type, writer);
|
||||||
case STATE_CIPHERSPEC_CHANGED_OUT:
|
case STATE_CIPHERSPEC_CHANGED_OUT:
|
||||||
return send_finished(this, type, writer);
|
return send_finished(this, type, writer);
|
||||||
case STATE_COMPLETE:
|
|
||||||
return INVALID_STATE;
|
|
||||||
default:
|
default:
|
||||||
return INVALID_STATE;
|
return INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user