Skip to content

Commit

Permalink
Do not materialise labels when comparing certs
Browse files Browse the repository at this point in the history
  • Loading branch information
kokes authored and paullaffitte committed Mar 22, 2024
1 parent b33c43a commit 03c48bc
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 20 deletions.
108 changes: 88 additions & 20 deletions internal/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,28 +313,91 @@ func (exporter *Exporter) collectMatchingPaths(pattern string, format certificat
return output, outputErrors
}

// compareCertificates compares labels of these two certificates
// and returns true if they are the same
// It would normally run `.getLabels` on both cert/ref combinations,
// but this is a very allocation-heavy method, so we'll unroll it here
func (exporter *Exporter) compareCertificates(
leftCert *parsedCertificate,
leftRef *certificateRef,
rightCert *parsedCertificate,
rightRef *certificateRef,
) bool {
lhsLabels := exporter.getLabels(leftCert, leftRef)
rhsLabels := exporter.getLabels(rightCert, rightRef)
// compare base labels
if leftRef.format != rightRef.format {
return false
}
if filepath.Base(leftRef.path) != filepath.Base(rightRef.path) {
return false
}
if leftRef.format != certificateFormatKubeSecret {
if trimComponents(leftRef.path, exporter.TrimPathComponents) != trimComponents(rightRef.path, exporter.TrimPathComponents) {
return false
}
} else {
if leftRef.kubeSecretKey != rightRef.kubeSecretKey {
return false
}
// secret namespace
if strings.Split(leftRef.path, "/")[1] != strings.Split(rightRef.path, "/")[1] {
return false
}
}

if len(lhsLabels) != len(rhsLabels) {
// non-base labels
if leftCert.cert.SerialNumber.String() != rightCert.cert.SerialNumber.String() {
return false
}
if !comparePkix(&leftCert.cert.Issuer, &rightCert.cert.Issuer) {
return false
}
if !comparePkix(&leftCert.cert.Subject, &rightCert.cert.Subject) {
return false
}

for key, value := range lhsLabels {
if rhsLabels[key] != value {
if leftRef.format == certificateFormatYAML {
// embedded_kind
if strings.TrimRight(strings.Split(leftCert.yqMatchExpr, ".")[1], "s") != strings.TrimRight(strings.Split(rightCert.yqMatchExpr, ".")[1], "s") {
return false
}
}
if leftCert.userID != rightCert.userID {
return false
}

return true
}

func comparePkix(left *pkix.Name, right *pkix.Name) bool {
if first(left.Country) != first(right.Country) {
return false
}
if first(left.StreetAddress) != first(right.StreetAddress) {
return false
}
if first(left.Locality) != first(right.Locality) {
return false
}
if first(left.Organization) != first(right.Organization) {
return false
}
if first(left.OrganizationalUnit) != first(right.OrganizationalUnit) {
return false
}
if left.CommonName != right.CommonName {
return false
}

return true
}

func first[T any](arr []T) T {
if len(arr) == 0 {
return *new(T)
}
return arr[0]
}

func (exporter *Exporter) getLabels(certData *parsedCertificate, ref *certificateRef) map[string]string {
labels := exporter.getBaseLabels(ref)

Expand All @@ -354,20 +417,25 @@ func (exporter *Exporter) getLabels(certData *parsedCertificate, ref *certificat
return labels
}

func trimComponents(filepath string, trimCount int) string {
if trimCount == 0 {
return filepath
}
pathComponents := strings.Split(filepath, "/")
prefix := ""
if pathComponents[0] == "" {
trimCount++
prefix = "/"
}
return path.Join(prefix, path.Join(pathComponents[trimCount:]...))
}

func (exporter *Exporter) getBaseLabels(ref *certificateRef) map[string]string {
labels := map[string]string{}

if ref.format != certificateFormatKubeSecret {
trimComponentsCount := exporter.TrimPathComponents
pathComponents := strings.Split(ref.path, "/")
prefix := ""
if pathComponents[0] == "" {
trimComponentsCount++
prefix = "/"
}

labels["filename"] = filepath.Base(ref.path)
labels["filepath"] = path.Join(prefix, path.Join(pathComponents[trimComponentsCount:]...))
labels["filepath"] = trimComponents(ref.path, exporter.TrimPathComponents)
} else {
labels["secret_name"] = filepath.Base(ref.path)
labels["secret_namespace"] = strings.Split(ref.path, "/")[1]
Expand Down Expand Up @@ -401,27 +469,27 @@ func (exporter *Exporter) unzipLabels(labels map[string]string) ([]string, []str

func fillLabelsFromName(name *pkix.Name, prefix string, output map[string]string) {
if len(name.Country) > 0 {
output[fmt.Sprintf("%s_C", prefix)] = name.Country[0]
output[prefix+"_C"] = name.Country[0]
}

if len(name.StreetAddress) > 0 {
output[fmt.Sprintf("%s_ST", prefix)] = name.StreetAddress[0]
output[prefix+"_ST"] = name.StreetAddress[0]
}

if len(name.Locality) > 0 {
output[fmt.Sprintf("%s_L", prefix)] = name.Locality[0]
output[prefix+"_L"] = name.Locality[0]
}

if len(name.Organization) > 0 {
output[fmt.Sprintf("%s_O", prefix)] = name.Organization[0]
output[prefix+"_O"] = name.Organization[0]
}

if len(name.OrganizationalUnit) > 0 {
output[fmt.Sprintf("%s_OU", prefix)] = name.OrganizationalUnit[0]
output[prefix+"_OU"] = name.OrganizationalUnit[0]
}

if len(name.CommonName) > 0 {
output[fmt.Sprintf("%s_CN", prefix)] = name.CommonName
output[prefix+"_CN"] = name.CommonName
}
}

Expand Down
20 changes: 20 additions & 0 deletions internal/exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,26 @@ func TestDuplicateCertificate2(t *testing.T) {
})
}

func BenchmarkParsingCertificates(b *testing.B) {
tempdir := b.TempDir()
notBefore := time.Now()
n := 1000
filenames := make([]string, 0, n)
for i := 0; i < n; i++ {
filename := path.Join(tempdir, fmt.Sprintf("cert%d.pem", i))
filenames = append(filenames, filename)
generateCertificate(filename, notBefore)
}
exporter := Exporter{Files: filenames}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, errs := exporter.parseAllCertificates()
if len(errs) != 0 {
b.Fatalf("unexpected errors: %v", errs)
}
}
}

func TestBadBase64StringInYAML(t *testing.T) {
testRequest(t, &Exporter{
YAMLs: []string{"../test/bad/yaml-bad-base64.conf"},
Expand Down

0 comments on commit 03c48bc

Please sign in to comment.