mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 09:38:19 +00:00
Add basic DTLSv1.3 support
DTLSv1.3 changes the DTLS record format, introducing a completely new header - which is a first for DTLS. We don't currently completely parse this header, as this requires a bit more statekeeping. This will be added in a future revision. This also also has little practical implications.
This commit is contained in:
parent
e7c9fa1f6e
commit
d6c4c510ea
7 changed files with 88 additions and 5 deletions
|
@ -11,6 +11,7 @@ export {
|
|||
const DTLSv10 = 0xFEFF;
|
||||
# DTLSv11 does not exist
|
||||
const DTLSv12 = 0xFEFD;
|
||||
const DTLSv13 = 0xFEFC;
|
||||
|
||||
## Mapping between the constants and string values for SSL/TLS versions.
|
||||
const version_strings: table[count] of string = {
|
||||
|
@ -21,7 +22,8 @@ export {
|
|||
[TLSv12] = "TLSv12",
|
||||
[TLSv13] = "TLSv13",
|
||||
[DTLSv10] = "DTLSv10",
|
||||
[DTLSv12] = "DTLSv12"
|
||||
[DTLSv12] = "DTLSv12",
|
||||
[DTLSv13] = "DTLSv13"
|
||||
} &default=function(i: count):string
|
||||
{
|
||||
if ( i/0xFF == 0x7F ) # TLS 1.3 draft
|
||||
|
|
|
@ -138,6 +138,31 @@ refine connection SSL_Conn += {
|
|||
|
||||
return true;
|
||||
%}
|
||||
|
||||
function proc_unified_record(is_orig: bool, ur: UnifiedRecord) : bool
|
||||
%{
|
||||
// we don't have a CCS packet anymore - so let's just assume the connection is established once we have seen a packet from each direction.
|
||||
if ( is_orig )
|
||||
client_state_ = STATE_ENCRYPTED;
|
||||
else
|
||||
server_state_ = STATE_ENCRYPTED;
|
||||
|
||||
if ( client_state_ == STATE_ENCRYPTED && server_state_ == STATE_ENCRYPTED && established_ == false )
|
||||
{
|
||||
established_ = true;
|
||||
if ( ssl_established )
|
||||
zeek::BifEvent::enqueue_ssl_established(zeek_analyzer(), zeek_analyzer()->Conn());
|
||||
}
|
||||
|
||||
if ( ssl_encrypted_data )
|
||||
{
|
||||
// FIXME: swallow is not quite the correct length, because we are not parsing the entire header
|
||||
zeek::BifEvent::enqueue_ssl_encrypted_data(zeek_analyzer(),
|
||||
zeek_analyzer()->Conn(), is_orig ^ zeek_analyzer()->GetFlipped(), DTLSv13, APPLICATION_DATA, ur->swallow().length());
|
||||
}
|
||||
|
||||
return true;
|
||||
%}
|
||||
};
|
||||
|
||||
refine typeattr SSLRecord += &let {
|
||||
|
@ -147,3 +172,7 @@ refine typeattr SSLRecord += &let {
|
|||
refine typeattr Handshake += &let {
|
||||
proc: bool = $context.connection.proc_handshake(rec, this);
|
||||
};
|
||||
|
||||
refine typeattr UnifiedRecord += &let {
|
||||
proc: bool = $context.connection.proc_unified_record(is_orig, this);
|
||||
};
|
||||
|
|
|
@ -4,11 +4,37 @@
|
|||
######################################################################
|
||||
|
||||
type DTLSPDU(is_orig: bool) = record {
|
||||
records: SSLRecord(is_orig)[] &transient;
|
||||
records: SSLRecordSwitch(is_orig)[] &transient;
|
||||
};
|
||||
|
||||
type SSLRecord(is_orig: bool) = record {
|
||||
content_type: uint8;
|
||||
# This feels like (another) really dirty hack. DTLS 1.3 introduces a new way in which ciphertext records
|
||||
# can be encoded, using a new unified header, which is completely different from the earlier DTLS headers.
|
||||
# It only is used after the client & server hello - which essentially are the same as in DTLS 1.2 (including
|
||||
# using the same record-layer versions - which is why `dtls_version_ok` underneath does not refer to DTLS 1.3)
|
||||
# The DTLS 1.3 unified header is signaled by the first 3 bits of the first byte being set to `001`, but only
|
||||
# after DTLS 1.3 has been negotiated.
|
||||
type SSLRecordSwitch(is_orig: bool) = record {
|
||||
firstbyte: uint8;
|
||||
|
||||
cont: case $context.connection.choose_record_type(firstbyte) of {
|
||||
false -> rec: SSLRecord(firstbyte, is_orig);
|
||||
true -> unified: UnifiedRecord(firstbyte, is_orig);
|
||||
};
|
||||
};
|
||||
|
||||
type UnifiedRecord(firstbyte: uint8, is_orig: bool) = record {
|
||||
# sequence_number: bytestring &length=(sequence_number_length?2:1);
|
||||
# lets just ignore eveything for now. We have very limited example
|
||||
# data, and it is hard to parse the CID due to variable length.
|
||||
swallow: bytestring &restofdata;
|
||||
} &let {
|
||||
with_cid: bool = ((firstbyte&0x10)==0x10);
|
||||
sequence_number_length: bool = ((firstbyte&0x08)==0x08);
|
||||
lengh_present: bool = ((firstbyte&0x04)==0x04);
|
||||
epoch_low_bits: uint8 = (firstbyte&0x03);
|
||||
};
|
||||
|
||||
type SSLRecord(content_type: uint8, is_orig: bool) = record {
|
||||
version: uint16;
|
||||
# the epoch signalizes that a changecipherspec message has been received. Hence, everything with
|
||||
# an epoch > 0 should be encrypted
|
||||
|
@ -83,4 +109,11 @@ refine connection SSL_Conn += {
|
|||
}
|
||||
%}
|
||||
|
||||
function choose_record_type(firstbyte: uint8): bool
|
||||
%{
|
||||
uint16_t negotiated_version = zeek_analyzer()->GetNegotiatedVersion();
|
||||
if ( negotiated_version == DTLSv13 && ( (firstbyte & 0x20) == 0x20 ) )
|
||||
return true;
|
||||
return false;
|
||||
%}
|
||||
};
|
||||
|
|
|
@ -77,6 +77,7 @@ function version_ok(vers : uint16) : bool
|
|||
case TLSv13:
|
||||
case DTLSv10:
|
||||
case DTLSv12:
|
||||
case DTLSv13:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
@ -121,7 +122,8 @@ enum SSLVersions {
|
|||
|
||||
DTLSv10 = 0xFEFF,
|
||||
# DTLSv11 does not exist.
|
||||
DTLSv12 = 0xFEFD
|
||||
DTLSv12 = 0xFEFD,
|
||||
DTLSv13 = 0xFEFC
|
||||
};
|
||||
|
||||
enum SSLExtensions {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path ssl
|
||||
#open XXXX-XX-XX-XX-XX-XX
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert
|
||||
#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool
|
||||
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.168.36.147 33714 10.168.36.144 11111 DTLSv13 TLS_AES_128_GCM_SHA256 secp256r1 - F - - T CjCs - - -
|
||||
#close XXXX-XX-XX-XX-XX-XX
|
BIN
testing/btest/Traces/tls/dtls13-wolfssl.pcap
Normal file
BIN
testing/btest/Traces/tls/dtls13-wolfssl.pcap
Normal file
Binary file not shown.
6
testing/btest/scripts/base/protocols/ssl/dtls-13.test
Normal file
6
testing/btest/scripts/base/protocols/ssl/dtls-13.test
Normal file
|
@ -0,0 +1,6 @@
|
|||
# This tests a normal SSL connection and the log it outputs.
|
||||
|
||||
# @TEST-EXEC: zeek -C -r $TRACES/tls/dtls13-wolfssl.pcap %INPUT
|
||||
# @TEST-EXEC: btest-diff ssl.log
|
||||
# @TEST-EXEC: test ! -f dpd.log
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue