Add organizationalUnit to passtlscert middleware
This commit is contained in:
parent
c76d58d532
commit
817ac8f256
18 changed files with 339 additions and 157 deletions
|
@ -35,8 +35,10 @@ 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 {
|
||||
// IssuerDistinguishedNameOptions is a struct for specifying the configuration
|
||||
// for the distinguished name info of the issuer. This information is defined in
|
||||
// RFC3739, section 3.1.1.
|
||||
type IssuerDistinguishedNameOptions struct {
|
||||
CommonName bool
|
||||
CountryName bool
|
||||
DomainComponent bool
|
||||
|
@ -46,12 +48,12 @@ type DistinguishedNameOptions struct {
|
|||
StateOrProvinceName bool
|
||||
}
|
||||
|
||||
func newDistinguishedNameOptions(info *dynamic.TLSCLientCertificateDNInfo) *DistinguishedNameOptions {
|
||||
func newIssuerDistinguishedNameOptions(info *dynamic.TLSCLientCertificateIssuerDNInfo) *IssuerDistinguishedNameOptions {
|
||||
if info == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &DistinguishedNameOptions{
|
||||
return &IssuerDistinguishedNameOptions{
|
||||
CommonName: info.CommonName,
|
||||
CountryName: info.Country,
|
||||
DomainComponent: info.DomainComponent,
|
||||
|
@ -62,13 +64,44 @@ func newDistinguishedNameOptions(info *dynamic.TLSCLientCertificateDNInfo) *Dist
|
|||
}
|
||||
}
|
||||
|
||||
// SubjectDistinguishedNameOptions is a struct for specifying the configuration
|
||||
// for the distinguished name info of the subject. This information is defined
|
||||
// in RFC3739, section 3.1.2.
|
||||
type SubjectDistinguishedNameOptions struct {
|
||||
CommonName bool
|
||||
CountryName bool
|
||||
DomainComponent bool
|
||||
LocalityName bool
|
||||
OrganizationName bool
|
||||
OrganizationalUnitName bool
|
||||
SerialNumber bool
|
||||
StateOrProvinceName bool
|
||||
}
|
||||
|
||||
func newSubjectDistinguishedNameOptions(info *dynamic.TLSCLientCertificateSubjectDNInfo) *SubjectDistinguishedNameOptions {
|
||||
if info == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &SubjectDistinguishedNameOptions{
|
||||
CommonName: info.CommonName,
|
||||
CountryName: info.Country,
|
||||
DomainComponent: info.DomainComponent,
|
||||
LocalityName: info.Locality,
|
||||
OrganizationName: info.Organization,
|
||||
OrganizationalUnitName: info.OrganizationalUnit,
|
||||
SerialNumber: info.SerialNumber,
|
||||
StateOrProvinceName: info.Province,
|
||||
}
|
||||
}
|
||||
|
||||
// tlsClientCertificateInfo is a struct for specifying the configuration for the passTLSClientCert middleware.
|
||||
type tlsClientCertificateInfo struct {
|
||||
notAfter bool
|
||||
notBefore bool
|
||||
sans bool
|
||||
subject *DistinguishedNameOptions
|
||||
issuer *DistinguishedNameOptions
|
||||
subject *SubjectDistinguishedNameOptions
|
||||
issuer *IssuerDistinguishedNameOptions
|
||||
serialNumber bool
|
||||
}
|
||||
|
||||
|
@ -78,10 +111,10 @@ func newTLSClientCertificateInfo(info *dynamic.TLSClientCertificateInfo) *tlsCli
|
|||
}
|
||||
|
||||
return &tlsClientCertificateInfo{
|
||||
issuer: newDistinguishedNameOptions(info.Issuer),
|
||||
issuer: newIssuerDistinguishedNameOptions(info.Issuer),
|
||||
notAfter: info.NotAfter,
|
||||
notBefore: info.NotBefore,
|
||||
subject: newDistinguishedNameOptions(info.Subject),
|
||||
subject: newSubjectDistinguishedNameOptions(info.Subject),
|
||||
serialNumber: info.SerialNumber,
|
||||
sans: info.Sans,
|
||||
}
|
||||
|
@ -147,12 +180,12 @@ func (p *passTLSClientCert) getCertInfo(ctx context.Context, certs []*x509.Certi
|
|||
var values []string
|
||||
|
||||
if p.info != nil {
|
||||
subject := getDNInfo(ctx, p.info.subject, &peerCert.Subject)
|
||||
subject := getSubjectDNInfo(ctx, p.info.subject, &peerCert.Subject)
|
||||
if subject != "" {
|
||||
values = append(values, fmt.Sprintf(`Subject="%s"`, strings.TrimSuffix(subject, subFieldSeparator)))
|
||||
}
|
||||
|
||||
issuer := getDNInfo(ctx, p.info.issuer, &peerCert.Issuer)
|
||||
issuer := getIssuerDNInfo(ctx, p.info.issuer, &peerCert.Issuer)
|
||||
if issuer != "" {
|
||||
values = append(values, fmt.Sprintf(`Issuer="%s"`, strings.TrimSuffix(issuer, subFieldSeparator)))
|
||||
}
|
||||
|
@ -187,7 +220,7 @@ func (p *passTLSClientCert) getCertInfo(ctx context.Context, certs []*x509.Certi
|
|||
return strings.Join(headerValues, certSeparator)
|
||||
}
|
||||
|
||||
func getDNInfo(ctx context.Context, options *DistinguishedNameOptions, cs *pkix.Name) string {
|
||||
func getIssuerDNInfo(ctx context.Context, options *IssuerDistinguishedNameOptions, cs *pkix.Name) string {
|
||||
if options == nil {
|
||||
return ""
|
||||
}
|
||||
|
@ -229,6 +262,52 @@ func getDNInfo(ctx context.Context, options *DistinguishedNameOptions, cs *pkix.
|
|||
return content.String()
|
||||
}
|
||||
|
||||
func getSubjectDNInfo(ctx context.Context, options *SubjectDistinguishedNameOptions, cs *pkix.Name) string {
|
||||
if options == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
content := &strings.Builder{}
|
||||
|
||||
// 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%s", name.Value, subFieldSeparator))
|
||||
}
|
||||
}
|
||||
|
||||
if options.CountryName {
|
||||
writeParts(ctx, content, cs.Country, "C")
|
||||
}
|
||||
|
||||
if options.StateOrProvinceName {
|
||||
writeParts(ctx, content, cs.Province, "ST")
|
||||
}
|
||||
|
||||
if options.LocalityName {
|
||||
writeParts(ctx, content, cs.Locality, "L")
|
||||
}
|
||||
|
||||
if options.OrganizationName {
|
||||
writeParts(ctx, content, cs.Organization, "O")
|
||||
}
|
||||
|
||||
if options.OrganizationalUnitName {
|
||||
writeParts(ctx, content, cs.OrganizationalUnit, "OU")
|
||||
}
|
||||
|
||||
if options.SerialNumber {
|
||||
writePart(ctx, content, cs.SerialNumber, "SN")
|
||||
}
|
||||
|
||||
if options.CommonName {
|
||||
writePart(ctx, content, cs.CommonName, "CN")
|
||||
}
|
||||
|
||||
return content.String()
|
||||
}
|
||||
|
||||
func writeParts(ctx context.Context, content io.StringWriter, entries []string, prefix string) {
|
||||
for _, entry := range entries {
|
||||
writePart(ctx, content, entry, prefix)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue