Separated cipherspec checking and switching, allowing us to defer the second

This commit is contained in:
Martin Willi
2011-12-31 13:14:49 +01:00
parent 7c0c2349a9
commit 4caa380625
4 changed files with 49 additions and 33 deletions
+4 -2
View File
@@ -251,8 +251,9 @@ METHOD(tls_fragmentation_t, process, status_t,
switch (type) switch (type)
{ {
case TLS_CHANGE_CIPHER_SPEC: case TLS_CHANGE_CIPHER_SPEC:
if (this->handshake->change_cipherspec(this->handshake)) if (this->handshake->cipherspec_changed(this->handshake, TRUE))
{ {
this->handshake->change_cipherspec(this->handshake, TRUE);
status = NEED_MORE; status = NEED_MORE;
break; break;
} }
@@ -397,8 +398,9 @@ METHOD(tls_fragmentation_t, build, status_t,
} }
if (!this->output.len) if (!this->output.len)
{ {
if (this->handshake->cipherspec_changed(this->handshake)) if (this->handshake->cipherspec_changed(this->handshake, FALSE))
{ {
this->handshake->change_cipherspec(this->handshake, FALSE);
*type = TLS_CHANGE_CIPHER_SPEC; *type = TLS_CHANGE_CIPHER_SPEC;
*data = chunk_clone(chunk_from_chars(0x01)); *data = chunk_clone(chunk_from_chars(0x01));
return NEED_MORE; return NEED_MORE;
+7 -6
View File
@@ -62,18 +62,19 @@ struct tls_handshake_t {
tls_handshake_type_t *type, bio_writer_t *writer); tls_handshake_type_t *type, bio_writer_t *writer);
/** /**
* Check if the cipher spec for outgoing messages has changed. * Check if the cipher spec should be changed for outgoing messages.
* *
* @return TRUE if cipher spec changed * @param inbound TRUE to check for inbound cipherspec change
* @return TRUE if cipher spec should be changed
*/ */
bool (*cipherspec_changed)(tls_handshake_t *this); bool (*cipherspec_changed)(tls_handshake_t *this, bool inbound);
/** /**
* Change the cipher spec for incoming messages. * Change the cipher for a direction.
* *
* @return TRUE if cipher spec changed * @param inbound TRUE to change inbound cipherspec, FALSE for outbound
*/ */
bool (*change_cipherspec)(tls_handshake_t *this); void (*change_cipherspec)(tls_handshake_t *this, bool inbound);
/** /**
* Check if the finished message was decoded successfully. * Check if the finished message was decoded successfully.
+19 -13
View File
@@ -1042,28 +1042,34 @@ METHOD(tls_handshake_t, build, status_t,
} }
METHOD(tls_handshake_t, cipherspec_changed, bool, METHOD(tls_handshake_t, cipherspec_changed, bool,
private_tls_peer_t *this) private_tls_peer_t *this, bool inbound)
{ {
if ((this->peer && this->state == STATE_VERIFY_SENT) || if (inbound)
(!this->peer && this->state == STATE_KEY_EXCHANGE_SENT))
{ {
this->crypto->change_cipher(this->crypto, FALSE); return this->state == STATE_FINISHED_SENT;
this->state = STATE_CIPHERSPEC_CHANGED_OUT; }
return TRUE; else
{
if (this->peer)
{
return this->state == STATE_VERIFY_SENT;
}
return this->state == STATE_KEY_EXCHANGE_SENT;
} }
return FALSE;
} }
METHOD(tls_handshake_t, change_cipherspec, bool, METHOD(tls_handshake_t, change_cipherspec, void,
private_tls_peer_t *this) private_tls_peer_t *this, bool inbound)
{ {
if (this->state == STATE_FINISHED_SENT) this->crypto->change_cipher(this->crypto, inbound);
if (inbound)
{ {
this->crypto->change_cipher(this->crypto, TRUE);
this->state = STATE_CIPHERSPEC_CHANGED_IN; this->state = STATE_CIPHERSPEC_CHANGED_IN;
return TRUE;
} }
return FALSE; else
{
this->state = STATE_CIPHERSPEC_CHANGED_OUT;
}
} }
METHOD(tls_handshake_t, finished, bool, METHOD(tls_handshake_t, finished, bool,
+19 -12
View File
@@ -956,28 +956,35 @@ METHOD(tls_handshake_t, build, status_t,
} }
METHOD(tls_handshake_t, cipherspec_changed, bool, METHOD(tls_handshake_t, cipherspec_changed, bool,
private_tls_server_t *this) private_tls_server_t *this, bool inbound)
{ {
if (this->state == STATE_FINISHED_RECEIVED) if (inbound)
{ {
this->crypto->change_cipher(this->crypto, FALSE); if (this->peer)
this->state = STATE_CIPHERSPEC_CHANGED_OUT; {
return TRUE; return this->state == STATE_CERT_VERIFY_RECEIVED;
}
return this->state == STATE_KEY_EXCHANGE_RECEIVED;
}
else
{
return this->state == STATE_FINISHED_RECEIVED;
} }
return FALSE; return FALSE;
} }
METHOD(tls_handshake_t, change_cipherspec, bool, METHOD(tls_handshake_t, change_cipherspec, void,
private_tls_server_t *this) private_tls_server_t *this, bool inbound)
{ {
if ((this->peer && this->state == STATE_CERT_VERIFY_RECEIVED) || this->crypto->change_cipher(this->crypto, inbound);
(!this->peer && this->state == STATE_KEY_EXCHANGE_RECEIVED)) if (inbound)
{ {
this->crypto->change_cipher(this->crypto, TRUE);
this->state = STATE_CIPHERSPEC_CHANGED_IN; this->state = STATE_CIPHERSPEC_CHANGED_IN;
return TRUE;
} }
return FALSE; else
{
this->state = STATE_CIPHERSPEC_CHANGED_OUT;
}
} }
METHOD(tls_handshake_t, finished, bool, METHOD(tls_handshake_t, finished, bool,