@@ -36,6 +36,7 @@ var ignorefsmerr = flag.Bool("ignorefsmerr", false, "Ignore TCP FSM errors")
3636var verbose = flag .Bool ("verbose" , false , "Be verbose" )
3737var debug = flag .Bool ("debug" , false , "Display debug information" )
3838var quiet = flag .Bool ("quiet" , false , "Be quiet regarding errors" )
39+ var partial = flag .Bool ("partial" , true , "Output partial TLS Sessions, e.g. where we don't see all three of client hello, server hello and certificate" )
3940
4041// capture
4142var iface = flag .String ("i" , "eth0" , "Interface to read packets from" )
@@ -101,6 +102,11 @@ func (factory *tcpStreamFactory) New(net, transport gopacket.Flow, tcp *layers.T
101102 optchecker : reassembly .NewTCPOptionCheck (),
102103 tlsSession : d4tls.TLSSession {},
103104 }
105+
106+ // Set network information in the TLSSession
107+ cip , sip , cp , sp := getIPPorts (stream )
108+ stream .tlsSession .SetNetwork (cip , sip , cp , sp )
109+
104110 return stream
105111}
106112
@@ -134,6 +140,7 @@ type tcpStream struct {
134140 urls []string
135141 ident string
136142 tlsSession d4tls.TLSSession
143+ queued bool
137144 ignorefsmerr bool
138145 nooptcheck bool
139146 checksum bool
@@ -181,6 +188,7 @@ func (t *tcpStream) ReassembledSG(sg reassembly.ScatterGather, ac reassembly.Ass
181188 }
182189 data := sg .Fetch (length )
183190 if t .isTLS {
191+
184192 if length > 0 {
185193 // We attempt to decode TLS
186194 tls := & etls.ETLS {}
@@ -195,13 +203,18 @@ func (t *tcpStream) ReassembledSG(sg reassembly.ScatterGather, ac reassembly.Ass
195203 //Debug("TLS: %s\n", gopacket.LayerDump(tls))
196204 // Debug("TLS: %s\n", gopacket.LayerGoString(tls))
197205 if tls .Handshake != nil {
206+
207+ // If the timestamp has not been set, we set it for the first time.
208+ if t .tlsSession .Record .Timestamp .IsZero () {
209+ info := sg .CaptureInfo (0 )
210+ t .tlsSession .SetTimestamp (info .Timestamp )
211+ }
212+
198213 for _ , tlsrecord := range tls .Handshake {
199214 switch tlsrecord .ETLSHandshakeMsgType {
200215 // Client Hello
201216 case 1 :
202- info := sg .CaptureInfo (0 )
203- cip , sip , cp , sp := getIPPorts (t )
204- t .tlsSession .PopulateClientHello (tlsrecord .ETLSHandshakeClientHello , cip , sip , cp , sp , info .Timestamp )
217+ t .tlsSession .PopulateClientHello (tlsrecord .ETLSHandshakeClientHello )
205218 t .tlsSession .D4Fingerprinting ("ja3" )
206219 // Server Hello
207220 case 2 :
@@ -210,14 +223,15 @@ func (t *tcpStream) ReassembledSG(sg reassembly.ScatterGather, ac reassembly.Ass
210223 // Server Certificate
211224 case 11 :
212225 t .tlsSession .PopulateCertificate (tlsrecord .ETLSHandshakeCertificate )
213-
214226 t .tlsSession .D4Fingerprinting ("tlsh" )
215- // If we get a cert, we consider the handshake as finished and ready to ship to D4
216- queueSession (t .tlsSession )
217- default :
218- break
219227 }
220228 }
229+
230+ // If the handshake is considered finished and we have not yet outputted it we ship it to output.
231+ if t .tlsSession .HandshakeComplete () && ! t .queued {
232+ t .queueSession ()
233+ }
234+
221235 }
222236 }
223237 }
@@ -235,6 +249,12 @@ func getIPPorts(t *tcpStream) (string, string, string, string) {
235249}
236250
237251func (t * tcpStream ) ReassemblyComplete (ac reassembly.AssemblerContext ) bool {
252+ // If the handshakre has not yet been outputted, but there are some information such as
253+ // either the client hello or the server hello, we also output a partial.
254+ if * partial && ! t .queued && t .tlsSession .HandshakeAny () {
255+ t .queueSession ()
256+ }
257+
238258 // remove connection from the pool
239259 return true
240260}
@@ -288,7 +308,7 @@ func main() {
288308 signal .Notify (signalChan , os .Interrupt )
289309
290310 // Job chan to hold Completed sessions to write
291- jobQ = make (chan d4tls.TLSSession , 100 )
311+ jobQ = make (chan d4tls.TLSSession , 4096 )
292312 cancelC := make (chan string )
293313
294314 // We start a worker to send the processed TLS connection the outside world
@@ -387,10 +407,13 @@ func main() {
387407 w .Wait ()
388408}
389409
390- // Tries to enqueue or false
391- func queueSession (t d4tls.TLSSession ) bool {
410+ // queueSession tries to enqueue the tlsSession for output
411+ // returns true if it succeeded or false if it failed to publish the
412+ // tlsSession for output
413+ func (t * tcpStream ) queueSession () bool {
414+ t .queued = true
392415 select {
393- case jobQ <- t :
416+ case jobQ <- t . tlsSession :
394417 return true
395418 default :
396419 return false
@@ -414,7 +437,6 @@ func processCompletedSession(cancelC <-chan string, jobQ <-chan d4tls.TLSSession
414437}
415438
416439func output (t d4tls.TLSSession ) {
417-
418440 jsonRecord , _ := json .MarshalIndent (t .Record , "" , " " )
419441
420442 // If an output folder was specified for certificates
0 commit comments