mirror of
https://github.com/zeek/zeek.git
synced 2025-10-16 21:48:21 +00:00
Added the ssl_session_ticket_handshake event and fixed a few SSL bugs.
This commit is contained in:
parent
c8839da069
commit
03646a8d55
3 changed files with 61 additions and 44 deletions
|
@ -280,6 +280,7 @@ event ssh_server_version%(c: connection, version: string%);
|
||||||
event ssl_client_hello%(c: connection, version: count, possible_ts: time, session_id: string, ciphers: count_set%);
|
event ssl_client_hello%(c: connection, version: count, possible_ts: time, session_id: string, ciphers: count_set%);
|
||||||
event ssl_server_hello%(c: connection, version: count, possible_ts: time, session_id: string, cipher: count, comp_method: count%);
|
event ssl_server_hello%(c: connection, version: count, possible_ts: time, session_id: string, cipher: count, comp_method: count%);
|
||||||
event ssl_extension%(c: connection, code: count, val: string%);
|
event ssl_extension%(c: connection, code: count, val: string%);
|
||||||
|
event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, ticket: string%);
|
||||||
event ssl_established%(c: connection%);
|
event ssl_established%(c: connection%);
|
||||||
event ssl_alert%(c: connection, level: count, desc: count%);
|
event ssl_alert%(c: connection, level: count, desc: count%);
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ refine connection SSL_Conn += {
|
||||||
if ( ssl_client_hello )
|
if ( ssl_client_hello )
|
||||||
{
|
{
|
||||||
vector<int>* cipher_suites = new vector<int>();
|
vector<int>* cipher_suites = new vector<int>();
|
||||||
if ( cipher_suites16 )
|
if ( cipher_suites16 )
|
||||||
std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(*cipher_suites));
|
std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(*cipher_suites));
|
||||||
else
|
else
|
||||||
std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(*cipher_suites), to_int());
|
std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(*cipher_suites), to_int());
|
||||||
|
@ -199,6 +199,18 @@ refine connection SSL_Conn += {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
function proc_session_ticket_handshake(rec: SessionTicketHandshake, is_orig: bool): bool
|
||||||
|
%{
|
||||||
|
if ( ssl_session_ticket_handshake )
|
||||||
|
{
|
||||||
|
BifEvent::generate_ssl_session_ticket_handshake(bro_analyzer(),
|
||||||
|
bro_analyzer()->Conn(),
|
||||||
|
${rec.ticket_lifetime_hint},
|
||||||
|
new StringVal(${rec.data}.length(), (const char*) ${rec.data}.data()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
|
||||||
function proc_ssl_extension(type: int, data: bytestring) : bool
|
function proc_ssl_extension(type: int, data: bytestring) : bool
|
||||||
%{
|
%{
|
||||||
|
@ -263,13 +275,14 @@ refine connection SSL_Conn += {
|
||||||
der_cert);
|
der_cert);
|
||||||
|
|
||||||
// Are there any X509 extensions?
|
// Are there any X509 extensions?
|
||||||
|
//printf("Number of x509 extensions: %d\n", X509_get_ext_count(pTemp));
|
||||||
if ( x509_extension && X509_get_ext_count(pTemp) > 0 )
|
if ( x509_extension && X509_get_ext_count(pTemp) > 0 )
|
||||||
{
|
{
|
||||||
int num_ext = X509_get_ext_count(pTemp);
|
int num_ext = X509_get_ext_count(pTemp);
|
||||||
for ( int k = 0; k < num_ext; ++k )
|
for ( int k = 0; k < num_ext; ++k )
|
||||||
{
|
{
|
||||||
unsigned char *pBuffer = 0;
|
unsigned char *pBuffer = 0;
|
||||||
int length = 0;
|
uint length = 0;
|
||||||
|
|
||||||
X509_EXTENSION* ex = X509_get_ext(pTemp, k);
|
X509_EXTENSION* ex = X509_get_ext(pTemp, k);
|
||||||
if (ex)
|
if (ex)
|
||||||
|
@ -277,7 +290,7 @@ refine connection SSL_Conn += {
|
||||||
ASN1_STRING *pString = X509_EXTENSION_get_data(ex);
|
ASN1_STRING *pString = X509_EXTENSION_get_data(ex);
|
||||||
length = ASN1_STRING_to_UTF8(&pBuffer, pString);
|
length = ASN1_STRING_to_UTF8(&pBuffer, pString);
|
||||||
//i2t_ASN1_OBJECT(&pBuffer, length, obj)
|
//i2t_ASN1_OBJECT(&pBuffer, length, obj)
|
||||||
|
printf("extension length: %u\n", length);
|
||||||
// -1 indicates an error.
|
// -1 indicates an error.
|
||||||
if ( length < 0 )
|
if ( length < 0 )
|
||||||
continue;
|
continue;
|
||||||
|
@ -436,6 +449,10 @@ refine typeattr Handshake += &let {
|
||||||
proc : bool = $context.connection.proc_handshake(this, rec.is_orig);
|
proc : bool = $context.connection.proc_handshake(this, rec.is_orig);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
refine typeattr SessionTicketHandshake += &let {
|
||||||
|
proc : bool = $context.connection.proc_session_ticket_handshake(this, rec.is_orig);
|
||||||
|
}
|
||||||
|
|
||||||
refine typeattr UnknownRecord += &let {
|
refine typeattr UnknownRecord += &let {
|
||||||
proc : bool = $context.connection.proc_unknown_record(rec);
|
proc : bool = $context.connection.proc_unknown_record(rec);
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,22 +57,15 @@ type SSLRecord(is_orig: bool) = record {
|
||||||
type RecordText(rec: SSLRecord, is_orig: bool) = case $context.connection.state() of {
|
type RecordText(rec: SSLRecord, is_orig: bool) = case $context.connection.state() of {
|
||||||
STATE_ABBREV_SERVER_ENCRYPTED, STATE_CLIENT_ENCRYPTED,
|
STATE_ABBREV_SERVER_ENCRYPTED, STATE_CLIENT_ENCRYPTED,
|
||||||
STATE_COMM_ENCRYPTED, STATE_CONN_ESTABLISHED
|
STATE_COMM_ENCRYPTED, STATE_CONN_ESTABLISHED
|
||||||
-> ciphertext : CiphertextRecord(rec, is_orig);
|
-> ciphertext : CiphertextRecord(rec);
|
||||||
default
|
default
|
||||||
-> plaintext : PlaintextRecord(rec, is_orig);
|
-> plaintext : PlaintextRecord(rec);
|
||||||
};
|
};
|
||||||
|
|
||||||
type PossibleEncryptedHandshake(rec: SSLRecord, is_orig: bool) = case $context.connection.state() of {
|
type PlaintextRecord(rec: SSLRecord) = case rec.content_type of {
|
||||||
# Deal with encrypted handshakes before the server cipher spec change.
|
|
||||||
STATE_CLIENT_FINISHED, STATE_CLIENT_ENCRYPTED
|
|
||||||
-> ct : CiphertextRecord(rec, is_orig);
|
|
||||||
default -> hs : Handshake(rec);
|
|
||||||
};
|
|
||||||
|
|
||||||
type PlaintextRecord(rec: SSLRecord, is_orig: bool) = case rec.content_type of {
|
|
||||||
CHANGE_CIPHER_SPEC -> ch_cipher : ChangeCipherSpec(rec);
|
CHANGE_CIPHER_SPEC -> ch_cipher : ChangeCipherSpec(rec);
|
||||||
ALERT -> alert : Alert(rec);
|
ALERT -> alert : Alert(rec);
|
||||||
HANDSHAKE -> handshake : PossibleEncryptedHandshake(rec, is_orig);
|
HANDSHAKE -> handshake : Handshake(rec);
|
||||||
APPLICATION_DATA -> app_data : ApplicationData(rec);
|
APPLICATION_DATA -> app_data : ApplicationData(rec);
|
||||||
V2_ERROR -> v2_error : V2Error(rec);
|
V2_ERROR -> v2_error : V2Error(rec);
|
||||||
V2_CLIENT_HELLO -> v2_client_hello : V2ClientHello(rec);
|
V2_CLIENT_HELLO -> v2_client_hello : V2ClientHello(rec);
|
||||||
|
@ -265,18 +258,19 @@ enum AnalyzerState {
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
enum HandshakeType {
|
enum HandshakeType {
|
||||||
HELLO_REQUEST = 0,
|
HELLO_REQUEST = 0,
|
||||||
CLIENT_HELLO = 1,
|
CLIENT_HELLO = 1,
|
||||||
SERVER_HELLO = 2,
|
SERVER_HELLO = 2,
|
||||||
CERTIFICATE = 11,
|
SESSION_TICKET = 4, # RFC 5077
|
||||||
SERVER_KEY_EXCHANGE = 12,
|
CERTIFICATE = 11,
|
||||||
CERTIFICATE_REQUEST = 13,
|
SERVER_KEY_EXCHANGE = 12,
|
||||||
SERVER_HELLO_DONE = 14,
|
CERTIFICATE_REQUEST = 13,
|
||||||
CERTIFICATE_VERIFY = 15,
|
SERVER_HELLO_DONE = 14,
|
||||||
CLIENT_KEY_EXCHANGE = 16,
|
CERTIFICATE_VERIFY = 15,
|
||||||
FINISHED = 20,
|
CLIENT_KEY_EXCHANGE = 16,
|
||||||
CERTIFICATE_URL = 21, # RFC 3546
|
FINISHED = 20,
|
||||||
CERTIFICATE_STATUS = 22, # RFC 3546
|
CERTIFICATE_URL = 21, # RFC 3546
|
||||||
|
CERTIFICATE_STATUS = 22, # RFC 3546
|
||||||
};
|
};
|
||||||
|
|
||||||
%code{
|
%code{
|
||||||
|
@ -286,6 +280,7 @@ enum HandshakeType {
|
||||||
case HELLO_REQUEST: return string("HELLO_REQUEST");
|
case HELLO_REQUEST: return string("HELLO_REQUEST");
|
||||||
case CLIENT_HELLO: return string("CLIENT_HELLO");
|
case CLIENT_HELLO: return string("CLIENT_HELLO");
|
||||||
case SERVER_HELLO: return string("SERVER_HELLO");
|
case SERVER_HELLO: return string("SERVER_HELLO");
|
||||||
|
case SESSION_TICKET: return string("SESSION_TICKET");
|
||||||
case CERTIFICATE: return string("CERTIFICATE");
|
case CERTIFICATE: return string("CERTIFICATE");
|
||||||
case SERVER_KEY_EXCHANGE: return string("SERVER_KEY_EXCHANGE");
|
case SERVER_KEY_EXCHANGE: return string("SERVER_KEY_EXCHANGE");
|
||||||
case CERTIFICATE_REQUEST: return string("CERTIFICATE_REQUEST");
|
case CERTIFICATE_REQUEST: return string("CERTIFICATE_REQUEST");
|
||||||
|
@ -457,8 +452,7 @@ type V2ServerHello(rec: SSLRecord) = record {
|
||||||
cert_data : bytestring &length = cert_len;
|
cert_data : bytestring &length = cert_len;
|
||||||
ciphers : uint24[ciph_len/3];
|
ciphers : uint24[ciph_len/3];
|
||||||
conn_id_data : bytestring &length = conn_id_len;
|
conn_id_data : bytestring &length = conn_id_len;
|
||||||
} #&length = 8 + cert_len + ciph_len + conn_id_len,
|
} &let {
|
||||||
&let {
|
|
||||||
state_changed : bool =
|
state_changed : bool =
|
||||||
(session_id_hit > 0 ?
|
(session_id_hit > 0 ?
|
||||||
$context.connection.transition(STATE_CLIENT_HELLO_RCVD,
|
$context.connection.transition(STATE_CLIENT_HELLO_RCVD,
|
||||||
|
@ -608,7 +602,7 @@ type CertificateVerify(rec: SSLRecord) = record {
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
# The finished messages are always sent after encryption is in effect,
|
# The finished messages are always sent after encryption is in effect,
|
||||||
# so we will not be able to read those message.
|
# so we will not be able to read those messages.
|
||||||
type Finished(rec: SSLRecord) = record {
|
type Finished(rec: SSLRecord) = record {
|
||||||
cont : bytestring &restofdata &transient;
|
cont : bytestring &restofdata &transient;
|
||||||
} &let {
|
} &let {
|
||||||
|
@ -620,13 +614,17 @@ type Finished(rec: SSLRecord) = record {
|
||||||
$context.connection.lost_track();
|
$context.connection.lost_track();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type SessionTicketHandshake(rec: SSLRecord) = record {
|
||||||
|
ticket_lifetime_hint: uint32;
|
||||||
|
data: bytestring &restofdata;
|
||||||
|
};
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# V3 Handshake Protocol (7.)
|
# V3 Handshake Protocol (7.)
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
type UnknownHandshake(hs: Handshake, is_orig: bool) = record {
|
type UnknownHandshake(hs: Handshake, is_orig: bool) = record {
|
||||||
cont : bytestring &restofdata &transient;
|
data : bytestring &restofdata &transient;
|
||||||
} &let {
|
} &let {
|
||||||
state_changed : bool = $context.connection.lost_track();
|
state_changed : bool = $context.connection.lost_track();
|
||||||
};
|
};
|
||||||
|
@ -636,19 +634,20 @@ type Handshake(rec: SSLRecord) = record {
|
||||||
length : uint24;
|
length : uint24;
|
||||||
|
|
||||||
body : case msg_type of {
|
body : case msg_type of {
|
||||||
HELLO_REQUEST -> hello_request : HelloRequest(rec);
|
HELLO_REQUEST -> hello_request : HelloRequest(rec);
|
||||||
CLIENT_HELLO -> client_hello : ClientHello(rec);
|
CLIENT_HELLO -> client_hello : ClientHello(rec);
|
||||||
SERVER_HELLO -> server_hello : ServerHello(rec);
|
SERVER_HELLO -> server_hello : ServerHello(rec);
|
||||||
CERTIFICATE -> certificate : Certificate(rec);
|
SESSION_TICKET -> session_ticket : SessionTicketHandshake(rec);
|
||||||
SERVER_KEY_EXCHANGE -> server_key_exchange : ServerKeyExchange(rec);
|
CERTIFICATE -> certificate : Certificate(rec);
|
||||||
CERTIFICATE_REQUEST -> certificate_request : CertificateRequest(rec);
|
SERVER_KEY_EXCHANGE -> server_key_exchange : ServerKeyExchange(rec);
|
||||||
SERVER_HELLO_DONE -> server_hello_done : ServerHelloDone(rec);
|
CERTIFICATE_REQUEST -> certificate_request : CertificateRequest(rec);
|
||||||
CERTIFICATE_VERIFY -> certificate_verify : CertificateVerify(rec);
|
SERVER_HELLO_DONE -> server_hello_done : ServerHelloDone(rec);
|
||||||
CLIENT_KEY_EXCHANGE -> client_key_exchange : ClientKeyExchange(rec);
|
CERTIFICATE_VERIFY -> certificate_verify : CertificateVerify(rec);
|
||||||
FINISHED -> finished : Finished(rec);
|
CLIENT_KEY_EXCHANGE -> client_key_exchange : ClientKeyExchange(rec);
|
||||||
CERTIFICATE_URL -> certificate_url : bytestring &restofdata &transient;
|
FINISHED -> finished : Finished(rec);
|
||||||
CERTIFICATE_STATUS -> certificate_status : bytestring &restofdata &transient;
|
CERTIFICATE_URL -> certificate_url : bytestring &restofdata &transient;
|
||||||
default -> unknown_handshake : UnknownHandshake(this, rec.is_orig);
|
CERTIFICATE_STATUS -> certificate_status : bytestring &restofdata &transient;
|
||||||
|
default -> unknown_handshake : UnknownHandshake(this, rec.is_orig);
|
||||||
} &length = to_int()(length);
|
} &length = to_int()(length);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -663,7 +662,7 @@ type UnknownRecord(rec: SSLRecord) = record {
|
||||||
state_changed : bool = $context.connection.lost_track();
|
state_changed : bool = $context.connection.lost_track();
|
||||||
};
|
};
|
||||||
|
|
||||||
type CiphertextRecord(rec: SSLRecord, is_orig: bool) = record {
|
type CiphertextRecord(rec: SSLRecord) = record {
|
||||||
cont : bytestring &restofdata &transient;
|
cont : bytestring &restofdata &transient;
|
||||||
} &let {
|
} &let {
|
||||||
state_changed : bool =
|
state_changed : bool =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue