diff --git a/plugins/inputs/x509_cert/README.md b/plugins/inputs/x509_cert/README.md index 80f038a4a..cf2ced861 100644 --- a/plugins/inputs/x509_cert/README.md +++ b/plugins/inputs/x509_cert/README.md @@ -39,6 +39,9 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. ## Only output the leaf certificates and omit the root ones. # exclude_root_certs = false + ## Pad certificate serial number with zeroes to 128-bits. + # pad_serial_with_zeroes = false + ## Optional TLS Config # tls_ca = "/etc/telegraf/ca.pem" # tls_cert = "/etc/telegraf/cert.pem" diff --git a/plugins/inputs/x509_cert/sample.conf b/plugins/inputs/x509_cert/sample.conf index d1b94e41a..1c29fad9a 100644 --- a/plugins/inputs/x509_cert/sample.conf +++ b/plugins/inputs/x509_cert/sample.conf @@ -19,6 +19,9 @@ ## Only output the leaf certificates and omit the root ones. # exclude_root_certs = false + ## Pad certificate serial number with zeroes to 128-bits. + # pad_serial_with_zeroes = false + ## Optional TLS Config # tls_ca = "/etc/telegraf/ca.pem" # tls_cert = "/etc/telegraf/cert.pem" diff --git a/plugins/inputs/x509_cert/x509_cert.go b/plugins/inputs/x509_cert/x509_cert.go index 97097ded3..4962997f9 100644 --- a/plugins/inputs/x509_cert/x509_cert.go +++ b/plugins/inputs/x509_cert/x509_cert.go @@ -44,6 +44,7 @@ type X509Cert struct { Timeout config.Duration `toml:"timeout"` ServerName string `toml:"server_name"` ExcludeRootCerts bool `toml:"exclude_root_certs"` + PadSerial bool `toml:"pad_serial_with_zeroes"` Log telegraf.Logger `toml:"-"` common_tls.ClientConfig proxy.TCPProxy @@ -132,7 +133,7 @@ func (c *X509Cert) Gather(acc telegraf.Accumulator) error { for i, cert := range certs { fields := getFields(cert, now) - tags := getTags(cert, location.String()) + tags := c.getTags(cert, location.String()) // Extract the verification result err := results[i] @@ -215,7 +216,7 @@ func (c *X509Cert) Gather(acc telegraf.Accumulator) error { func (c *X509Cert) processCertificate(certificate *x509.Certificate, opts x509.VerifyOptions) error { chains, err := certificate.Verify(opts) if err != nil { - c.Log.Debugf("Invalid certificate %v", certificate.SerialNumber.Text(16)) + c.Log.Debugf("Invalid certificate %v", c.getSerialNumberString(certificate)) c.Log.Debugf(" cert DNS names: %v", certificate.DNSNames) c.Log.Debugf(" cert IP addresses: %v", certificate.IPAddresses) c.Log.Debugf(" cert subject: %v", certificate.Subject) @@ -466,11 +467,11 @@ func getFields(cert *x509.Certificate, now time.Time) map[string]interface{} { return fields } -func getTags(cert *x509.Certificate, location string) map[string]string { +func (c *X509Cert) getTags(cert *x509.Certificate, location string) map[string]string { tags := map[string]string{ "source": location, "common_name": cert.Subject.CommonName, - "serial_number": cert.SerialNumber.Text(16), + "serial_number": c.getSerialNumberString(cert), "signature_algorithm": cert.SignatureAlgorithm.String(), "public_key_algorithm": cert.PublicKeyAlgorithm.String(), } @@ -524,6 +525,13 @@ func (c *X509Cert) collectCertURLs() []*url.URL { return urls } +func (c *X509Cert) getSerialNumberString(cert *x509.Certificate) string { + if c.PadSerial { + return fmt.Sprintf("%016x", cert.SerialNumber) + } + return cert.SerialNumber.Text(16) +} + func init() { inputs.Add("x509_cert", func() telegraf.Input { return &X509Cert{ diff --git a/plugins/inputs/x509_cert/x509_cert_test.go b/plugins/inputs/x509_cert/x509_cert_test.go index bb4f72cc1..fa3960c99 100644 --- a/plugins/inputs/x509_cert/x509_cert_test.go +++ b/plugins/inputs/x509_cert/x509_cert_test.go @@ -482,6 +482,20 @@ func TestServerName(t *testing.T) { } } +func TestCertificateSerialNumberRetainsLeadingZeroes(t *testing.T) { + bi := &big.Int{} + bi.SetString("123456789abcdef", 16) + + plugin := &X509Cert{} + certificate := &x509.Certificate{ + SerialNumber: bi, + } + + require.Equal(t, "123456789abcdef", plugin.getSerialNumberString(certificate)) + plugin.PadSerial = true + require.Equal(t, "0123456789abcdef", plugin.getSerialNumberString(certificate)) +} + // Bases on code from // https://medium.com/@shaneutt/create-sign-x509-certificates-in-golang-8ac4ae49f903 func TestClassification(t *testing.T) {