diff --git a/xhttp/xhttpserver/server.go b/xhttp/xhttpserver/server.go index 758cc85..01cac08 100644 --- a/xhttp/xhttpserver/server.go +++ b/xhttp/xhttpserver/server.go @@ -50,12 +50,6 @@ type Options struct { DisableHandlerLogger bool } -func logTLSInformation(l *zap.Logger, r *http.Request) { - l.Info( - "TLS information", - ) -} - // NewServerChain produces the standard constructor chain for a server, primarily using configuration. func NewServerChain(o Options, l *zap.Logger, fbs ...sallusthttp.FieldBuilder) alice.Chain { bs := sallusthttp.Builders{} @@ -74,7 +68,10 @@ func NewServerChain(o Options, l *zap.Logger, fbs ...sallusthttp.FieldBuilder) a func(next http.Handler) http.Handler { return http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) { requestLogger := bs.Build(request, l) - logTLSInformation(requestLogger, request) + requestLogger.Info( + "tls info", + connectionStateField("state", request.TLS), + ) next.ServeHTTP( response, diff --git a/xhttp/xhttpserver/zap.go b/xhttp/xhttpserver/zap.go new file mode 100644 index 0000000..26ce46b --- /dev/null +++ b/xhttp/xhttpserver/zap.go @@ -0,0 +1,104 @@ +// SPDX-FileCopyrightText: 2017 Comcast Cable Communications Management, LLC +// SPDX-License-Identifier: Apache-2.0 +package xhttpserver + +import ( + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +type stringArray []string + +func (sa stringArray) MarshalLogArray(enc zapcore.ArrayEncoder) error { + for _, s := range sa { + enc.AppendString(s) + } + + return nil +} + +type pkixName pkix.Name + +func (pn pkixName) MarshalLogObject(enc zapcore.ObjectEncoder) error { + enc.AddArray("organization", stringArray(pn.Organization)) + enc.AddArray("organizationalUnit", stringArray(pn.OrganizationalUnit)) + enc.AddString("commonName", pn.CommonName) + enc.AddString("serialNumber", pn.SerialNumber) + + return nil +} + +type certificate x509.Certificate + +func (c certificate) MarshalLogObject(enc zapcore.ObjectEncoder) error { + enc.AddObject("issuer", pkixName(c.Issuer)) + enc.AddObject("subject", pkixName(c.Subject)) + enc.AddArray("dnsNames", stringArray(c.DNSNames)) + enc.AddArray("emailAddresses", stringArray(c.EmailAddresses)) + enc.AddArray("issuingCertificateURL", stringArray(c.IssuingCertificateURL)) + enc.AddTime("notBefore", c.NotBefore) + enc.AddTime("notAfter", c.NotAfter) + + if c.SerialNumber != nil { + enc.AddString("serialNumber", c.SerialNumber.String()) + } else { + enc.AddString("serialNumber", "") + } + + return nil +} + +type certificates []*x509.Certificate + +func (cs certificates) MarshalLogArray(enc zapcore.ArrayEncoder) error { + for _, c := range cs { + if c != nil { + enc.AppendObject(certificate(*c)) + } + } + + return nil +} + +func tlsVersionToString(v uint16) string { + switch v { + case tls.VersionTLS10: + return "1.0" + + case tls.VersionTLS11: + return "1.1" + + case tls.VersionTLS12: + return "1.2" + + case tls.VersionTLS13: + return "1.3" + + case tls.VersionSSL30: //nolint:staticcheck + return "SSLv3" + + default: + return "unknown" + } +} + +type connectionState tls.ConnectionState + +func (cstate connectionState) MarshalLogObject(enc zapcore.ObjectEncoder) error { + enc.AddString("version", tlsVersionToString(cstate.Version)) + enc.AddArray("peerCertificates", certificates(cstate.PeerCertificates)) + + return nil +} + +func connectionStateField(field string, v *tls.ConnectionState) zap.Field { + if v != nil { + return zap.Object(field, connectionState(*v)) + } else { + return zap.Skip() + } +}