forked from TrueCloudLab/certificates
Explicitly disable wildcard Common Name constraint
This commit is contained in:
parent
0f4ffa504a
commit
cc26a0b394
4 changed files with 92 additions and 2 deletions
|
@ -2492,6 +2492,7 @@ func TestNamePolicyEngine_X509_AllAllowed(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
engine, err := New(tt.options...)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, engine)
|
||||
gotErr := engine.IsX509CertificateAllowed(tt.cert)
|
||||
wantErr := tt.wantErr != nil
|
||||
|
||||
|
|
|
@ -28,14 +28,30 @@ func WithAllowLiteralWildcardNames() NamePolicyOption {
|
|||
|
||||
func WithPermittedCommonNames(commonNames ...string) NamePolicyOption {
|
||||
return func(g *NamePolicyEngine) error {
|
||||
g.permittedCommonNames = commonNames
|
||||
normalizedCommonNames := make([]string, len(commonNames))
|
||||
for i, commonName := range commonNames {
|
||||
normalizedCommonName, err := normalizeAndValidateCommonName(commonName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot parse permitted common name constraint %q: %w", commonName, err)
|
||||
}
|
||||
normalizedCommonNames[i] = normalizedCommonName
|
||||
}
|
||||
g.permittedCommonNames = normalizedCommonNames
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithExcludedCommonNames(commonNames ...string) NamePolicyOption {
|
||||
return func(g *NamePolicyEngine) error {
|
||||
g.excludedCommonNames = commonNames
|
||||
normalizedCommonNames := make([]string, len(commonNames))
|
||||
for i, commonName := range commonNames {
|
||||
normalizedCommonName, err := normalizeAndValidateCommonName(commonName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot parse excluded common name constraint %q: %w", commonName, err)
|
||||
}
|
||||
normalizedCommonNames[i] = normalizedCommonName
|
||||
}
|
||||
g.excludedCommonNames = normalizedCommonNames
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -242,6 +258,17 @@ func isIPv4(ip net.IP) bool {
|
|||
return ip.To4() != nil
|
||||
}
|
||||
|
||||
func normalizeAndValidateCommonName(constraint string) (string, error) {
|
||||
normalizedConstraint := strings.ToLower(strings.TrimSpace(constraint))
|
||||
if normalizedConstraint == "" {
|
||||
return "", fmt.Errorf("contraint %q can not be empty or white space string", constraint)
|
||||
}
|
||||
if normalizedConstraint == "*" {
|
||||
return "", fmt.Errorf("wildcard constraint %q is not supported", constraint)
|
||||
}
|
||||
return normalizedConstraint, nil
|
||||
}
|
||||
|
||||
func normalizeAndValidateDNSDomainConstraint(constraint string) (string, error) {
|
||||
normalizedConstraint := strings.ToLower(strings.TrimSpace(constraint))
|
||||
if normalizedConstraint == "" {
|
||||
|
|
|
@ -8,6 +8,46 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_normalizeAndValidateCommonName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
constraint string
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "fail/empty-constraint",
|
||||
constraint: "",
|
||||
want: "",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "fail/wildcard",
|
||||
constraint: "*",
|
||||
want: "",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "ok",
|
||||
constraint: "step",
|
||||
want: "step",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := normalizeAndValidateCommonName(tt.constraint)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("normalizeAndValidateCommonName() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("normalizeAndValidateCommonName() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_normalizeAndValidateDNSDomainConstraint(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -196,6 +236,24 @@ func TestNew(t *testing.T) {
|
|||
wantErr bool
|
||||
}
|
||||
var tests = map[string]func(t *testing.T) test{
|
||||
"fail/with-permitted-common-name": func(t *testing.T) test {
|
||||
return test{
|
||||
options: []NamePolicyOption{
|
||||
WithPermittedCommonNames("*"),
|
||||
},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
}
|
||||
},
|
||||
"fail/with-excluded-common-name": func(t *testing.T) test {
|
||||
return test{
|
||||
options: []NamePolicyOption{
|
||||
WithExcludedCommonNames(""),
|
||||
},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
}
|
||||
},
|
||||
"fail/with-permitted-dns-domains": func(t *testing.T) test {
|
||||
return test{
|
||||
options: []NamePolicyOption{
|
||||
|
|
|
@ -639,5 +639,9 @@ func matchPrincipalConstraint(principal, constraint string) (bool, error) {
|
|||
|
||||
// matchCommonNameConstraint performs a string literal equality check against constraint.
|
||||
func matchCommonNameConstraint(commonName, constraint string) (bool, error) {
|
||||
// wildcard constraint is (currently) not supported for common names
|
||||
if constraint == "*" {
|
||||
return false, nil
|
||||
}
|
||||
return strings.EqualFold(commonName, constraint), nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue