diff options
author | Martin Willi <martin@revosec.ch> | 2010-02-09 12:37:29 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-08-03 15:39:25 +0200 |
commit | 8fef06a683128a292f0f6295053e07ec76b51e3e (patch) | |
tree | c1d57012364c708f523edc0b7acebd3bf5c5128b /src | |
parent | dc9f34be4d566978fea8fbd0260e1d674ee2f8d9 (diff) | |
download | strongswan-8fef06a683128a292f0f6295053e07ec76b51e3e.tar.bz2 strongswan-8fef06a683128a292f0f6295053e07ec76b51e3e.tar.xz |
Use stricter state handling while processing TLS messages
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/plugins/eap_tls/tls/tls_peer.c | 69 |
1 files changed, 44 insertions, 25 deletions
diff --git a/src/charon/plugins/eap_tls/tls/tls_peer.c b/src/charon/plugins/eap_tls/tls/tls_peer.c index 6272b90e4..c52da6dfd 100644 --- a/src/charon/plugins/eap_tls/tls/tls_peer.c +++ b/src/charon/plugins/eap_tls/tls/tls_peer.c @@ -24,8 +24,11 @@ typedef struct private_tls_peer_t private_tls_peer_t; typedef enum { STATE_INIT, STATE_HELLO_SENT, + STATE_HELLO_RECEIVED, STATE_HELLO_DONE, STATE_CERT_SENT, + STATE_CERT_RECEIVED, + STATE_CERTREQ_RECEIVED, STATE_KEY_EXCHANGE_SENT, STATE_VERIFY_SENT, 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"); return FAILED; } + this->state = STATE_HELLO_RECEIVED; return NEED_MORE; } @@ -187,6 +191,7 @@ static status_t process_certificate(private_tls_peer_t *this, } } certs->destroy(certs); + this->state = STATE_CERT_RECEIVED; return NEED_MORE; } @@ -242,6 +247,7 @@ static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader) id->destroy(id); } authorities->destroy(authorities); + this->state = STATE_CERTREQ_RECEIVED; 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, private_tls_peer_t *this, tls_handshake_type_t type, tls_reader_t *reader) { + tls_handshake_type_t expected; + switch (this->state) { case STATE_HELLO_SENT: - switch (type) + if (type == TLS_SERVER_HELLO) + { + return process_server_hello(this, reader); + } + expected = TLS_SERVER_HELLO; + break; + case STATE_HELLO_RECEIVED: + if (type == TLS_CERTIFICATE) { - case TLS_SERVER_HELLO: - 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; + 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; case STATE_CIPHERSPEC_CHANGED_IN: - switch (type) + if (type == TLS_FINISHED) { - case TLS_FINISHED: - return process_finished(this, reader); - default: - break; + return process_finished(this, reader); } + expected = TLS_FINISHED; break; 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", - tls_handshake_type_names, type); - return NEED_MORE; + DBG1(DBG_IKE, "TLS %N expected, but received %N", + tls_handshake_type_names, expected, tls_handshake_type_names, type); + return FAILED; } /** * Send a client hello */ -static status_t send_hello(private_tls_peer_t *this, - tls_handshake_type_t *type, tls_writer_t *writer) +static status_t send_client_hello(private_tls_peer_t *this, + tls_handshake_type_t *type, tls_writer_t *writer) { tls_cipher_suite_t *suite; int count, i; @@ -527,7 +548,7 @@ METHOD(tls_handshake_t, build, status_t, switch (this->state) { case STATE_INIT: - return send_hello(this, type, writer); + return send_client_hello(this, type, writer); case STATE_HELLO_DONE: return send_certificate(this, type, writer); case STATE_CERT_SENT: @@ -536,8 +557,6 @@ METHOD(tls_handshake_t, build, status_t, return send_certificate_verify(this, type, writer); case STATE_CIPHERSPEC_CHANGED_OUT: return send_finished(this, type, writer); - case STATE_COMPLETE: - return INVALID_STATE; default: return INVALID_STATE; } |