From 7efafa5a2c5e69d9646bb48ac84d2a517aa241dd Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Doumenjou Date: Wed, 9 Jan 2019 11:28:04 +0100 Subject: [PATCH] Migrates the pass client tls cert middleware --- config/middlewares.go | 35 +- .../passtlsclientcert/pass_tls_client_cert.go | 207 ++++--- .../pass_tls_client_cert_test.go | 520 ++++++++++++------ provider/label/parser_test.go | 380 ++++++------- 4 files changed, 671 insertions(+), 471 deletions(-) diff --git a/config/middlewares.go b/config/middlewares.go index f9edd60fb..cd6464b45 100644 --- a/config/middlewares.go +++ b/config/middlewares.go @@ -201,8 +201,8 @@ type MaxConn struct { // PassTLSClientCert holds the TLS client cert headers configuration. type PassTLSClientCert struct { - PEM bool `description:"Enable header with escaped client pem" json:"pem"` - Infos *TLSClientCertificateInfos `description:"Enable header with configured client cert infos" json:"infos,omitempty"` + PEM bool `description:"Enable header with escaped client pem" json:"pem"` + Info *TLSClientCertificateInfo `description:"Enable header with configured client cert info" json:"info,omitempty"` } // Rate holds the rate limiting configuration for a specific time period. @@ -252,22 +252,25 @@ type StripPrefixRegex struct { Regex []string `json:"regex,omitempty"` } -// TLSClientCertificateInfos holds the client TLS certificate infos configuration. -type TLSClientCertificateInfos struct { - NotAfter bool `description:"Add NotAfter info in header" json:"notAfter"` - NotBefore bool `description:"Add NotBefore info in header" json:"notBefore"` - Subject *TLSCLientCertificateSubjectInfos `description:"Add Subject info in header" json:"subject,omitempty"` - Sans bool `description:"Add Sans info in header" json:"sans"` +// TLSClientCertificateInfo holds the client TLS certificate info configuration. +type TLSClientCertificateInfo struct { + NotAfter bool `description:"Add NotAfter info in header" json:"notAfter"` + NotBefore bool `description:"Add NotBefore info in header" json:"notBefore"` + Sans bool `description:"Add Sans info in header" json:"sans"` + Subject *TLSCLientCertificateDNInfo `description:"Add Subject info in header" json:"subject,omitempty"` + Issuer *TLSCLientCertificateDNInfo `description:"Add Issuer info in header" json:"issuer,omitempty"` } -// TLSCLientCertificateSubjectInfos holds the client TLS certificate subject infos configuration. -type TLSCLientCertificateSubjectInfos struct { - Country bool `description:"Add Country info in header" json:"country"` - Province bool `description:"Add Province info in header" json:"province"` - Locality bool `description:"Add Locality info in header" json:"locality"` - Organization bool `description:"Add Organization info in header" json:"organization"` - CommonName bool `description:"Add CommonName info in header" json:"commonName"` - SerialNumber bool `description:"Add SerialNumber info in header" json:"serialNumber"` +// TLSCLientCertificateDNInfo holds the client TLS certificate distinguished name info configuration +// cf https://tools.ietf.org/html/rfc3739 +type TLSCLientCertificateDNInfo struct { + Country bool `description:"Add Country info in header" json:"country"` + Province bool `description:"Add Province info in header" json:"province"` + Locality bool `description:"Add Locality info in header" json:"locality"` + Organization bool `description:"Add Organization info in header" json:"organization"` + CommonName bool `description:"Add CommonName info in header" json:"commonName"` + SerialNumber bool `description:"Add SerialNumber info in header" json:"serialNumber"` + DomainComponent bool `description:"Add Domain Component info in header" json:"domainComponent"` } // Users holds a list of users diff --git a/middlewares/passtlsclientcert/pass_tls_client_cert.go b/middlewares/passtlsclientcert/pass_tls_client_cert.go index 32823b61b..926f9ef36 100644 --- a/middlewares/passtlsclientcert/pass_tls_client_cert.go +++ b/middlewares/passtlsclientcert/pass_tls_client_cert.go @@ -18,17 +18,48 @@ import ( ) const ( - xForwardedTLSClientCert = "X-Forwarded-Tls-Client-Cert" - xForwardedTLSClientCertInfos = "X-Forwarded-Tls-Client-Cert-infos" - typeName = "PassClientTLSCert" + xForwardedTLSClientCert = "X-Forwarded-Tls-Client-Cert" + xForwardedTLSClientCertInfo = "X-Forwarded-Tls-Client-Cert-info" + typeName = "PassClientTLSCert" ) +var attributeTypeNames = map[string]string{ + "0.9.2342.19200300.100.1.25": "DC", // Domain component OID - RFC 2247 +} + +// DistinguishedNameOptions is a struct for specifying the configuration for the distinguished name info. +type DistinguishedNameOptions struct { + CommonName bool + CountryName bool + DomainComponent bool + LocalityName bool + OrganizationName bool + SerialNumber bool + StateOrProvinceName bool +} + +func newDistinguishedNameOptions(info *config.TLSCLientCertificateDNInfo) *DistinguishedNameOptions { + if info == nil { + return nil + } + + return &DistinguishedNameOptions{ + CommonName: info.CommonName, + CountryName: info.Country, + DomainComponent: info.DomainComponent, + LocalityName: info.Locality, + OrganizationName: info.Organization, + SerialNumber: info.SerialNumber, + StateOrProvinceName: info.Province, + } +} + // passTLSClientCert is a middleware that helps setup a few tls info features. type passTLSClientCert struct { - next http.Handler - name string - pem bool // pass the sanitized pem to the backend in a specific header - infos *tlsClientCertificateInfos // pass selected information from the client certificate + next http.Handler + name string + pem bool // pass the sanitized pem to the backend in a specific header + info *tlsClientCertificateInfo // pass selected information from the client certificate } // New constructs a new PassTLSClientCert instance from supplied frontend header struct. @@ -36,56 +67,33 @@ func New(ctx context.Context, next http.Handler, config config.PassTLSClientCert middlewares.GetLogger(ctx, name, typeName).Debug("Creating middleware") return &passTLSClientCert{ - next: next, - name: name, - pem: config.PEM, - infos: newTLSClientInfos(config.Infos), + next: next, + name: name, + pem: config.PEM, + info: newTLSClientInfo(config.Info), }, nil } -// tlsClientCertificateInfos is a struct for specifying the configuration for the passTLSClientCert middleware. -type tlsClientCertificateInfos struct { +// tlsClientCertificateInfo is a struct for specifying the configuration for the passTLSClientCert middleware. +type tlsClientCertificateInfo struct { notAfter bool notBefore bool - subject *tlsCLientCertificateSubjectInfos sans bool + subject *DistinguishedNameOptions + issuer *DistinguishedNameOptions } -func newTLSClientInfos(infos *config.TLSClientCertificateInfos) *tlsClientCertificateInfos { - if infos == nil { +func newTLSClientInfo(info *config.TLSClientCertificateInfo) *tlsClientCertificateInfo { + if info == nil { return nil } - return &tlsClientCertificateInfos{ - notBefore: infos.NotBefore, - notAfter: infos.NotAfter, - sans: infos.Sans, - subject: newTLSCLientCertificateSubjectInfos(infos.Subject), - } -} - -// tlsCLientCertificateSubjectInfos contains the configuration for the certificate subject infos. -type tlsCLientCertificateSubjectInfos struct { - country bool - province bool - locality bool - Organization bool - commonName bool - serialNumber bool -} - -func newTLSCLientCertificateSubjectInfos(infos *config.TLSCLientCertificateSubjectInfos) *tlsCLientCertificateSubjectInfos { - if infos == nil { - return nil - } - - return &tlsCLientCertificateSubjectInfos{ - serialNumber: infos.SerialNumber, - commonName: infos.CommonName, - country: infos.Country, - locality: infos.Locality, - Organization: infos.Organization, - province: infos.Province, + return &tlsClientCertificateInfo{ + issuer: newDistinguishedNameOptions(info.Issuer), + notAfter: info.NotAfter, + notBefore: info.NotBefore, + subject: newDistinguishedNameOptions(info.Subject), + sans: info.Sans, } } @@ -98,47 +106,67 @@ func (p *passTLSClientCert) ServeHTTP(rw http.ResponseWriter, req *http.Request) p.modifyRequestHeaders(logger, req) p.next.ServeHTTP(rw, req) } +func getDNInfo(prefix string, options *DistinguishedNameOptions, cs *pkix.Name) string { + if options == nil { + return "" + } -// getSubjectInfos extract the requested information from the certificate subject. -func (p *passTLSClientCert) getSubjectInfos(cs *pkix.Name) string { - var subject string + content := &strings.Builder{} - if p.infos != nil && p.infos.subject != nil { - options := p.infos.subject - - var content []string - - if options.country && len(cs.Country) > 0 { - content = append(content, fmt.Sprintf("C=%s", cs.Country[0])) - } - - if options.province && len(cs.Province) > 0 { - content = append(content, fmt.Sprintf("ST=%s", cs.Province[0])) - } - - if options.locality && len(cs.Locality) > 0 { - content = append(content, fmt.Sprintf("L=%s", cs.Locality[0])) - } - - if options.Organization && len(cs.Organization) > 0 { - content = append(content, fmt.Sprintf("O=%s", cs.Organization[0])) - } - - if options.commonName && len(cs.CommonName) > 0 { - content = append(content, fmt.Sprintf("CN=%s", cs.CommonName)) - } - - if len(content) > 0 { - subject = `Subject="` + strings.Join(content, ",") + `"` + // Manage non standard attributes + for _, name := range cs.Names { + // Domain Component - RFC 2247 + if options.DomainComponent && attributeTypeNames[name.Type.String()] == "DC" { + content.WriteString(fmt.Sprintf("DC=%s,", name.Value)) } } - return subject + if options.CountryName { + writeParts(content, cs.Country, "C") + } + + if options.StateOrProvinceName { + writeParts(content, cs.Province, "ST") + } + + if options.LocalityName { + writeParts(content, cs.Locality, "L") + } + + if options.OrganizationName { + writeParts(content, cs.Organization, "O") + } + + if options.SerialNumber { + writePart(content, cs.SerialNumber, "SN") + } + + if options.CommonName { + writePart(content, cs.CommonName, "CN") + } + + if content.Len() > 0 { + return prefix + `="` + strings.TrimSuffix(content.String(), ",") + `"` + } + + return "" } -// getXForwardedTLSClientCertInfos Build a string with the wanted client certificates information +func writeParts(content *strings.Builder, entries []string, prefix string) { + for _, entry := range entries { + writePart(content, entry, prefix) + } +} + +func writePart(content *strings.Builder, entry string, prefix string) { + if len(entry) > 0 { + content.WriteString(fmt.Sprintf("%s=%s,", prefix, entry)) + } +} + +// getXForwardedTLSClientCertInfo Build a string with the wanted client certificates information // like Subject="C=%s,ST=%s,L=%s,O=%s,CN=%s",NB=%d,NA=%d,SAN=%s; -func (p *passTLSClientCert) getXForwardedTLSClientCertInfos(certs []*x509.Certificate) string { +func (p *passTLSClientCert) getXForwardedTLSClientCertInfo(certs []*x509.Certificate) string { var headerValues []string for _, peerCert := range certs { @@ -147,12 +175,19 @@ func (p *passTLSClientCert) getXForwardedTLSClientCertInfos(certs []*x509.Certif var nb string var na string - subject := p.getSubjectInfos(&peerCert.Subject) - if len(subject) > 0 { - values = append(values, subject) + if p.info != nil { + subject := getDNInfo("Subject", p.info.subject, &peerCert.Subject) + if len(subject) > 0 { + values = append(values, subject) + } + + issuer := getDNInfo("Issuer", p.info.issuer, &peerCert.Issuer) + if len(issuer) > 0 { + values = append(values, issuer) + } } - ci := p.infos + ci := p.info if ci != nil { if ci.notBefore { nb = fmt.Sprintf("NB=%d", uint64(peerCert.NotBefore.Unix())) @@ -186,10 +221,10 @@ func (p *passTLSClientCert) modifyRequestHeaders(logger logrus.FieldLogger, r *h } } - if p.infos != nil { + if p.info != nil { if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 { - headerContent := p.getXForwardedTLSClientCertInfos(r.TLS.PeerCertificates) - r.Header.Set(xForwardedTLSClientCertInfos, url.QueryEscape(headerContent)) + headerContent := p.getXForwardedTLSClientCertInfo(r.TLS.PeerCertificates) + r.Header.Set(xForwardedTLSClientCertInfo, url.QueryEscape(headerContent)) } else { logger.Warn("Try to extract certificate on a request without TLS") } diff --git a/middlewares/passtlsclientcert/pass_tls_client_cert_test.go b/middlewares/passtlsclientcert/pass_tls_client_cert_test.go index 1b5170bc8..519580096 100644 --- a/middlewares/passtlsclientcert/pass_tls_client_cert_test.go +++ b/middlewares/passtlsclientcert/pass_tls_client_cert_test.go @@ -19,27 +19,227 @@ import ( ) const ( - rootCrt = `-----BEGIN CERTIFICATE----- -MIIDhjCCAm6gAwIBAgIJAIKZlW9a3VrYMA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV -BAYTAkZSMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQHDAhUb3Vsb3VzZTEh -MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMB4XDTE4MDcxNzIwMzQz -OFoXDTE4MDgxNjIwMzQzOFowWDELMAkGA1UEBhMCRlIxEzARBgNVBAgMClNvbWUt -U3RhdGUxETAPBgNVBAcMCFRvdWxvdXNlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn -aXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1P8GJ -H9LkIxIIqK9MyUpushnjmjwccpSMB3OecISKYLy62QDIcAw6NzGcSe8hMwciMJr+ -CdCjJlohybnaRI9hrJ3GPnI++UT/MMthf2IIcjmJxmD4k9L1fgs1V6zSTlo0+o0x -0gkAGlWvRkgA+3nt555ee84XQZuneKKeRRIlSA1ygycewFobZ/pGYijIEko+gYkV -sF3LnRGxNl673w+EQsvI7+z29T1nzjmM/xE7WlvnsrVd1/N61jAohLota0YTufwd -ioJZNryzuPejHBCiQRGMbJ7uEEZLiSCN6QiZEfqhS3AulykjgFXQQHn4zoVljSBR -UyLV0prIn5Scbks/AgMBAAGjUzBRMB0GA1UdDgQWBBTroRRnSgtkV+8dumtcftb/ -lwIkATAfBgNVHSMEGDAWgBTroRRnSgtkV+8dumtcftb/lwIkATAPBgNVHRMBAf8E -BTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAJ67U5cLa0ZFa/7zQQT4ldkY6YOEgR -0LNoTu51hc+ozaXSvF8YIBzkEpEnbGS3x4xodrwEBZjK2LFhNu/33gkCAuhmedgk -KwZrQM6lqRFGHGVOlkVz+QrJ2EsKYaO4SCUIwVjijXRLA7A30G5C/CIh66PsMgBY -6QHXVPEWm/v1d1Q/DfFfFzSOa1n1rIUw03qVJsxqSwfwYcegOF8YvS/eH4HUr2gF -cEujh6CCnylf35ExHa45atr3+xxbOVdNjobISkYADtbhAAn4KjLS4v8W6445vxxj -G5EIZLjOHyWg1sGaHaaAPkVpZQg8EKm21c4hrEEMfel60AMSSzad/a/V ------END CERTIFICATE-----` + signingCA = `Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha1WithRSAEncryption + Issuer: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Cheese Section, OU=Cheese Section 2, CN=Simple Root CA, CN=Simple Root CA 2, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Root State, ST=Root State 2/emailAddress=root@signing.com/emailAddress=root2@signing.com + Validity + Not Before: Dec 6 11:10:09 2018 GMT + Not After : Dec 5 11:10:09 2028 GMT + Subject: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=Simple Signing CA, CN=Simple Signing CA 2, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Signing State, ST=Signing State 2/emailAddress=simple@signing.com/emailAddress=simple2@signing.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:c3:9d:9f:61:15:57:3f:78:cc:e7:5d:20:e2:3e: + 2e:79:4a:c3:3a:0c:26:40:18:db:87:08:85:c2:f7: + af:87:13:1a:ff:67:8a:b7:2b:58:a7:cc:89:dd:77: + ff:5e:27:65:11:80:82:8f:af:a0:af:25:86:ec:a2: + 4f:20:0e:14:15:16:12:d7:74:5a:c3:99:bd:3b:81: + c8:63:6f:fc:90:14:86:d2:39:ee:87:b2:ff:6d:a5: + 69:da:ab:5a:3a:97:cd:23:37:6a:4b:ba:63:cd:a1: + a9:e6:79:aa:37:b8:d1:90:c9:24:b5:e8:70:fc:15: + ad:39:97:28:73:47:66:f6:22:79:5a:b0:03:83:8a: + f1:ca:ae:8b:50:1e:c8:fa:0d:9f:76:2e:00:c2:0e: + 75:bc:47:5a:b6:d8:05:ed:5a:bc:6d:50:50:36:6b: + ab:ab:69:f6:9b:1b:6c:7e:a8:9f:b2:33:3a:3c:8c: + 6d:5e:83:ce:17:82:9e:10:51:a6:39:ec:98:4e:50: + b7:b1:aa:8b:ac:bb:a1:60:1b:ea:31:3b:b8:0a:ea: + 63:41:79:b5:ec:ee:19:e9:85:8e:f3:6d:93:80:da: + 98:58:a2:40:93:a5:53:eb:1d:24:b6:66:07:ec:58: + 10:63:e7:fa:6e:18:60:74:76:15:39:3c:f4:95:95: + 7e:df + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Subject Key Identifier: + 1E:52:A2:E8:54:D5:37:EB:D5:A8:1D:E4:C2:04:1D:37:E2:F7:70:03 + X509v3 Authority Key Identifier: + keyid:36:70:35:AA:F0:F6:93:B2:86:5D:32:73:F9:41:5A:3F:3B:C8:BC:8B + + Signature Algorithm: sha1WithRSAEncryption + 76:f3:16:21:27:6d:a2:2e:e8:18:49:aa:54:1e:f8:3b:07:fa: + 65:50:d8:1f:a2:cf:64:6c:15:e0:0f:c8:46:b2:d7:b8:0e:cd: + 05:3b:06:fb:dd:c6:2f:01:ae:bd:69:d3:bb:55:47:a9:f6:e5: + ba:be:4b:45:fb:2e:3c:33:e0:57:d4:3e:8e:3e:11:f2:0a:f1: + 7d:06:ab:04:2e:a5:76:20:c2:db:a4:68:5a:39:00:62:2a:1d: + c2:12:b1:90:66:8c:36:a8:fd:83:d1:1b:da:23:a7:1d:5b:e6: + 9b:40:c4:78:25:c7:b7:6b:75:35:cf:bb:37:4a:4f:fc:7e:32: + 1f:8c:cf:12:d2:c9:c8:99:d9:4a:55:0a:1e:ac:de:b4:cb:7c: + bf:c4:fb:60:2c:a8:f7:e7:63:5c:b0:1c:62:af:01:3c:fe:4d: + 3c:0b:18:37:4c:25:fc:d0:b2:f6:b2:f1:c3:f4:0f:53:d6:1e: + b5:fa:bc:d8:ad:dd:1c:f5:45:9f:af:fe:0a:01:79:92:9a:d8: + 71:db:37:f3:1e:bd:fb:c7:1e:0a:0f:97:2a:61:f3:7b:19:93: + 9c:a6:8a:69:cd:b0:f5:91:02:a5:1b:10:f4:80:5d:42:af:4e: + 82:12:30:3e:d3:a7:11:14:ce:50:91:04:80:d7:2a:03:ef:71: + 10:b8:db:a5 +-----BEGIN CERTIFICATE----- +MIIFzTCCBLWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCCAWQxEzARBgoJkiaJk/Is +ZAEZFgNvcmcxFjAUBgoJkiaJk/IsZAEZFgZjaGVlc2UxDzANBgNVBAoMBkNoZWVz +ZTERMA8GA1UECgwIQ2hlZXNlIDIxFzAVBgNVBAsMDkNoZWVzZSBTZWN0aW9uMRkw +FwYDVQQLDBBDaGVlc2UgU2VjdGlvbiAyMRcwFQYDVQQDDA5TaW1wbGUgUm9vdCBD +QTEZMBcGA1UEAwwQU2ltcGxlIFJvb3QgQ0EgMjELMAkGA1UEBhMCRlIxCzAJBgNV +BAYTAlVTMREwDwYDVQQHDAhUT1VMT1VTRTENMAsGA1UEBwwETFlPTjETMBEGA1UE +CAwKUm9vdCBTdGF0ZTEVMBMGA1UECAwMUm9vdCBTdGF0ZSAyMR8wHQYJKoZIhvcN +AQkBFhByb290QHNpZ25pbmcuY29tMSAwHgYJKoZIhvcNAQkBFhFyb290MkBzaWdu +aW5nLmNvbTAeFw0xODEyMDYxMTEwMDlaFw0yODEyMDUxMTEwMDlaMIIBhDETMBEG +CgmSJomT8ixkARkWA29yZzEWMBQGCgmSJomT8ixkARkWBmNoZWVzZTEPMA0GA1UE +CgwGQ2hlZXNlMREwDwYDVQQKDAhDaGVlc2UgMjEfMB0GA1UECwwWU2ltcGxlIFNp +Z25pbmcgU2VjdGlvbjEhMB8GA1UECwwYU2ltcGxlIFNpZ25pbmcgU2VjdGlvbiAy +MRowGAYDVQQDDBFTaW1wbGUgU2lnbmluZyBDQTEcMBoGA1UEAwwTU2ltcGxlIFNp +Z25pbmcgQ0EgMjELMAkGA1UEBhMCRlIxCzAJBgNVBAYTAlVTMREwDwYDVQQHDAhU +T1VMT1VTRTENMAsGA1UEBwwETFlPTjEWMBQGA1UECAwNU2lnbmluZyBTdGF0ZTEY +MBYGA1UECAwPU2lnbmluZyBTdGF0ZSAyMSEwHwYJKoZIhvcNAQkBFhJzaW1wbGVA +c2lnbmluZy5jb20xIjAgBgkqhkiG9w0BCQEWE3NpbXBsZTJAc2lnbmluZy5jb20w +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDnZ9hFVc/eMznXSDiPi55 +SsM6DCZAGNuHCIXC96+HExr/Z4q3K1inzIndd/9eJ2URgIKPr6CvJYbsok8gDhQV +FhLXdFrDmb07gchjb/yQFIbSOe6Hsv9tpWnaq1o6l80jN2pLumPNoanmeao3uNGQ +ySS16HD8Fa05lyhzR2b2InlasAODivHKrotQHsj6DZ92LgDCDnW8R1q22AXtWrxt +UFA2a6urafabG2x+qJ+yMzo8jG1eg84Xgp4QUaY57JhOULexqousu6FgG+oxO7gK +6mNBebXs7hnphY7zbZOA2phYokCTpVPrHSS2ZgfsWBBj5/puGGB0dhU5PPSVlX7f +AgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0G +A1UdDgQWBBQeUqLoVNU369WoHeTCBB034vdwAzAfBgNVHSMEGDAWgBQ2cDWq8PaT +soZdMnP5QVo/O8i8izANBgkqhkiG9w0BAQUFAAOCAQEAdvMWISdtoi7oGEmqVB74 +Owf6ZVDYH6LPZGwV4A/IRrLXuA7NBTsG+93GLwGuvWnTu1VHqfblur5LRfsuPDPg +V9Q+jj4R8grxfQarBC6ldiDC26RoWjkAYiodwhKxkGaMNqj9g9Eb2iOnHVvmm0DE +eCXHt2t1Nc+7N0pP/H4yH4zPEtLJyJnZSlUKHqzetMt8v8T7YCyo9+djXLAcYq8B +PP5NPAsYN0wl/NCy9rLxw/QPU9Yetfq82K3dHPVFn6/+CgF5kprYcds38x69+8ce +Cg+XKmHzexmTnKaKac2w9ZECpRsQ9IBdQq9OghIwPtOnERTOUJEEgNcqA+9xELjb +pQ== +-----END CERTIFICATE----- +` + minimalCheeseCrt = `-----BEGIN CERTIFICATE----- +MIIEQDCCAygCFFRY0OBk/L5Se0IZRj3CMljawL2UMA0GCSqGSIb3DQEBCwUAMIIB +hDETMBEGCgmSJomT8ixkARkWA29yZzEWMBQGCgmSJomT8ixkARkWBmNoZWVzZTEP +MA0GA1UECgwGQ2hlZXNlMREwDwYDVQQKDAhDaGVlc2UgMjEfMB0GA1UECwwWU2lt +cGxlIFNpZ25pbmcgU2VjdGlvbjEhMB8GA1UECwwYU2ltcGxlIFNpZ25pbmcgU2Vj +dGlvbiAyMRowGAYDVQQDDBFTaW1wbGUgU2lnbmluZyBDQTEcMBoGA1UEAwwTU2lt +cGxlIFNpZ25pbmcgQ0EgMjELMAkGA1UEBhMCRlIxCzAJBgNVBAYTAlVTMREwDwYD +VQQHDAhUT1VMT1VTRTENMAsGA1UEBwwETFlPTjEWMBQGA1UECAwNU2lnbmluZyBT +dGF0ZTEYMBYGA1UECAwPU2lnbmluZyBTdGF0ZSAyMSEwHwYJKoZIhvcNAQkBFhJz +aW1wbGVAc2lnbmluZy5jb20xIjAgBgkqhkiG9w0BCQEWE3NpbXBsZTJAc2lnbmlu +Zy5jb20wHhcNMTgxMjA2MTExMDM2WhcNMjEwOTI1MTExMDM2WjAzMQswCQYDVQQG +EwJGUjETMBEGA1UECAwKU29tZS1TdGF0ZTEPMA0GA1UECgwGQ2hlZXNlMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAskX/bUtwFo1gF2BTPNaNcTUMaRFu +FMZozK8IgLjccZ4kZ0R9oFO6Yp8Zl/IvPaf7tE26PI7XP7eHriUdhnQzX7iioDd0 +RZa68waIhAGc+xPzRFrP3b3yj3S2a9Rve3c0K+SCV+EtKAwsxMqQDhoo9PcBfo5B +RHfht07uD5MncUcGirwN+/pxHV5xzAGPcc7On0/5L7bq/G+63nhu78zw9XyuLaHC +PM5VbOUvpyIESJHbMMzTdFGL8ob9VKO+Kr1kVGdEA9i8FLGl3xz/GBKuW/JD0xyW +DrU29mri5vYWHmkuv7ZWHGXnpXjTtPHwveE9/0/ArnmpMyR9JtqFr1oEvQIDAQAB +MA0GCSqGSIb3DQEBCwUAA4IBAQBHta+NWXI08UHeOkGzOTGRiWXsOH2dqdX6gTe9 +xF1AIjyoQ0gvpoGVvlnChSzmlUj+vnx/nOYGIt1poE3hZA3ZHZD/awsvGyp3GwWD +IfXrEViSCIyF+8tNNKYyUcEO3xdAsAUGgfUwwF/mZ6MBV5+A/ZEEILlTq8zFt9dV +vdKzIt7fZYxYBBHFSarl1x8pDgWXlf3hAufevGJXip9xGYmznF0T5cq1RbWJ4be3 +/9K7yuWhuBYC3sbTbCneHBa91M82za+PIISc1ygCYtWSBoZKSAqLk0rkZpHaekDP +WqeUSNGYV//RunTeuRDAf5OxehERb1srzBXhRZ3cZdzXbgR/ +-----END CERTIFICATE----- +` + + completeCheeseCrt = `Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Issuer: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=Simple Signing CA, CN=Simple Signing CA 2, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Signing State, ST=Signing State 2/emailAddress=simple@signing.com/emailAddress=simple2@signing.com + Validity + Not Before: Dec 6 11:10:16 2018 GMT + Not After : Dec 5 11:10:16 2020 GMT + Subject: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=*.cheese.org, CN=*.cheese.com, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Cheese org state, ST=Cheese com state/emailAddress=cert@cheese.org/emailAddress=cert@scheese.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:de:77:fa:8d:03:70:30:39:dd:51:1b:cc:60:db: + a9:5a:13:b1:af:fe:2c:c6:38:9b:88:0a:0f:8e:d9: + 1b:a1:1d:af:0d:66:e4:13:5b:bc:5d:36:92:d7:5e: + d0:fa:88:29:d3:78:e1:81:de:98:b2:a9:22:3f:bf: + 8a:af:12:92:63:d4:a9:c3:f2:e4:7e:d2:dc:a2:c5: + 39:1c:7a:eb:d7:12:70:63:2e:41:47:e0:f0:08:e8: + dc:be:09:01:ec:28:09:af:35:d7:79:9c:50:35:d1: + 6b:e5:87:7b:34:f6:d2:31:65:1d:18:42:69:6c:04: + 11:83:fe:44:ae:90:92:2d:0b:75:39:57:62:e6:17: + 2f:47:2b:c7:53:dd:10:2d:c9:e3:06:13:d2:b9:ba: + 63:2e:3c:7d:83:6b:d6:89:c9:cc:9d:4d:bf:9f:e8: + a3:7b:da:c8:99:2b:ba:66:d6:8e:f8:41:41:a0:c9: + d0:5e:c8:11:a4:55:4a:93:83:87:63:04:63:41:9c: + fb:68:04:67:c2:71:2f:f2:65:1d:02:5d:15:db:2c: + d9:04:69:85:c2:7d:0d:ea:3b:ac:85:f8:d4:8f:0f: + c5:70:b2:45:e1:ec:b2:54:0b:e9:f7:82:b4:9b:1b: + 2d:b9:25:d4:ab:ca:8f:5b:44:3e:15:dd:b8:7f:b7: + ee:f9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Basic Constraints: + CA:FALSE + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 Subject Key Identifier: + 94:BA:73:78:A2:87:FB:58:28:28:CF:98:3B:C2:45:70:16:6E:29:2F + X509v3 Authority Key Identifier: + keyid:1E:52:A2:E8:54:D5:37:EB:D5:A8:1D:E4:C2:04:1D:37:E2:F7:70:03 + + X509v3 Subject Alternative Name: + DNS:*.cheese.org, DNS:*.cheese.net, DNS:*.cheese.com, IP Address:10.0.1.0, IP Address:10.0.1.2, email:test@cheese.org, email:test@cheese.net + Signature Algorithm: sha1WithRSAEncryption + 76:6b:05:b0:0e:34:11:b1:83:99:91:dc:ae:1b:e2:08:15:8b: + 16:b2:9b:27:1c:02:ac:b5:df:1b:d0:d0:75:a4:2b:2c:5c:65: + ed:99:ab:f7:cd:fe:38:3f:c3:9a:22:31:1b:ac:8c:1c:c2:f9: + 5d:d4:75:7a:2e:72:c7:85:a9:04:af:9f:2a:cc:d3:96:75:f0: + 8e:c7:c6:76:48:ac:45:a4:b9:02:1e:2f:c0:15:c4:07:08:92: + cb:27:50:67:a1:c8:05:c5:3a:b3:a6:48:be:eb:d5:59:ab:a2: + 1b:95:30:71:13:5b:0a:9a:73:3b:60:cc:10:d0:6a:c7:e5:d7: + 8b:2f:f9:2e:98:f2:ff:81:14:24:09:e3:4b:55:57:09:1a:22: + 74:f1:f6:40:13:31:43:89:71:0a:96:1a:05:82:1f:83:3a:87: + 9b:17:25:ef:5a:55:f2:2d:cd:0d:4d:e4:81:58:b6:e3:8d:09: + 62:9a:0c:bd:e4:e5:5c:f0:95:da:cb:c7:34:2c:34:5f:6d:fc: + 60:7b:12:5b:86:fd:df:21:89:3b:48:08:30:bf:67:ff:8c:e6: + 9b:53:cc:87:36:47:70:40:3b:d9:90:2a:d2:d2:82:c6:9c:f5: + d1:d8:e0:e6:fd:aa:2f:95:7e:39:ac:fc:4e:d4:ce:65:b3:ec: + c6:98:8a:31 +-----BEGIN CERTIFICATE----- +MIIGWjCCBUKgAwIBAgIBATANBgkqhkiG9w0BAQUFADCCAYQxEzARBgoJkiaJk/Is +ZAEZFgNvcmcxFjAUBgoJkiaJk/IsZAEZFgZjaGVlc2UxDzANBgNVBAoMBkNoZWVz +ZTERMA8GA1UECgwIQ2hlZXNlIDIxHzAdBgNVBAsMFlNpbXBsZSBTaWduaW5nIFNl +Y3Rpb24xITAfBgNVBAsMGFNpbXBsZSBTaWduaW5nIFNlY3Rpb24gMjEaMBgGA1UE +AwwRU2ltcGxlIFNpZ25pbmcgQ0ExHDAaBgNVBAMME1NpbXBsZSBTaWduaW5nIENB +IDIxCzAJBgNVBAYTAkZSMQswCQYDVQQGEwJVUzERMA8GA1UEBwwIVE9VTE9VU0Ux +DTALBgNVBAcMBExZT04xFjAUBgNVBAgMDVNpZ25pbmcgU3RhdGUxGDAWBgNVBAgM +D1NpZ25pbmcgU3RhdGUgMjEhMB8GCSqGSIb3DQEJARYSc2ltcGxlQHNpZ25pbmcu +Y29tMSIwIAYJKoZIhvcNAQkBFhNzaW1wbGUyQHNpZ25pbmcuY29tMB4XDTE4MTIw +NjExMTAxNloXDTIwMTIwNTExMTAxNlowggF2MRMwEQYKCZImiZPyLGQBGRYDb3Jn +MRYwFAYKCZImiZPyLGQBGRYGY2hlZXNlMQ8wDQYDVQQKDAZDaGVlc2UxETAPBgNV +BAoMCENoZWVzZSAyMR8wHQYDVQQLDBZTaW1wbGUgU2lnbmluZyBTZWN0aW9uMSEw +HwYDVQQLDBhTaW1wbGUgU2lnbmluZyBTZWN0aW9uIDIxFTATBgNVBAMMDCouY2hl +ZXNlLm9yZzEVMBMGA1UEAwwMKi5jaGVlc2UuY29tMQswCQYDVQQGEwJGUjELMAkG +A1UEBhMCVVMxETAPBgNVBAcMCFRPVUxPVVNFMQ0wCwYDVQQHDARMWU9OMRkwFwYD +VQQIDBBDaGVlc2Ugb3JnIHN0YXRlMRkwFwYDVQQIDBBDaGVlc2UgY29tIHN0YXRl +MR4wHAYJKoZIhvcNAQkBFg9jZXJ0QGNoZWVzZS5vcmcxHzAdBgkqhkiG9w0BCQEW +EGNlcnRAc2NoZWVzZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDed/qNA3AwOd1RG8xg26laE7Gv/izGOJuICg+O2RuhHa8NZuQTW7xdNpLXXtD6 +iCnTeOGB3piyqSI/v4qvEpJj1KnD8uR+0tyixTkceuvXEnBjLkFH4PAI6Ny+CQHs +KAmvNdd5nFA10Wvlh3s09tIxZR0YQmlsBBGD/kSukJItC3U5V2LmFy9HK8dT3RAt +yeMGE9K5umMuPH2Da9aJycydTb+f6KN72siZK7pm1o74QUGgydBeyBGkVUqTg4dj +BGNBnPtoBGfCcS/yZR0CXRXbLNkEaYXCfQ3qO6yF+NSPD8VwskXh7LJUC+n3grSb +Gy25JdSryo9bRD4V3bh/t+75AgMBAAGjgeAwgd0wDgYDVR0PAQH/BAQDAgWgMAkG +A1UdEwQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQW +BBSUunN4oof7WCgoz5g7wkVwFm4pLzAfBgNVHSMEGDAWgBQeUqLoVNU369WoHeTC +BB034vdwAzBhBgNVHREEWjBYggwqLmNoZWVzZS5vcmeCDCouY2hlZXNlLm5ldIIM +Ki5jaGVlc2UuY29thwQKAAEAhwQKAAECgQ90ZXN0QGNoZWVzZS5vcmeBD3Rlc3RA +Y2hlZXNlLm5ldDANBgkqhkiG9w0BAQUFAAOCAQEAdmsFsA40EbGDmZHcrhviCBWL +FrKbJxwCrLXfG9DQdaQrLFxl7Zmr983+OD/DmiIxG6yMHML5XdR1ei5yx4WpBK+f +KszTlnXwjsfGdkisRaS5Ah4vwBXEBwiSyydQZ6HIBcU6s6ZIvuvVWauiG5UwcRNb +CppzO2DMENBqx+XXiy/5Lpjy/4EUJAnjS1VXCRoidPH2QBMxQ4lxCpYaBYIfgzqH +mxcl71pV8i3NDU3kgVi2440JYpoMveTlXPCV2svHNCw0X238YHsSW4b93yGJO0gI +ML9n/4zmm1PMhzZHcEA72ZAq0tKCxpz10djg5v2qL5V+Oaz8TtTOZbPsxpiKMQ== +-----END CERTIFICATE----- +` minimalCert = `-----BEGIN CERTIFICATE----- MIIDGTCCAgECCQCqLd75YLi2kDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJG @@ -60,87 +260,6 @@ SBRHc6ojvbqZSJCO0jziGDT1L3D+EDgTjED4nd77v/NRdP+egb0q3P0s4dnQ/5AV aQlQADUn61j3ScbGJ4NSeZFFvsl38jeRi/MEzp0bGgNBcPj6JHi7qbbauZcZfQ05 jECvgAY7Nfd9mZ1KtyNaW31is+kag7NsvjxU/kM= -----END CERTIFICATE-----` - - completeCert = `Certificate: - Data: - Version: 3 (0x2) - Serial Number: 3 (0x3) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=FR, ST=Some-State, L=Toulouse, O=Internet Widgits Pty Ltd - Validity - Not Before: Jul 18 08:00:16 2018 GMT - Not After : Jul 18 08:00:16 2019 GMT - subject: C=FR, ST=SomeState, L=Toulouse, O=Cheese, CN=*.cheese.org - subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:a6:1f:96:7c:c1:cc:b8:1c:b5:91:5d:b8:bf:70: - bc:f7:b8:04:4f:2a:42:de:ea:c5:c3:19:0b:03:04: - ec:ef:a1:24:25:de:ad:05:e7:26:ea:89:6c:59:60: - 10:18:0c:73:f1:bf:d3:cc:7b:ed:6b:9c:ea:1d:88: - e2:ee:14:81:d7:07:ee:87:95:3d:36:df:9c:38:b7: - 7b:1e:2b:51:9c:4a:1f:d0:cc:5b:af:5d:6c:5c:35: - 49:32:e4:01:5b:f9:8c:71:cf:62:48:5a:ea:b7:31: - 58:e2:c6:d0:5b:1c:50:b5:5c:6d:5a:6f:da:41:5e: - d5:4c:6e:1a:21:f3:40:f9:9e:52:76:50:25:3e:03: - 9b:87:19:48:5b:47:87:d3:67:c6:25:69:77:29:8e: - 56:97:45:d9:6f:64:a8:4e:ad:35:75:2e:fc:6a:2e: - 47:87:76:fc:4e:3e:44:e9:16:b2:c7:f0:23:98:13: - a2:df:15:23:cb:0c:3d:fd:48:5e:c7:2c:86:70:63: - 8b:c6:c8:89:17:52:d5:a7:8e:cb:4e:11:9d:69:8e: - 8e:59:cc:7e:a3:bd:a1:11:88:d7:cf:7b:8c:19:46: - 9c:1b:7a:c9:39:81:4c:58:08:1f:c7:ce:b0:0e:79: - 64:d3:11:72:65:e6:dd:bd:00:7f:22:30:46:9b:66: - 9c:b9 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - X509v3 subject Alternative Name: - DNS:*.cheese.org, DNS:*.cheese.net, DNS:cheese.in, IP Address:10.0.1.0, IP Address:10.0.1.2, email:test@cheese.org, email:test@cheese.net - X509v3 subject Key Identifier: - AB:6B:89:25:11:FC:5E:7B:D4:B0:F7:D4:B6:D9:EB:D0:30:93:E5:58 - Signature Algorithm: sha1WithRSAEncryption - ad:87:84:a0:88:a3:4c:d9:0a:c0:14:e4:2d:9a:1d:bb:57:b7: - 12:ef:3a:fb:8b:b2:ce:32:b8:04:e6:59:c8:4f:14:6a:b5:12: - 46:e9:c9:0a:11:64:ea:a1:86:20:96:0e:a7:40:e3:aa:e5:98: - 91:36:89:77:b6:b9:73:7e:1a:58:19:ae:d1:14:83:1e:c1:5f: - a5:a0:32:bb:52:68:b4:8d:a3:1d:b3:08:d7:45:6e:3b:87:64: - 7e:ef:46:e6:6f:d5:79:d7:1d:57:68:67:d8:18:39:61:5b:8b: - 1a:7f:88:da:0a:51:9b:3d:6c:5d:b1:cf:b7:e9:1e:06:65:8e: - 96:d3:61:96:f8:a2:61:f9:40:5e:fa:bc:76:b9:64:0e:6f:90: - 37:de:ac:6d:7f:36:84:35:19:88:8c:26:af:3e:c3:6a:1a:03: - ed:d7:90:89:ed:18:4c:9e:94:1f:d8:ae:6c:61:36:17:72:f9: - bb:de:0a:56:9a:79:b4:7d:4a:9d:cb:4a:7d:71:9f:38:e7:8d: - f0:87:24:21:0a:24:1f:82:9a:6b:67:ce:7d:af:cb:91:6b:8a: - de:e6:d8:6f:a1:37:b9:2d:d0:cb:e8:4e:f4:43:af:ad:90:13: - 7d:61:7a:ce:86:48:fc:00:8c:37:fb:e0:31:6b:e2:18:ad:fd: - 1e:df:08:db ------BEGIN CERTIFICATE----- -MIIDvTCCAqWgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJGUjET -MBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UEBwwIVG91bG91c2UxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xODA3MTgwODAwMTZaFw0xOTA3 -MTgwODAwMTZaMFwxCzAJBgNVBAYTAkZSMRIwEAYDVQQIDAlTb21lU3RhdGUxETAP -BgNVBAcMCFRvdWxvdXNlMQ8wDQYDVQQKDAZDaGVlc2UxFTATBgNVBAMMDCouY2hl -ZXNlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKYflnzBzLgc -tZFduL9wvPe4BE8qQt7qxcMZCwME7O+hJCXerQXnJuqJbFlgEBgMc/G/08x77Wuc -6h2I4u4UgdcH7oeVPTbfnDi3ex4rUZxKH9DMW69dbFw1STLkAVv5jHHPYkha6rcx -WOLG0FscULVcbVpv2kFe1UxuGiHzQPmeUnZQJT4Dm4cZSFtHh9NnxiVpdymOVpdF -2W9kqE6tNXUu/GouR4d2/E4+ROkWssfwI5gTot8VI8sMPf1IXscshnBji8bIiRdS -1aeOy04RnWmOjlnMfqO9oRGI1897jBlGnBt6yTmBTFgIH8fOsA55ZNMRcmXm3b0A -fyIwRptmnLkCAwEAAaOBjTCBijAJBgNVHRMEAjAAMF4GA1UdEQRXMFWCDCouY2hl -ZXNlLm9yZ4IMKi5jaGVlc2UubmV0ggljaGVlc2UuaW6HBAoAAQCHBAoAAQKBD3Rl -c3RAY2hlZXNlLm9yZ4EPdGVzdEBjaGVlc2UubmV0MB0GA1UdDgQWBBSra4klEfxe -e9Sw99S22evQMJPlWDANBgkqhkiG9w0BAQUFAAOCAQEArYeEoIijTNkKwBTkLZod -u1e3Eu86+4uyzjK4BOZZyE8UarUSRunJChFk6qGGIJYOp0DjquWYkTaJd7a5c34a -WBmu0RSDHsFfpaAyu1JotI2jHbMI10VuO4dkfu9G5m/VedcdV2hn2Bg5YVuLGn+I -2gpRmz1sXbHPt+keBmWOltNhlviiYflAXvq8drlkDm+QN96sbX82hDUZiIwmrz7D -ahoD7deQie0YTJ6UH9iubGE2F3L5u94KVpp5tH1KnctKfXGfOOeN8IckIQokH4Ka -a2fOfa/LkWuK3ubYb6E3uS3Qy+hO9EOvrZATfWF6zoZI/ACMN/vgMWviGK39Ht8I -2w== ------END CERTIFICATE----- -` ) func getCleanCertContents(certContents []string) string { @@ -157,7 +276,7 @@ func getCleanCertContents(certContents []string) string { func getCertificate(certContent string) *x509.Certificate { roots := x509.NewCertPool() - ok := roots.AppendCertsFromPEM([]byte(rootCrt)) + ok := roots.AppendCertsFromPEM([]byte(signingCA)) if !ok { panic("failed to parse root certificate") } @@ -206,24 +325,30 @@ func TestSanitize(t *testing.T) { }, { desc: "With a minimal cert", - toSanitize: []byte(minimalCert), - expected: getExpectedSanitized(`MIIDGTCCAgECCQCqLd75YLi2kDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJG -UjETMBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UEBwwIVG91bG91c2UxITAfBgNV -BAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xODA3MTgwODI4MTZaFw0x -ODA4MTcwODI4MTZaMEUxCzAJBgNVBAYTAkZSMRMwEQYDVQQIDApTb21lLVN0YXRl -MSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQC/+frDMMTLQyXG34F68BPhQq0kzK4LIq9Y0/gl -FjySZNn1C0QDWA1ubVCAcA6yY204I9cxcQDPNrhC7JlS5QA8Y5rhIBrqQlzZizAi -Rj3NTrRjtGUtOScnHuJaWjLy03DWD+aMwb7q718xt5SEABmmUvLwQK+EjW2MeDwj -y8/UEIpvrRDmdhGaqv7IFpIDkcIF7FowJ/hwDvx3PMc+z/JWK0ovzpvgbx69AVbw -ZxCimeha65rOqVi+lEetD26le+WnOdYsdJ2IkmpPNTXGdfb15xuAc+gFXfMCh7Iw -3Ynl6dZtZM/Ok2kiA7/OsmVnRKkWrtBfGYkI9HcNGb3zrk6nAgMBAAEwDQYJKoZI -hvcNAQELBQADggEBAC/R+Yvhh1VUhcbK49olWsk/JKqfS3VIDQYZg1Eo+JCPbwgS -I1BSYVfMcGzuJTX6ua3m/AHzGF3Tap4GhF4tX12jeIx4R4utnjj7/YKkTvuEM2f4 -xT56YqI7zalGScIB0iMeyNz1QcimRl+M/49au8ow9hNX8C2tcA2cwd/9OIj/6T8q -SBRHc6ojvbqZSJCO0jziGDT1L3D+EDgTjED4nd77v/NRdP+egb0q3P0s4dnQ/5AV -aQlQADUn61j3ScbGJ4NSeZFFvsl38jeRi/MEzp0bGgNBcPj6JHi7qbbauZcZfQ05 -jECvgAY7Nfd9mZ1KtyNaW31is+kag7NsvjxU/kM=`), + toSanitize: []byte(minimalCheeseCrt), + expected: getExpectedSanitized(`MIIEQDCCAygCFFRY0OBk/L5Se0IZRj3CMljawL2UMA0GCSqGSIb3DQEBCwUAMIIB +hDETMBEGCgmSJomT8ixkARkWA29yZzEWMBQGCgmSJomT8ixkARkWBmNoZWVzZTEP +MA0GA1UECgwGQ2hlZXNlMREwDwYDVQQKDAhDaGVlc2UgMjEfMB0GA1UECwwWU2lt +cGxlIFNpZ25pbmcgU2VjdGlvbjEhMB8GA1UECwwYU2ltcGxlIFNpZ25pbmcgU2Vj +dGlvbiAyMRowGAYDVQQDDBFTaW1wbGUgU2lnbmluZyBDQTEcMBoGA1UEAwwTU2lt +cGxlIFNpZ25pbmcgQ0EgMjELMAkGA1UEBhMCRlIxCzAJBgNVBAYTAlVTMREwDwYD +VQQHDAhUT1VMT1VTRTENMAsGA1UEBwwETFlPTjEWMBQGA1UECAwNU2lnbmluZyBT +dGF0ZTEYMBYGA1UECAwPU2lnbmluZyBTdGF0ZSAyMSEwHwYJKoZIhvcNAQkBFhJz +aW1wbGVAc2lnbmluZy5jb20xIjAgBgkqhkiG9w0BCQEWE3NpbXBsZTJAc2lnbmlu +Zy5jb20wHhcNMTgxMjA2MTExMDM2WhcNMjEwOTI1MTExMDM2WjAzMQswCQYDVQQG +EwJGUjETMBEGA1UECAwKU29tZS1TdGF0ZTEPMA0GA1UECgwGQ2hlZXNlMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAskX/bUtwFo1gF2BTPNaNcTUMaRFu +FMZozK8IgLjccZ4kZ0R9oFO6Yp8Zl/IvPaf7tE26PI7XP7eHriUdhnQzX7iioDd0 +RZa68waIhAGc+xPzRFrP3b3yj3S2a9Rve3c0K+SCV+EtKAwsxMqQDhoo9PcBfo5B +RHfht07uD5MncUcGirwN+/pxHV5xzAGPcc7On0/5L7bq/G+63nhu78zw9XyuLaHC +PM5VbOUvpyIESJHbMMzTdFGL8ob9VKO+Kr1kVGdEA9i8FLGl3xz/GBKuW/JD0xyW +DrU29mri5vYWHmkuv7ZWHGXnpXjTtPHwveE9/0/ArnmpMyR9JtqFr1oEvQIDAQAB +MA0GCSqGSIb3DQEBCwUAA4IBAQBHta+NWXI08UHeOkGzOTGRiWXsOH2dqdX6gTe9 +xF1AIjyoQ0gvpoGVvlnChSzmlUj+vnx/nOYGIt1poE3hZA3ZHZD/awsvGyp3GwWD +IfXrEViSCIyF+8tNNKYyUcEO3xdAsAUGgfUwwF/mZ6MBV5+A/ZEEILlTq8zFt9dV +vdKzIt7fZYxYBBHFSarl1x8pDgWXlf3hAufevGJXip9xGYmznF0T5cq1RbWJ4be3 +/9K7yuWhuBYC3sbTbCneHBa91M82za+PIISc1ygCYtWSBoZKSAqLk0rkZpHaekDP +WqeUSNGYV//RunTeuRDAf5OxehERb1srzBXhRZ3cZdzXbgR/`), }, } @@ -250,7 +375,7 @@ func TestTLSClientHeadersWithPEM(t *testing.T) { }, { desc: "TLS, no option", - certContents: []string{minimalCert}, + certContents: []string{minimalCheeseCrt}, }, { desc: "No TLS, with pem option true", @@ -258,21 +383,21 @@ func TestTLSClientHeadersWithPEM(t *testing.T) { }, { desc: "TLS with simple certificate, with pem option true", - certContents: []string{minimalCert}, + certContents: []string{minimalCheeseCrt}, config: config.PassTLSClientCert{PEM: true}, expectedHeader: getCleanCertContents([]string{minimalCert}), }, { desc: "TLS with complete certificate, with pem option true", - certContents: []string{completeCert}, + certContents: []string{minimalCheeseCrt}, config: config.PassTLSClientCert{PEM: true}, - expectedHeader: getCleanCertContents([]string{completeCert}), + expectedHeader: getCleanCertContents([]string{minimalCheeseCrt}), }, { desc: "TLS with two certificate, with pem option true", - certContents: []string{minimalCert, completeCert}, + certContents: []string{minimalCert, minimalCheeseCrt}, config: config.PassTLSClientCert{PEM: true}, - expectedHeader: getCleanCertContents([]string{minimalCert, completeCert}), + expectedHeader: getCleanCertContents([]string{minimalCert, minimalCheeseCrt}), }, } @@ -356,9 +481,9 @@ func TestGetSans(t *testing.T) { } -func TestTLSClientHeadersWithCertInfos(t *testing.T) { - minimalCertAllInfos := `Subject="C=FR,ST=Some-State,O=Internet Widgits Pty Ltd",NB=1531902496,NA=1534494496,SAN=` - completeCertAllInfos := `Subject="C=FR,ST=SomeState,L=Toulouse,O=Cheese,CN=*.cheese.org",NB=1531900816,NA=1563436816,SAN=*.cheese.org,*.cheese.net,cheese.in,test@cheese.org,test@cheese.net,10.0.1.0,10.0.1.2` +func TestTLSClientHeadersWithCertInfo(t *testing.T) { + minimalCheeseCertAllInfo := `Subject="C=FR,ST=Some-State,O=Cheese",Issuer="DC=org,DC=cheese,C=FR,C=US,ST=Signing State,ST=Signing State 2,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=Simple Signing CA 2",NB=1544094636,NA=1632568236,SAN=` + completeCertAllInfo := `Subject="DC=org,DC=cheese,C=FR,C=US,ST=Cheese org state,ST=Cheese com state,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=*.cheese.com",Issuer="DC=org,DC=cheese,C=FR,C=US,ST=Signing State,ST=Signing State 2,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=Simple Signing CA 2",NB=1544094616,NA=1607166616,SAN=*.cheese.org,*.cheese.net,*.cheese.com,test@cheese.org,test@cheese.net,10.0.1.0,10.0.1.2` testCases := []struct { desc string @@ -374,10 +499,10 @@ func TestTLSClientHeadersWithCertInfos(t *testing.T) { certContents: []string{minimalCert}, }, { - desc: "No TLS, with pem option true", + desc: "No TLS, with subject info", config: config.PassTLSClientCert{ - Infos: &config.TLSClientCertificateInfos{ - Subject: &config.TLSCLientCertificateSubjectInfos{ + Info: &config.TLSClientCertificateInfo{ + Subject: &config.TLSCLientCertificateDNInfo{ CommonName: true, Organization: true, Locality: true, @@ -389,87 +514,120 @@ func TestTLSClientHeadersWithCertInfos(t *testing.T) { }, }, { - desc: "No TLS, with pem option true with no flag", + desc: "No TLS, with pem option false with empty subject info", config: config.PassTLSClientCert{ PEM: false, - Infos: &config.TLSClientCertificateInfos{ - Subject: &config.TLSCLientCertificateSubjectInfos{}, + Info: &config.TLSClientCertificateInfo{ + Subject: &config.TLSCLientCertificateDNInfo{}, }, }, }, { - desc: "TLS with simple certificate, with all infos", - certContents: []string{minimalCert}, + desc: "TLS with simple certificate, with all info", + certContents: []string{minimalCheeseCrt}, config: config.PassTLSClientCert{ - Infos: &config.TLSClientCertificateInfos{ + Info: &config.TLSClientCertificateInfo{ NotAfter: true, NotBefore: true, - Subject: &config.TLSCLientCertificateSubjectInfos{ - CommonName: true, - Organization: true, - Locality: true, - Province: true, - Country: true, - SerialNumber: true, + Sans: true, + Subject: &config.TLSCLientCertificateDNInfo{ + CommonName: true, + Country: true, + DomainComponent: true, + Locality: true, + Organization: true, + Province: true, + SerialNumber: true, + }, + Issuer: &config.TLSCLientCertificateDNInfo{ + CommonName: true, + Country: true, + DomainComponent: true, + Locality: true, + Organization: true, + Province: true, + SerialNumber: true, }, - Sans: true, }, }, - expectedHeader: url.QueryEscape(minimalCertAllInfos), + expectedHeader: url.QueryEscape(minimalCheeseCertAllInfo), }, { - desc: "TLS with simple certificate, with some infos", - certContents: []string{minimalCert}, + desc: "TLS with simple certificate, with some info", + certContents: []string{minimalCheeseCrt}, config: config.PassTLSClientCert{ - Infos: &config.TLSClientCertificateInfos{ + Info: &config.TLSClientCertificateInfo{ NotAfter: true, - Subject: &config.TLSCLientCertificateSubjectInfos{ + Sans: true, + Subject: &config.TLSCLientCertificateDNInfo{ Organization: true, }, - Sans: true, + Issuer: &config.TLSCLientCertificateDNInfo{ + Country: true, + }, }, }, - expectedHeader: url.QueryEscape(`Subject="O=Internet Widgits Pty Ltd",NA=1534494496,SAN=`), + expectedHeader: url.QueryEscape(`Subject="O=Cheese",Issuer="C=FR,C=US",NA=1632568236,SAN=`), }, { - desc: "TLS with complete certificate, with all infos", - certContents: []string{completeCert}, + desc: "TLS with complete certificate, with all info", + certContents: []string{completeCheeseCrt}, config: config.PassTLSClientCert{ - Infos: &config.TLSClientCertificateInfos{ + Info: &config.TLSClientCertificateInfo{ NotAfter: true, NotBefore: true, - Subject: &config.TLSCLientCertificateSubjectInfos{ - CommonName: true, - Organization: true, - Locality: true, - Province: true, - Country: true, - SerialNumber: true, + Sans: true, + Subject: &config.TLSCLientCertificateDNInfo{ + Country: true, + Province: true, + Locality: true, + Organization: true, + CommonName: true, + SerialNumber: true, + DomainComponent: true, + }, + Issuer: &config.TLSCLientCertificateDNInfo{ + Country: true, + Province: true, + Locality: true, + Organization: true, + CommonName: true, + SerialNumber: true, + DomainComponent: true, }, - Sans: true, }, }, - expectedHeader: url.QueryEscape(completeCertAllInfos), + expectedHeader: url.QueryEscape(completeCertAllInfo), }, { - desc: "TLS with 2 certificates, with all infos", - certContents: []string{minimalCert, completeCert}, + desc: "TLS with 2 certificates, with all info", + certContents: []string{minimalCheeseCrt, completeCheeseCrt}, config: config.PassTLSClientCert{ - Infos: &config.TLSClientCertificateInfos{ + Info: &config.TLSClientCertificateInfo{ NotAfter: true, NotBefore: true, - Subject: &config.TLSCLientCertificateSubjectInfos{ - CommonName: true, - Organization: true, - Locality: true, - Province: true, - Country: true, - SerialNumber: true, + Sans: true, + Subject: &config.TLSCLientCertificateDNInfo{ + Country: true, + Province: true, + Locality: true, + Organization: true, + CommonName: true, + SerialNumber: true, + DomainComponent: true, + }, + Issuer: &config.TLSCLientCertificateDNInfo{ + Country: true, + Province: true, + Locality: true, + Organization: true, + CommonName: true, + SerialNumber: true, + DomainComponent: true, }, - Sans: true, }, }, - expectedHeader: url.QueryEscape(strings.Join([]string{minimalCertAllInfos, completeCertAllInfos}, ";")), + expectedHeader: url.QueryEscape(strings.Join([]string{minimalCheeseCertAllInfo, completeCertAllInfo}, ";")), }, } @@ -494,11 +652,11 @@ func TestTLSClientHeadersWithCertInfos(t *testing.T) { require.Equal(t, "bar", res.Body.String(), "Should be the expected body") if test.expectedHeader != "" { - require.Equal(t, test.expectedHeader, req.Header.Get(xForwardedTLSClientCertInfos), "The request header should contain the cleaned certificate") + require.Equal(t, test.expectedHeader, req.Header.Get(xForwardedTLSClientCertInfo), "The request header should contain the cleaned certificate") } else { - require.Empty(t, req.Header.Get(xForwardedTLSClientCertInfos)) + require.Empty(t, req.Header.Get(xForwardedTLSClientCertInfo)) } - require.Empty(t, res.Header().Get(xForwardedTLSClientCertInfos), "The response header should be always empty") + require.Empty(t, res.Header().Get(xForwardedTLSClientCertInfo), "The response header should be always empty") }) } diff --git a/provider/label/parser_test.go b/provider/label/parser_test.go index 8c328ca4c..6d546d7a0 100644 --- a/provider/label/parser_test.go +++ b/provider/label/parser_test.go @@ -13,92 +13,93 @@ import ( func TestDecode(t *testing.T) { labels := map[string]string{ - "traefik.middlewares.Middleware0.addprefix.prefix": "foobar", - "traefik.middlewares.Middleware1.basicauth.headerfield": "foobar", - "traefik.middlewares.Middleware1.basicauth.realm": "foobar", - "traefik.middlewares.Middleware1.basicauth.removeheader": "true", - "traefik.middlewares.Middleware1.basicauth.users": "foobar, fiibar", - "traefik.middlewares.Middleware1.basicauth.usersfile": "foobar", - "traefik.middlewares.Middleware2.buffering.maxrequestbodybytes": "42", - "traefik.middlewares.Middleware2.buffering.maxresponsebodybytes": "42", - "traefik.middlewares.Middleware2.buffering.memrequestbodybytes": "42", - "traefik.middlewares.Middleware2.buffering.memresponsebodybytes": "42", - "traefik.middlewares.Middleware2.buffering.retryexpression": "foobar", - "traefik.middlewares.Middleware3.chain.middlewares": "foobar, fiibar", - "traefik.middlewares.Middleware4.circuitbreaker.expression": "foobar", - "traefik.middlewares.Middleware5.digestauth.headerfield": "foobar", - "traefik.middlewares.Middleware5.digestauth.realm": "foobar", - "traefik.middlewares.Middleware5.digestauth.removeheader": "true", - "traefik.middlewares.Middleware5.digestauth.users": "foobar, fiibar", - "traefik.middlewares.Middleware5.digestauth.usersfile": "foobar", - "traefik.middlewares.Middleware6.errors.query": "foobar", - "traefik.middlewares.Middleware6.errors.service": "foobar", - "traefik.middlewares.Middleware6.errors.status": "foobar, fiibar", - "traefik.middlewares.Middleware7.forwardauth.address": "foobar", - "traefik.middlewares.Middleware7.forwardauth.authresponseheaders": "foobar, fiibar", - "traefik.middlewares.Middleware7.forwardauth.tls.ca": "foobar", - "traefik.middlewares.Middleware7.forwardauth.tls.caoptional": "true", - "traefik.middlewares.Middleware7.forwardauth.tls.cert": "foobar", - "traefik.middlewares.Middleware7.forwardauth.tls.insecureskipverify": "true", - "traefik.middlewares.Middleware7.forwardauth.tls.key": "foobar", - "traefik.middlewares.Middleware7.forwardauth.trustforwardheader": "true", - "traefik.middlewares.Middleware8.headers.allowedhosts": "foobar, fiibar", - "traefik.middlewares.Middleware8.headers.browserxssfilter": "true", - "traefik.middlewares.Middleware8.headers.contentsecuritypolicy": "foobar", - "traefik.middlewares.Middleware8.headers.contenttypenosniff": "true", - "traefik.middlewares.Middleware8.headers.custombrowserxssvalue": "foobar", - "traefik.middlewares.Middleware8.headers.customframeoptionsvalue": "foobar", - "traefik.middlewares.Middleware8.headers.customrequestheaders.name0": "foobar", - "traefik.middlewares.Middleware8.headers.customrequestheaders.name1": "foobar", - "traefik.middlewares.Middleware8.headers.customresponseheaders.name0": "foobar", - "traefik.middlewares.Middleware8.headers.customresponseheaders.name1": "foobar", - "traefik.middlewares.Middleware8.headers.forcestsheader": "true", - "traefik.middlewares.Middleware8.headers.framedeny": "true", - "traefik.middlewares.Middleware8.headers.hostsproxyheaders": "foobar, fiibar", - "traefik.middlewares.Middleware8.headers.isdevelopment": "true", - "traefik.middlewares.Middleware8.headers.publickey": "foobar", - "traefik.middlewares.Middleware8.headers.referrerpolicy": "foobar", - "traefik.middlewares.Middleware8.headers.sslforcehost": "true", - "traefik.middlewares.Middleware8.headers.sslhost": "foobar", - "traefik.middlewares.Middleware8.headers.sslproxyheaders.name0": "foobar", - "traefik.middlewares.Middleware8.headers.sslproxyheaders.name1": "foobar", - "traefik.middlewares.Middleware8.headers.sslredirect": "true", - "traefik.middlewares.Middleware8.headers.ssltemporaryredirect": "true", - "traefik.middlewares.Middleware8.headers.stsincludesubdomains": "true", - "traefik.middlewares.Middleware8.headers.stspreload": "true", - "traefik.middlewares.Middleware8.headers.stsseconds": "42", - "traefik.middlewares.Middleware9.ipwhitelist.ipstrategy.depth": "42", - "traefik.middlewares.Middleware9.ipwhitelist.ipstrategy.excludedips": "foobar, fiibar", - "traefik.middlewares.Middleware9.ipwhitelist.sourcerange": "foobar, fiibar", - "traefik.middlewares.Middleware10.maxconn.amount": "42", - "traefik.middlewares.Middleware10.maxconn.extractorfunc": "foobar", - "traefik.middlewares.Middleware11.passtlsclientcert.infos.notafter": "true", - "traefik.middlewares.Middleware11.passtlsclientcert.infos.notbefore": "true", - "traefik.middlewares.Middleware11.passtlsclientcert.infos.sans": "true", - "traefik.middlewares.Middleware11.passtlsclientcert.infos.subject.commonname": "true", - "traefik.middlewares.Middleware11.passtlsclientcert.infos.subject.country": "true", - "traefik.middlewares.Middleware11.passtlsclientcert.infos.subject.locality": "true", - "traefik.middlewares.Middleware11.passtlsclientcert.infos.subject.organization": "true", - "traefik.middlewares.Middleware11.passtlsclientcert.infos.subject.province": "true", - "traefik.middlewares.Middleware11.passtlsclientcert.infos.subject.serialnumber": "true", - "traefik.middlewares.Middleware11.passtlsclientcert.pem": "true", - "traefik.middlewares.Middleware12.ratelimit.extractorfunc": "foobar", - "traefik.middlewares.Middleware12.ratelimit.rateset.Rate0.average": "42", - "traefik.middlewares.Middleware12.ratelimit.rateset.Rate0.burst": "42", - "traefik.middlewares.Middleware12.ratelimit.rateset.Rate0.period": "42", - "traefik.middlewares.Middleware12.ratelimit.rateset.Rate1.average": "42", - "traefik.middlewares.Middleware12.ratelimit.rateset.Rate1.burst": "42", - "traefik.middlewares.Middleware12.ratelimit.rateset.Rate1.period": "42", - "traefik.middlewares.Middleware13.redirect.permanent": "true", - "traefik.middlewares.Middleware13.redirect.regex": "foobar", - "traefik.middlewares.Middleware13.redirect.replacement": "foobar", - "traefik.middlewares.Middleware14.replacepath.path": "foobar", - "traefik.middlewares.Middleware15.replacepathregex.regex": "foobar", - "traefik.middlewares.Middleware15.replacepathregex.replacement": "foobar", - "traefik.middlewares.Middleware16.retry.attempts": "42", - "traefik.middlewares.Middleware17.stripprefix.prefixes": "foobar, fiibar", - "traefik.middlewares.Middleware18.stripprefixregex.regex": "foobar, fiibar", - "traefik.middlewares.Middleware19.compress": "true", + "traefik.middlewares.Middleware0.addprefix.prefix": "foobar", + "traefik.middlewares.Middleware1.basicauth.headerfield": "foobar", + "traefik.middlewares.Middleware1.basicauth.realm": "foobar", + "traefik.middlewares.Middleware1.basicauth.removeheader": "true", + "traefik.middlewares.Middleware1.basicauth.users": "foobar, fiibar", + "traefik.middlewares.Middleware1.basicauth.usersfile": "foobar", + "traefik.middlewares.Middleware2.buffering.maxrequestbodybytes": "42", + "traefik.middlewares.Middleware2.buffering.maxresponsebodybytes": "42", + "traefik.middlewares.Middleware2.buffering.memrequestbodybytes": "42", + "traefik.middlewares.Middleware2.buffering.memresponsebodybytes": "42", + "traefik.middlewares.Middleware2.buffering.retryexpression": "foobar", + "traefik.middlewares.Middleware3.chain.middlewares": "foobar, fiibar", + "traefik.middlewares.Middleware4.circuitbreaker.expression": "foobar", + "traefik.middlewares.Middleware5.digestauth.headerfield": "foobar", + "traefik.middlewares.Middleware5.digestauth.realm": "foobar", + "traefik.middlewares.Middleware5.digestauth.removeheader": "true", + "traefik.middlewares.Middleware5.digestauth.users": "foobar, fiibar", + "traefik.middlewares.Middleware5.digestauth.usersfile": "foobar", + "traefik.middlewares.Middleware6.errors.query": "foobar", + "traefik.middlewares.Middleware6.errors.service": "foobar", + "traefik.middlewares.Middleware6.errors.status": "foobar, fiibar", + "traefik.middlewares.Middleware7.forwardauth.address": "foobar", + "traefik.middlewares.Middleware7.forwardauth.authresponseheaders": "foobar, fiibar", + "traefik.middlewares.Middleware7.forwardauth.tls.ca": "foobar", + "traefik.middlewares.Middleware7.forwardauth.tls.caoptional": "true", + "traefik.middlewares.Middleware7.forwardauth.tls.cert": "foobar", + "traefik.middlewares.Middleware7.forwardauth.tls.insecureskipverify": "true", + "traefik.middlewares.Middleware7.forwardauth.tls.key": "foobar", + "traefik.middlewares.Middleware7.forwardauth.trustforwardheader": "true", + "traefik.middlewares.Middleware8.headers.allowedhosts": "foobar, fiibar", + "traefik.middlewares.Middleware8.headers.browserxssfilter": "true", + "traefik.middlewares.Middleware8.headers.contentsecuritypolicy": "foobar", + "traefik.middlewares.Middleware8.headers.contenttypenosniff": "true", + "traefik.middlewares.Middleware8.headers.custombrowserxssvalue": "foobar", + "traefik.middlewares.Middleware8.headers.customframeoptionsvalue": "foobar", + "traefik.middlewares.Middleware8.headers.customrequestheaders.name0": "foobar", + "traefik.middlewares.Middleware8.headers.customrequestheaders.name1": "foobar", + "traefik.middlewares.Middleware8.headers.customresponseheaders.name0": "foobar", + "traefik.middlewares.Middleware8.headers.customresponseheaders.name1": "foobar", + "traefik.middlewares.Middleware8.headers.forcestsheader": "true", + "traefik.middlewares.Middleware8.headers.framedeny": "true", + "traefik.middlewares.Middleware8.headers.hostsproxyheaders": "foobar, fiibar", + "traefik.middlewares.Middleware8.headers.isdevelopment": "true", + "traefik.middlewares.Middleware8.headers.publickey": "foobar", + "traefik.middlewares.Middleware8.headers.referrerpolicy": "foobar", + "traefik.middlewares.Middleware8.headers.sslforcehost": "true", + "traefik.middlewares.Middleware8.headers.sslhost": "foobar", + "traefik.middlewares.Middleware8.headers.sslproxyheaders.name0": "foobar", + "traefik.middlewares.Middleware8.headers.sslproxyheaders.name1": "foobar", + "traefik.middlewares.Middleware8.headers.sslredirect": "true", + "traefik.middlewares.Middleware8.headers.ssltemporaryredirect": "true", + "traefik.middlewares.Middleware8.headers.stsincludesubdomains": "true", + "traefik.middlewares.Middleware8.headers.stspreload": "true", + "traefik.middlewares.Middleware8.headers.stsseconds": "42", + "traefik.middlewares.Middleware9.ipwhitelist.ipstrategy.depth": "42", + "traefik.middlewares.Middleware9.ipwhitelist.ipstrategy.excludedips": "foobar, fiibar", + "traefik.middlewares.Middleware9.ipwhitelist.sourcerange": "foobar, fiibar", + "traefik.middlewares.Middleware10.maxconn.amount": "42", + "traefik.middlewares.Middleware10.maxconn.extractorfunc": "foobar", + "traefik.middlewares.Middleware11.passtlsclientcert.info.notafter": "true", + "traefik.middlewares.Middleware11.passtlsclientcert.info.notbefore": "true", + "traefik.middlewares.Middleware11.passtlsclientcert.info.sans": "true", + "traefik.middlewares.Middleware11.passtlsclientcert.info.subject.commonname": "true", + "traefik.middlewares.Middleware11.passtlsclientcert.info.subject.country": "true", + "traefik.middlewares.Middleware11.passtlsclientcert.info.subject.domaincomponent": "true", + "traefik.middlewares.Middleware11.passtlsclientcert.info.subject.locality": "true", + "traefik.middlewares.Middleware11.passtlsclientcert.info.subject.organization": "true", + "traefik.middlewares.Middleware11.passtlsclientcert.info.subject.province": "true", + "traefik.middlewares.Middleware11.passtlsclientcert.info.subject.serialnumber": "true", + "traefik.middlewares.Middleware11.passtlsclientcert.pem": "true", + "traefik.middlewares.Middleware12.ratelimit.extractorfunc": "foobar", + "traefik.middlewares.Middleware12.ratelimit.rateset.Rate0.average": "42", + "traefik.middlewares.Middleware12.ratelimit.rateset.Rate0.burst": "42", + "traefik.middlewares.Middleware12.ratelimit.rateset.Rate0.period": "42", + "traefik.middlewares.Middleware12.ratelimit.rateset.Rate1.average": "42", + "traefik.middlewares.Middleware12.ratelimit.rateset.Rate1.burst": "42", + "traefik.middlewares.Middleware12.ratelimit.rateset.Rate1.period": "42", + "traefik.middlewares.Middleware13.redirect.permanent": "true", + "traefik.middlewares.Middleware13.redirect.regex": "foobar", + "traefik.middlewares.Middleware13.redirect.replacement": "foobar", + "traefik.middlewares.Middleware14.replacepath.path": "foobar", + "traefik.middlewares.Middleware15.replacepathregex.regex": "foobar", + "traefik.middlewares.Middleware15.replacepathregex.replacement": "foobar", + "traefik.middlewares.Middleware16.retry.attempts": "42", + "traefik.middlewares.Middleware17.stripprefix.prefixes": "foobar, fiibar", + "traefik.middlewares.Middleware18.stripprefixregex.regex": "foobar, fiibar", + "traefik.middlewares.Middleware19.compress": "true", "traefik.routers.Router0.entrypoints": "foobar, fiibar", "traefik.routers.Router0.middlewares": "foobar, fiibar", @@ -201,16 +202,17 @@ func TestDecode(t *testing.T) { "Middleware11": { PassTLSClientCert: &config.PassTLSClientCert{ PEM: true, - Infos: &config.TLSClientCertificateInfos{ + Info: &config.TLSClientCertificateInfo{ NotAfter: true, NotBefore: true, - Subject: &config.TLSCLientCertificateSubjectInfos{ - Country: true, - Province: true, - Locality: true, - Organization: true, - CommonName: true, - SerialNumber: true, + Subject: &config.TLSCLientCertificateDNInfo{ + Country: true, + Province: true, + Locality: true, + Organization: true, + CommonName: true, + SerialNumber: true, + DomainComponent: true, }, Sans: true, }, @@ -514,16 +516,17 @@ func TestEncode(t *testing.T) { "Middleware11": { PassTLSClientCert: &config.PassTLSClientCert{ PEM: true, - Infos: &config.TLSClientCertificateInfos{ + Info: &config.TLSClientCertificateInfo{ NotAfter: true, NotBefore: true, - Subject: &config.TLSCLientCertificateSubjectInfos{ - Country: true, - Province: true, - Locality: true, - Organization: true, - CommonName: true, - SerialNumber: true, + Subject: &config.TLSCLientCertificateDNInfo{ + Country: true, + Province: true, + Locality: true, + Organization: true, + CommonName: true, + SerialNumber: true, + DomainComponent: true, }, Sans: true, }, @@ -771,92 +774,93 @@ func TestEncode(t *testing.T) { require.NoError(t, err) expected := map[string]string{ - "traefik.Middlewares.Middleware0.AddPrefix.Prefix": "foobar", - "traefik.Middlewares.Middleware1.BasicAuth.HeaderField": "foobar", - "traefik.Middlewares.Middleware1.BasicAuth.Realm": "foobar", - "traefik.Middlewares.Middleware1.BasicAuth.RemoveHeader": "true", - "traefik.Middlewares.Middleware1.BasicAuth.Users": "foobar, fiibar", - "traefik.Middlewares.Middleware1.BasicAuth.UsersFile": "foobar", - "traefik.Middlewares.Middleware2.Buffering.MaxRequestBodyBytes": "42", - "traefik.Middlewares.Middleware2.Buffering.MaxResponseBodyBytes": "42", - "traefik.Middlewares.Middleware2.Buffering.MemRequestBodyBytes": "42", - "traefik.Middlewares.Middleware2.Buffering.MemResponseBodyBytes": "42", - "traefik.Middlewares.Middleware2.Buffering.RetryExpression": "foobar", - "traefik.Middlewares.Middleware3.Chain.Middlewares": "foobar, fiibar", - "traefik.Middlewares.Middleware4.CircuitBreaker.Expression": "foobar", - "traefik.Middlewares.Middleware5.DigestAuth.HeaderField": "foobar", - "traefik.Middlewares.Middleware5.DigestAuth.Realm": "foobar", - "traefik.Middlewares.Middleware5.DigestAuth.RemoveHeader": "true", - "traefik.Middlewares.Middleware5.DigestAuth.Users": "foobar, fiibar", - "traefik.Middlewares.Middleware5.DigestAuth.UsersFile": "foobar", - "traefik.Middlewares.Middleware6.Errors.Query": "foobar", - "traefik.Middlewares.Middleware6.Errors.Service": "foobar", - "traefik.Middlewares.Middleware6.Errors.Status": "foobar, fiibar", - "traefik.Middlewares.Middleware7.ForwardAuth.Address": "foobar", - "traefik.Middlewares.Middleware7.ForwardAuth.AuthResponseHeaders": "foobar, fiibar", - "traefik.Middlewares.Middleware7.ForwardAuth.TLS.CA": "foobar", - "traefik.Middlewares.Middleware7.ForwardAuth.TLS.CAOptional": "true", - "traefik.Middlewares.Middleware7.ForwardAuth.TLS.Cert": "foobar", - "traefik.Middlewares.Middleware7.ForwardAuth.TLS.InsecureSkipVerify": "true", - "traefik.Middlewares.Middleware7.ForwardAuth.TLS.Key": "foobar", - "traefik.Middlewares.Middleware7.ForwardAuth.TrustForwardHeader": "true", - "traefik.Middlewares.Middleware8.Headers.AllowedHosts": "foobar, fiibar", - "traefik.Middlewares.Middleware8.Headers.BrowserXSSFilter": "true", - "traefik.Middlewares.Middleware8.Headers.ContentSecurityPolicy": "foobar", - "traefik.Middlewares.Middleware8.Headers.ContentTypeNosniff": "true", - "traefik.Middlewares.Middleware8.Headers.CustomBrowserXSSValue": "foobar", - "traefik.Middlewares.Middleware8.Headers.CustomFrameOptionsValue": "foobar", - "traefik.Middlewares.Middleware8.Headers.CustomRequestHeaders.name0": "foobar", - "traefik.Middlewares.Middleware8.Headers.CustomRequestHeaders.name1": "foobar", - "traefik.Middlewares.Middleware8.Headers.CustomResponseHeaders.name0": "foobar", - "traefik.Middlewares.Middleware8.Headers.CustomResponseHeaders.name1": "foobar", - "traefik.Middlewares.Middleware8.Headers.ForceSTSHeader": "true", - "traefik.Middlewares.Middleware8.Headers.FrameDeny": "true", - "traefik.Middlewares.Middleware8.Headers.HostsProxyHeaders": "foobar, fiibar", - "traefik.Middlewares.Middleware8.Headers.IsDevelopment": "true", - "traefik.Middlewares.Middleware8.Headers.PublicKey": "foobar", - "traefik.Middlewares.Middleware8.Headers.ReferrerPolicy": "foobar", - "traefik.Middlewares.Middleware8.Headers.SSLForceHost": "true", - "traefik.Middlewares.Middleware8.Headers.SSLHost": "foobar", - "traefik.Middlewares.Middleware8.Headers.SSLProxyHeaders.name0": "foobar", - "traefik.Middlewares.Middleware8.Headers.SSLProxyHeaders.name1": "foobar", - "traefik.Middlewares.Middleware8.Headers.SSLRedirect": "true", - "traefik.Middlewares.Middleware8.Headers.SSLTemporaryRedirect": "true", - "traefik.Middlewares.Middleware8.Headers.STSIncludeSubdomains": "true", - "traefik.Middlewares.Middleware8.Headers.STSPreload": "true", - "traefik.Middlewares.Middleware8.Headers.STSSeconds": "42", - "traefik.Middlewares.Middleware9.IPWhiteList.IPStrategy.Depth": "42", - "traefik.Middlewares.Middleware9.IPWhiteList.IPStrategy.ExcludedIPs": "foobar, fiibar", - "traefik.Middlewares.Middleware9.IPWhiteList.SourceRange": "foobar, fiibar", - "traefik.Middlewares.Middleware10.MaxConn.Amount": "42", - "traefik.Middlewares.Middleware10.MaxConn.ExtractorFunc": "foobar", - "traefik.Middlewares.Middleware11.PassTLSClientCert.Infos.NotAfter": "true", - "traefik.Middlewares.Middleware11.PassTLSClientCert.Infos.NotBefore": "true", - "traefik.Middlewares.Middleware11.PassTLSClientCert.Infos.Sans": "true", - "traefik.Middlewares.Middleware11.PassTLSClientCert.Infos.Subject.CommonName": "true", - "traefik.Middlewares.Middleware11.PassTLSClientCert.Infos.Subject.Country": "true", - "traefik.Middlewares.Middleware11.PassTLSClientCert.Infos.Subject.Locality": "true", - "traefik.Middlewares.Middleware11.PassTLSClientCert.Infos.Subject.Organization": "true", - "traefik.Middlewares.Middleware11.PassTLSClientCert.Infos.Subject.Province": "true", - "traefik.Middlewares.Middleware11.PassTLSClientCert.Infos.Subject.SerialNumber": "true", - "traefik.Middlewares.Middleware11.PassTLSClientCert.PEM": "true", - "traefik.Middlewares.Middleware12.RateLimit.ExtractorFunc": "foobar", - "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Average": "42", - "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Burst": "42", - "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Period": "42", - "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Average": "42", - "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Burst": "42", - "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Period": "42", - "traefik.Middlewares.Middleware13.Redirect.Permanent": "true", - "traefik.Middlewares.Middleware13.Redirect.Regex": "foobar", - "traefik.Middlewares.Middleware13.Redirect.Replacement": "foobar", - "traefik.Middlewares.Middleware14.ReplacePath.Path": "foobar", - "traefik.Middlewares.Middleware15.ReplacePathRegex.Regex": "foobar", - "traefik.Middlewares.Middleware15.ReplacePathRegex.Replacement": "foobar", - "traefik.Middlewares.Middleware16.Retry.Attempts": "42", - "traefik.Middlewares.Middleware17.StripPrefix.Prefixes": "foobar, fiibar", - "traefik.Middlewares.Middleware18.StripPrefixRegex.Regex": "foobar, fiibar", - "traefik.Middlewares.Middleware19.Compress": "true", + "traefik.Middlewares.Middleware0.AddPrefix.Prefix": "foobar", + "traefik.Middlewares.Middleware1.BasicAuth.HeaderField": "foobar", + "traefik.Middlewares.Middleware1.BasicAuth.Realm": "foobar", + "traefik.Middlewares.Middleware1.BasicAuth.RemoveHeader": "true", + "traefik.Middlewares.Middleware1.BasicAuth.Users": "foobar, fiibar", + "traefik.Middlewares.Middleware1.BasicAuth.UsersFile": "foobar", + "traefik.Middlewares.Middleware2.Buffering.MaxRequestBodyBytes": "42", + "traefik.Middlewares.Middleware2.Buffering.MaxResponseBodyBytes": "42", + "traefik.Middlewares.Middleware2.Buffering.MemRequestBodyBytes": "42", + "traefik.Middlewares.Middleware2.Buffering.MemResponseBodyBytes": "42", + "traefik.Middlewares.Middleware2.Buffering.RetryExpression": "foobar", + "traefik.Middlewares.Middleware3.Chain.Middlewares": "foobar, fiibar", + "traefik.Middlewares.Middleware4.CircuitBreaker.Expression": "foobar", + "traefik.Middlewares.Middleware5.DigestAuth.HeaderField": "foobar", + "traefik.Middlewares.Middleware5.DigestAuth.Realm": "foobar", + "traefik.Middlewares.Middleware5.DigestAuth.RemoveHeader": "true", + "traefik.Middlewares.Middleware5.DigestAuth.Users": "foobar, fiibar", + "traefik.Middlewares.Middleware5.DigestAuth.UsersFile": "foobar", + "traefik.Middlewares.Middleware6.Errors.Query": "foobar", + "traefik.Middlewares.Middleware6.Errors.Service": "foobar", + "traefik.Middlewares.Middleware6.Errors.Status": "foobar, fiibar", + "traefik.Middlewares.Middleware7.ForwardAuth.Address": "foobar", + "traefik.Middlewares.Middleware7.ForwardAuth.AuthResponseHeaders": "foobar, fiibar", + "traefik.Middlewares.Middleware7.ForwardAuth.TLS.CA": "foobar", + "traefik.Middlewares.Middleware7.ForwardAuth.TLS.CAOptional": "true", + "traefik.Middlewares.Middleware7.ForwardAuth.TLS.Cert": "foobar", + "traefik.Middlewares.Middleware7.ForwardAuth.TLS.InsecureSkipVerify": "true", + "traefik.Middlewares.Middleware7.ForwardAuth.TLS.Key": "foobar", + "traefik.Middlewares.Middleware7.ForwardAuth.TrustForwardHeader": "true", + "traefik.Middlewares.Middleware8.Headers.AllowedHosts": "foobar, fiibar", + "traefik.Middlewares.Middleware8.Headers.BrowserXSSFilter": "true", + "traefik.Middlewares.Middleware8.Headers.ContentSecurityPolicy": "foobar", + "traefik.Middlewares.Middleware8.Headers.ContentTypeNosniff": "true", + "traefik.Middlewares.Middleware8.Headers.CustomBrowserXSSValue": "foobar", + "traefik.Middlewares.Middleware8.Headers.CustomFrameOptionsValue": "foobar", + "traefik.Middlewares.Middleware8.Headers.CustomRequestHeaders.name0": "foobar", + "traefik.Middlewares.Middleware8.Headers.CustomRequestHeaders.name1": "foobar", + "traefik.Middlewares.Middleware8.Headers.CustomResponseHeaders.name0": "foobar", + "traefik.Middlewares.Middleware8.Headers.CustomResponseHeaders.name1": "foobar", + "traefik.Middlewares.Middleware8.Headers.ForceSTSHeader": "true", + "traefik.Middlewares.Middleware8.Headers.FrameDeny": "true", + "traefik.Middlewares.Middleware8.Headers.HostsProxyHeaders": "foobar, fiibar", + "traefik.Middlewares.Middleware8.Headers.IsDevelopment": "true", + "traefik.Middlewares.Middleware8.Headers.PublicKey": "foobar", + "traefik.Middlewares.Middleware8.Headers.ReferrerPolicy": "foobar", + "traefik.Middlewares.Middleware8.Headers.SSLForceHost": "true", + "traefik.Middlewares.Middleware8.Headers.SSLHost": "foobar", + "traefik.Middlewares.Middleware8.Headers.SSLProxyHeaders.name0": "foobar", + "traefik.Middlewares.Middleware8.Headers.SSLProxyHeaders.name1": "foobar", + "traefik.Middlewares.Middleware8.Headers.SSLRedirect": "true", + "traefik.Middlewares.Middleware8.Headers.SSLTemporaryRedirect": "true", + "traefik.Middlewares.Middleware8.Headers.STSIncludeSubdomains": "true", + "traefik.Middlewares.Middleware8.Headers.STSPreload": "true", + "traefik.Middlewares.Middleware8.Headers.STSSeconds": "42", + "traefik.Middlewares.Middleware9.IPWhiteList.IPStrategy.Depth": "42", + "traefik.Middlewares.Middleware9.IPWhiteList.IPStrategy.ExcludedIPs": "foobar, fiibar", + "traefik.Middlewares.Middleware9.IPWhiteList.SourceRange": "foobar, fiibar", + "traefik.Middlewares.Middleware10.MaxConn.Amount": "42", + "traefik.Middlewares.Middleware10.MaxConn.ExtractorFunc": "foobar", + "traefik.Middlewares.Middleware11.PassTLSClientCert.Info.NotAfter": "true", + "traefik.Middlewares.Middleware11.PassTLSClientCert.Info.NotBefore": "true", + "traefik.Middlewares.Middleware11.PassTLSClientCert.Info.Sans": "true", + "traefik.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.CommonName": "true", + "traefik.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Country": "true", + "traefik.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.DomainComponent": "true", + "traefik.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Locality": "true", + "traefik.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Organization": "true", + "traefik.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Province": "true", + "traefik.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.SerialNumber": "true", + "traefik.Middlewares.Middleware11.PassTLSClientCert.PEM": "true", + "traefik.Middlewares.Middleware12.RateLimit.ExtractorFunc": "foobar", + "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Average": "42", + "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Burst": "42", + "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Period": "42", + "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Average": "42", + "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Burst": "42", + "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Period": "42", + "traefik.Middlewares.Middleware13.Redirect.Permanent": "true", + "traefik.Middlewares.Middleware13.Redirect.Regex": "foobar", + "traefik.Middlewares.Middleware13.Redirect.Replacement": "foobar", + "traefik.Middlewares.Middleware14.ReplacePath.Path": "foobar", + "traefik.Middlewares.Middleware15.ReplacePathRegex.Regex": "foobar", + "traefik.Middlewares.Middleware15.ReplacePathRegex.Replacement": "foobar", + "traefik.Middlewares.Middleware16.Retry.Attempts": "42", + "traefik.Middlewares.Middleware17.StripPrefix.Prefixes": "foobar, fiibar", + "traefik.Middlewares.Middleware18.StripPrefixRegex.Regex": "foobar, fiibar", + "traefik.Middlewares.Middleware19.Compress": "true", "traefik.Routers.Router0.EntryPoints": "foobar, fiibar", "traefik.Routers.Router0.Middlewares": "foobar, fiibar",