static uint32_t SSL_decode_v3(const uint8_t* pkt, int size, uint32_t pkt_flags,
uint8_t* alert_flags, uint16_t* partial_rec_len, int max_hb_len, uint32_t* info_flags,
- SSLV3ClientHelloData* client_hello_data, SSLV3ServerCertData* server_cert_data)
+ SSLV3ClientHelloData* client_hello_data, SSLV3ServerCertData* server_cert_data, uint32_t prev_flags)
{
uint32_t retval = 0;
uint16_t hblen;
case SSL_HANDSHAKE_REC:
/* If the CHANGE_CIPHER_FLAG is set, the following handshake
* record should be encrypted */
- if (!(retval & SSL_CHANGE_CIPHER_FLAG))
+ if (!(retval & SSL_CHANGE_CIPHER_FLAG) && !(prev_flags & SSL_CHANGE_CIPHER_FLAG))
{
int hsize = size < (int)reclen ? size : (int)reclen;
retval |= SSL_decode_handshake_v3(pkt, hsize, retval, pkt_flags, client_hello_data, server_cert_data);
* indicate that it is truncated. */
if (size == 5)
return SSL_decode_v3(pkt, size, pkt_flags, alert_flags, partial_rec_len, max_hb_len, info_flags,
- client_hello_data, server_cert_data);
+ client_hello_data, server_cert_data, prev_flags);
/* At this point, 'size' has to be > 5 */
}
return SSL_decode_v3(pkt, size, pkt_flags, alert_flags, partial_rec_len, max_hb_len, info_flags,
- client_hello_data, server_cert_data);
+ client_hello_data, server_cert_data, prev_flags);
}
/* very simplistic - just enough to say this is binary data - the rules will make a final
#define SSL_IS_CHELLO(x) ((x) & SSL_CLIENT_HELLO_FLAG)
#define SSL_IS_SHELLO(x) ((x) & SSL_SERVER_HELLO_FLAG)
#define SSL_IS_CKEYX(x) ((x) & SSL_CLIENT_KEYX_FLAG)
+#define SSL_IS_CHANGE_CIPHER(x) ((x) & SSL_CHANGE_CIPHER_FLAG)
#define SSL_IS_APP(x) (((x) & SSL_SAPP_FLAG) || ((x) & SSL_CAPP_FLAG))
#define SSL_IS_ALERT(x) ((x) & SSL_ALERT_FLAG)
#define SSL_CLEAR_TEMPORARY_FLAGS(x) (x) &= ~SSL_STATEFLAGS
{
sd->ssn_flags = SSLPP_process_app(config, sd->ssn_flags, new_flags, p);
}
+ else if (SSL_IS_CHANGE_CIPHER(new_flags))
+ {
+ /* If the 'change cipher spec' and 'encrypted handshake message' flags come in separate subsequent packets,
+ * the encrypted handshake message is inspected, and attempts to process some random type and it fails.
+ * To avoid this situation, update the 'change cipher spec' flag in the session to skip processing
+ * the encrypted handshake message.*/
+ sd->ssn_flags |= SSL_CHANGE_CIPHER_FLAG;
+ }
else
{
/* Different record type that we don't care about.