Separated cipherspec checking and switching, allowing us to defer the second
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user