fleet/orbit/pkg/cryptoinfo/parse_certificate.go
2023-11-01 20:11:35 -06:00

100 lines
3.2 KiB
Go

// based on github.com/kolide/launcher/pkg/osquery/tables
package cryptoinfo
import (
"crypto/x509"
"crypto/x509/pkix"
"fmt"
"net"
"net/url"
"time"
)
type certExtract struct {
CRLDistributionPoints []string
DNSNames []string
EmailAddresses []string
ExcludedDNSDomains []string
ExcludedEmailAddresses []string
ExcludedIPRanges []*net.IPNet
ExcludedURIDomains []string
IPAddresses []net.IP
Issuer pkix.Name
IssuerParsed string
IssuingCertificateURL []string
KeyUsage int
KeyUsageParsed []string
NotBefore, NotAfter time.Time
OCSPServer []string
PermittedDNSDomains []string
PermittedDNSDomainsCritical bool
PermittedEmailAddresses []string
PermittedIPRanges []*net.IPNet
PermittedURIDomains []string
PublicKeyAlgorithm string
SerialNumber string
SignatureAlgorithm string
Subject pkix.Name
SubjectParsed string
URIs []*url.URL
Version int
}
// parseCertificate parses a certificate from a stream of bytes. We use this, instead of a bare x509.ParseCertificate, to handle some
// string conversions, and bitfield enumerations.
func parseCertificate(certBytes []byte) (interface{}, error) {
c, err := x509.ParseCertificate(certBytes)
if err != nil {
return nil, fmt.Errorf("parsing certificate: %w", err)
}
return extractCert(c)
}
func extractCert(c *x509.Certificate) (interface{}, error) {
return &certExtract{
CRLDistributionPoints: c.CRLDistributionPoints,
DNSNames: c.DNSNames,
EmailAddresses: c.EmailAddresses,
IPAddresses: c.IPAddresses,
Issuer: c.Issuer,
IssuerParsed: c.Issuer.String(),
IssuingCertificateURL: c.IssuingCertificateURL,
KeyUsage: int(c.KeyUsage),
KeyUsageParsed: keyUsageToStrings(c.KeyUsage),
NotAfter: c.NotAfter,
NotBefore: c.NotBefore,
OCSPServer: c.OCSPServer,
PublicKeyAlgorithm: c.PublicKeyAlgorithm.String(),
SerialNumber: c.SerialNumber.String(),
SignatureAlgorithm: c.SignatureAlgorithm.String(),
Subject: c.Subject,
SubjectParsed: c.Subject.String(),
URIs: c.URIs,
Version: c.Version,
}, nil
}
var keyUsageBits = map[x509.KeyUsage]string{
x509.KeyUsageDigitalSignature: "Digital Signature",
x509.KeyUsageContentCommitment: "Content Commitment",
x509.KeyUsageKeyEncipherment: "Key Encipherment",
x509.KeyUsageDataEncipherment: "Data Encipherment",
x509.KeyUsageKeyAgreement: "Key Agreement",
x509.KeyUsageCertSign: "Certificate Sign",
x509.KeyUsageCRLSign: "CRL Sign",
x509.KeyUsageEncipherOnly: "Encipher Only",
x509.KeyUsageDecipherOnly: "Decipher Only",
}
func keyUsageToStrings(k x509.KeyUsage) []string {
var usage []string
for usageBit, usageMeaning := range keyUsageBits {
if k&usageBit != 0 {
usage = append(usage, usageMeaning)
}
}
return usage
}