# New SSL analyzer

**URL:** <https://community.zeek.org/t/new-ssl-analyzer/1847>\
**Category:** Development\
**Tags:** development\
**Created:** [March 28, 2011, 3:27pm UTC](https://community.zeek.org/t/new-ssl-analyzer/1847 "2011-03-28T15:27:23Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Seth\_Hall3](https://avatars.discourse-cdn.com/v4/letter/s/d6d6ee/32.png) [@Seth\_Hall3](https://community.zeek.org/u/Seth_Hall3)\
**Post date:** [March 28, 2011, 3:27pm UTC](https://community.zeek.org/t/new-ssl-analyzer/1847/1 "2011-03-28T15:27:23Z")

</div>

As I was working on the ssl.bro script last week, I realized that the core SSL analyzers (hand written and binpac) generated really strange events that seemed very different than the events that most of the other core analyzers generate. It turns out that those analyzers were storing some state about existing SSL sessions and generating events based on that information. I think it was storing too much internally and not even making all of it available at the scripting layer. I'll go through bullet points of changes and where I think a bit more work needs to be done.

- SSL & X509 related events are completely rewritten.  
&nbsp;&nbsp;event ssl\_client\_hello(c: connection, version: count, possible\_ts: time, session\_id: string, ciphers: count\_set)  
&nbsp;&nbsp;event ssl\_server\_hello(c: connection, version: count, possible\_ts: time, session\_id: string, cipher: count, comp\_method: count)  
&nbsp;&nbsp;event ssl\_extension(c: connection, code: count, val: string)  
&nbsp;&nbsp;event ssl\_established(c: connection)  
&nbsp;&nbsp;event ssl\_alert(c: connection, level: count, desc: count)

&nbsp;&nbsp;event x509\_certificate(c: connection, cert: X509, is\_server: bool, chain\_idx: count, chain\_len: count)  
&nbsp;&nbsp;event x509\_extension(c: connection, data: string)  
&nbsp;&nbsp;event x509\_error(c: connection, err: int, err\_string: string)  
&nbsp;&nbsp;event x509\_cert\_validated(c: connection)  
&nbsp;&nbsp;event x509\_cert\_body(c: connection, cert: string)

- In ssl\_client\_hello, I'm not currently extracting the compression methods supported for some reason, but I'll try to remember to add that soon.

- The possible\_ts fields in both "hello" events are the first 32bits of the random data section which some SSL libraries populate with a current time stamp.

- I changed the session\_id to a string instead of a table[count] of count like it was before (since it can be up to 32 bytes long). The table was really difficult to work with but it's much easier now that it's a string.

- There is a small issue where the ssl\_extension event is be generated before the ssl\_client\_hello event due to how the parser is parsing the hello record which is a little backward since the extensions are at the end of the hello record. Should I just include the SSL extensions in the hello events as a table? The follow up question is if it makes sense to just include the raw data for the extension even though there is a data structure there? Here's an example of printing the server\_name extension (i have to rip off the first 5 bytes which is a piece of the data structure for the extension)...

event ssl\_extension(c: connection, code: count, val: string)  
&nbsp;&nbsp;{  
&nbsp;&nbsp;if ( code == 0 )  
&nbsp;&nbsp;&nbsp;&nbsp;print fmt("ssl extension %d %s", code, sub(val, /^...../, ""));  
&nbsp;&nbsp;}

- The X509 data type has had some extra fields added to it about the certificate (like the serial number, notValidBefore, and notValidAfter fields).

- The chain\_idx and chain\_len values indicate which certificate is being looked at if it's part of a certificate full signing chain. The server's certificate will be chain\_idx == 1 and the root signing key will be chain\_idx==chain\_len. Intermediate certs will be somewhere between. 🙂 Is there a better way to represent this in the script land? I doesn't look very clean and isn't terribly obvious but I wasn't coming up with anything better.

- Certificate extraction now happens in scripting land with the x509\_cert\_body event (as a DER certificate). It can work on a cluster deployment this way (by printing remotely) and it's just generally more flexible. My initial testing doesn't actually show much difference in pushing the cert to script land or not pushing it there.

- Certificate and certificate chain validation can be controlled at the scripting land a bit more easily because I added a table with root CAs. Sites can even add local CAs to Bro's root CA list if they want to trust locally signed keys. It's just a table that yields DER encoded certificates. I have a script that can automatically generate the Bro script with all of Mozilla's root CAs too so we can ship the same trust model as Mozilla. The problem is that I'm building this X509\_STACK (OpenSSL terminology) with each instantiation of the SSL analyzer and it should probably only be done when certs are added or removed from the scripting land table and stored globally. Any guidance I could get on where/how to do this would help.

There is probably more, but this is all I can think of at the moment. Any and all feedback would be great! I'll get the code committed and pushed today.

Thanks!  
&nbsp;&nbsp;.Seth

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex011/uploads/zeek/original/1X/f09d732bc2cc7c7cc7e35db67cf4e1d5233ce7a7.png) [@system](https://community.zeek.org/u/system)\
**Post date:** [May 6, 2022, 3:39pm UTC](https://community.zeek.org/t/new-ssl-analyzer/1847/2 "2022-05-06T15:39:30Z")

</div>


