mirror of
https://github.com/zeek/zeek.git
synced 2025-10-15 04:58:21 +00:00
141 lines
3.2 KiB
JavaScript
141 lines
3.2 KiB
JavaScript
# $Id:$
|
|
|
|
# binpac analyzer representing the SSLv3 record layer
|
|
#
|
|
# This additional layering in the analyzer hierarchy is necessary due to
|
|
# fragmentation that can be introduced in the SSL record layer.
|
|
|
|
%include binpac.pac
|
|
%include bro.pac
|
|
|
|
analyzer SSLRecordLayer withcontext {
|
|
analyzer : SSLRecordLayerAnalyzer;
|
|
flow : SSLRecordLayerFlow;
|
|
};
|
|
|
|
%include ssl-defs.pac
|
|
|
|
%extern{
|
|
#include "ssl_pac.h"
|
|
using binpac::SSL::SSLAnalyzer;
|
|
%}
|
|
|
|
extern type const_bytestring;
|
|
|
|
|
|
type SSLPDU = record {
|
|
head0 : uint8;
|
|
head1 : uint8;
|
|
head2 : uint8;
|
|
head3 : uint8;
|
|
head4 : uint8;
|
|
fragment : bytestring &restofdata;
|
|
} &length = 5 + length, &byteorder = bigendian, &let {
|
|
version : int =
|
|
$context.analyzer.determine_ssl_version(head0, head1, head2);
|
|
|
|
length : int = case version of {
|
|
UNKNOWN_VERSION -> 0;
|
|
SSLv20 -> (((head0 & 0x7f) << 8) | head1) - 3;
|
|
default -> (head3 << 8) | head4;
|
|
};
|
|
|
|
fw : bool = case version of {
|
|
UNKNOWN_VERSION ->
|
|
$context.analyzer.forward_record(const_bytestring(),
|
|
UNKNOWN_OR_V2_ENCRYPTED, UNKNOWN_VERSION,
|
|
$context.flow.is_orig)
|
|
&& $context.flow.discard_data();
|
|
|
|
SSLv20 -> $context.analyzer.forward_v2_record(head2, head3, head4,
|
|
fragment, $context.flow.is_orig);
|
|
default -> $context.analyzer.forward_record(fragment, head0,
|
|
(head1 << 8) | head2, $context.flow.is_orig);
|
|
};
|
|
};
|
|
|
|
# binpac-specific definitions
|
|
|
|
analyzer SSLRecordLayerAnalyzer {
|
|
upflow = SSLRecordLayerFlow(true);
|
|
downflow = SSLRecordLayerFlow(false);
|
|
|
|
%member{
|
|
SSLAnalyzer* ssl_analyzer_;
|
|
|
|
int ssl_version_;
|
|
int record_length_;
|
|
%}
|
|
|
|
%init{
|
|
ssl_analyzer_ = 0;
|
|
ssl_version_ = UNKNOWN_VERSION;
|
|
record_length_ = 0;
|
|
%}
|
|
|
|
%eof{
|
|
ssl_analyzer_->FlowEOF(true);
|
|
ssl_analyzer_->FlowEOF(false);
|
|
%}
|
|
|
|
function set_ssl_analyzer(a : SSLAnalyzer) : void
|
|
%{ ssl_analyzer_ = a; %}
|
|
|
|
function ssl_version() : int %{ return ssl_version_; %}
|
|
function record_length() : int %{ return record_length_; %}
|
|
|
|
function determine_ssl_version(head0 : uint8, head1 : uint8,
|
|
head2 : uint8) : int
|
|
%{
|
|
if ( head0 >= 20 && head0 <= 23 &&
|
|
head1 == 0x03 && head2 < 0x03 )
|
|
// This is most probably SSL version 3.
|
|
ssl_version_ = (head1 << 8) | head2;
|
|
|
|
else if ( head0 >= 128 && head2 < 5 && head2 != 3 )
|
|
// Not very strong evidence, but we suspect
|
|
// this to be SSLv2.
|
|
ssl_version_ = SSLv20;
|
|
|
|
else
|
|
ssl_version_ = UNKNOWN_VERSION;
|
|
|
|
return ssl_version_;
|
|
%}
|
|
|
|
function forward_record(fragment : const_bytestring, type : int,
|
|
version : uint16, is_orig : bool) : bool
|
|
%{
|
|
return ssl_analyzer_->next_record(fragment, type,
|
|
version, is_orig);
|
|
%}
|
|
|
|
function forward_v2_record(b1 : uint8, b2 : uint8, b3 : uint8,
|
|
fragment : const_bytestring,
|
|
is_orig : bool) : bool
|
|
%{
|
|
uint8* buffer = new uint8[2 + fragment.length()];
|
|
|
|
// Byte 1 is the record type.
|
|
buffer[0] = b2;
|
|
buffer[1] = b3;
|
|
|
|
memcpy(buffer + 2, fragment.begin(), fragment.length());
|
|
const_bytestring bs(buffer, 2 + fragment.length());
|
|
|
|
bool ret = ssl_analyzer_->next_record(bs, 300 + b1, SSLv20,
|
|
is_orig);
|
|
delete [] buffer;
|
|
return ret;
|
|
%}
|
|
};
|
|
|
|
flow SSLRecordLayerFlow(is_orig : bool) {
|
|
flowunit = SSLPDU withcontext(connection, this);
|
|
|
|
function discard_data() : bool
|
|
%{
|
|
flow_buffer_->DiscardData();
|
|
return true;
|
|
%}
|
|
};
|