diff --git a/Makefile b/Makefile index d4a583b..23b5c6a 100644 --- a/Makefile +++ b/Makefile @@ -44,4 +44,5 @@ cover: .PHONY: clean clean: + find ./bin ! -name '.gitignore' -type f -exec rm -vrf {} + rm -v *.txt *.pcap* diff --git a/layers/http.go b/layers/http.go index 30adc3e..cb82158 100644 --- a/layers/http.go +++ b/layers/http.go @@ -3,6 +3,7 @@ package layers import ( "bufio" "bytes" + "encoding/json" "fmt" "net/http" "net/http/httputil" @@ -78,3 +79,47 @@ func (h *HTTPMessage) Parse(data []byte) error { } func (h *HTTPMessage) NextLayer() (layer string, payload []byte) { return } + +type HTTPRequestWrapper struct { + Request HTTPRequest `json:"http_request"` +} + +type HTTPRequest struct { + Host string `json:"host,omitempty"` + URI string `json:"uri,omitempty"` + Method string `json:"method,omitempty"` + Proto string `json:"proto,omitempty"` + ContentLength int `json:"content-length,omitempty"` + Header http.Header `json:"header,omitempty"` +} + +type HTTPResponseWrapper struct { + Response HTTPResponse `json:"http_response"` +} + +type HTTPResponse struct { + Proto string `json:"proto,omitempty"` + Status string `json:"status,omitempty"` + ContentLength int `json:"content-length,omitempty"` + Header http.Header `json:"header,omitempty"` +} + +func (h *HTTPMessage) MarshalJSON() ([]byte, error) { + if h.Request != nil { + return json.Marshal(&HTTPRequestWrapper{Request: HTTPRequest{ + Host: h.Request.Host, + URI: h.Request.RequestURI, + Method: h.Request.Method, + Proto: h.Request.Proto, + ContentLength: int(h.Request.ContentLength), + Header: h.Request.Header, + }}) + } else if h.Response != nil { + return json.Marshal(&HTTPResponseWrapper{Response: HTTPResponse{ + Proto: h.Response.Proto, + Status: h.Response.Status, + ContentLength: int(h.Response.ContentLength), + Header: h.Response.Header}}) + } + return nil, fmt.Errorf("both request and response are empty") +} diff --git a/layers/tls.go b/layers/tls.go index 1d798ba..10bb5b1 100644 --- a/layers/tls.go +++ b/layers/tls.go @@ -3,6 +3,7 @@ package layers import ( "encoding/binary" "encoding/hex" + "encoding/json" "fmt" "strings" ) @@ -129,6 +130,47 @@ type TLSClientHello struct { ALPN []string } +type TLSClientHelloRequestWrapper struct { + Request TLSClientHelloRequest `json:"tls_request"` +} + +type TLSClientHelloRequest struct { + SNI string `json:"sni,omitempty"` + Type string `json:"type,omitempty"` + Version string `json:"version,omitempty"` + SessionID string `json:"session_id,omitempty"` + CipherSuites []string `json:"cipher_suites,omitempty"` + Extensions []string `json:"extensions,omitempty"` + ALPN []string `json:"alpn,omitempty"` +} + +func (tch *TLSClientHello) MarshalJSON() ([]byte, error) { + cs := make([]string, 0, len(tch.CipherSuites)) + for _, c := range tch.CipherSuites { + cs = append(cs, c.String()) + } + es := make([]string, 0, len(tch.Extensions)) + for _, e := range tch.Extensions { + es = append(es, e.String()) + } + var ver, sn string + if tch.Version != nil { + ver = tch.Version.String() + } + if tch.ServerName != nil { + sn = tch.ServerName.SNName + } + return json.Marshal(&TLSClientHelloRequestWrapper{Request: TLSClientHelloRequest{ + SNI: sn, + Type: fmt.Sprintf("%s (%d)", tch.TypeDesc, tch.Type), + Version: ver, + SessionID: tch.SessionID, + CipherSuites: cs, + Extensions: es, + ALPN: tch.ALPN, + }}) +} + func (tch *TLSClientHello) String() string { return fmt.Sprintf(` - Type: %s (%d) - Length: %d @@ -286,6 +328,44 @@ type TLSServerHello struct { SupportedVersion *TLSVersion } +type TLSServerHelloResponseWrapper struct { + Response TLSServerHelloResponse `json:"tls_response"` +} + +type TLSServerHelloResponse struct { + Type string `json:"type,omitempty"` + Version string `json:"version,omitempty"` + SessionID string `json:"session_id,omitempty"` + CipherSuite string `json:"cipher_suite,omitempty"` + Extensions []string `json:"extensions,omitempty"` + SupportedVersion string `json:"supported_version,omitempty"` +} + +func (tsh *TLSServerHello) MarshalJSON() ([]byte, error) { + es := make([]string, 0, len(tsh.Extensions)) + for _, e := range tsh.Extensions { + es = append(es, e.String()) + } + var ver, supver, cs string + if tsh.Version != nil { + ver = tsh.Version.String() + } + if tsh.SupportedVersion != nil { + supver = tsh.SupportedVersion.String() + } + if tsh.CipherSuite != nil { + cs = tsh.CipherSuite.String() + } + return json.Marshal(&TLSServerHelloResponseWrapper{Response: TLSServerHelloResponse{ + Type: fmt.Sprintf("%s (%d)", tsh.TypeDesc, tsh.Type), + Version: ver, + SessionID: tsh.SessionID, + CipherSuite: cs, + Extensions: es, + SupportedVersion: supver, + }}) +} + func (tsh *TLSServerHello) String() string { return fmt.Sprintf(` - Type: %s (%d) - Length: %d