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) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
engine, err := New(tt.options...)
|
engine, err := New(tt.options...)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, engine)
|
||||||
gotErr := engine.IsX509CertificateAllowed(tt.cert)
|
gotErr := engine.IsX509CertificateAllowed(tt.cert)
|
||||||
wantErr := tt.wantErr != nil
|
wantErr := tt.wantErr != nil
|
||||||
|
|
||||||
|
|
|
@ -28,14 +28,30 @@ func WithAllowLiteralWildcardNames() NamePolicyOption {
|
||||||
|
|
||||||
func WithPermittedCommonNames(commonNames ...string) NamePolicyOption {
|
func WithPermittedCommonNames(commonNames ...string) NamePolicyOption {
|
||||||
return func(g *NamePolicyEngine) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithExcludedCommonNames(commonNames ...string) NamePolicyOption {
|
func WithExcludedCommonNames(commonNames ...string) NamePolicyOption {
|
||||||
return func(g *NamePolicyEngine) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,6 +258,17 @@ func isIPv4(ip net.IP) bool {
|
||||||
return ip.To4() != nil
|
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) {
|
func normalizeAndValidateDNSDomainConstraint(constraint string) (string, error) {
|
||||||
normalizedConstraint := strings.ToLower(strings.TrimSpace(constraint))
|
normalizedConstraint := strings.ToLower(strings.TrimSpace(constraint))
|
||||||
if normalizedConstraint == "" {
|
if normalizedConstraint == "" {
|
||||||
|
|
|
@ -8,6 +8,46 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"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) {
|
func Test_normalizeAndValidateDNSDomainConstraint(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -196,6 +236,24 @@ func TestNew(t *testing.T) {
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}
|
}
|
||||||
var tests = map[string]func(t *testing.T) test{
|
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 {
|
"fail/with-permitted-dns-domains": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
options: []NamePolicyOption{
|
options: []NamePolicyOption{
|
||||||
|
|
|
@ -639,5 +639,9 @@ func matchPrincipalConstraint(principal, constraint string) (bool, error) {
|
||||||
|
|
||||||
// matchCommonNameConstraint performs a string literal equality check against constraint.
|
// matchCommonNameConstraint performs a string literal equality check against constraint.
|
||||||
func matchCommonNameConstraint(commonName, constraint string) (bool, error) {
|
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
|
return strings.EqualFold(commonName, constraint), nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue