You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
smallstep-certificates/policy/x509/x509_test.go

300 lines
6.8 KiB
Go

package x509policy
import (
"crypto/x509"
"net"
"net/url"
"testing"
"github.com/smallstep/assert"
)
func TestGuard_IsAllowed(t *testing.T) {
type fields struct {
permittedDNSDomains []string
excludedDNSDomains []string
permittedIPRanges []*net.IPNet
excludedIPRanges []*net.IPNet
permittedEmailAddresses []string
excludedEmailAddresses []string
permittedURIDomains []string
excludedURIDomains []string
}
tests := []struct {
name string
fields fields
csr *x509.CertificateRequest
want bool
wantErr bool
}{
{
name: "fail/dns-permitted",
fields: fields{
permittedDNSDomains: []string{".local"},
},
csr: &x509.CertificateRequest{
DNSNames: []string{"www.example.com"},
},
want: false,
wantErr: true,
},
{
name: "fail/dns-excluded",
fields: fields{
excludedDNSDomains: []string{"example.com"},
},
csr: &x509.CertificateRequest{
DNSNames: []string{"www.example.com"},
},
want: false,
wantErr: true,
},
{
name: "fail/ipv4-permitted",
fields: fields{
permittedIPRanges: []*net.IPNet{
{
IP: net.ParseIP("127.0.0.1"),
Mask: net.IPv4Mask(255, 255, 255, 0),
},
},
},
csr: &x509.CertificateRequest{
IPAddresses: []net.IP{net.ParseIP("1.1.1.1")},
},
want: false,
wantErr: true,
},
{
name: "fail/ipv4-excluded",
fields: fields{
excludedIPRanges: []*net.IPNet{
{
IP: net.ParseIP("127.0.0.1"),
Mask: net.IPv4Mask(255, 255, 255, 0),
},
},
},
csr: &x509.CertificateRequest{
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
},
want: false,
wantErr: true,
},
{
name: "fail/ipv6-permitted",
fields: fields{
permittedIPRanges: []*net.IPNet{
{
IP: net.ParseIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334"),
Mask: net.CIDRMask(120, 128),
},
},
},
csr: &x509.CertificateRequest{
IPAddresses: []net.IP{net.ParseIP("3001:0db8:85a3:0000:0000:8a2e:0370:7334")},
},
want: false,
wantErr: true,
},
{
name: "fail/ipv6-excluded",
fields: fields{
excludedIPRanges: []*net.IPNet{
{
IP: net.ParseIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334"),
Mask: net.CIDRMask(120, 128),
},
},
},
csr: &x509.CertificateRequest{
IPAddresses: []net.IP{net.ParseIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334")},
},
want: false,
wantErr: true,
},
{
name: "fail/mail-permitted",
fields: fields{
permittedEmailAddresses: []string{"example.local"},
},
csr: &x509.CertificateRequest{
EmailAddresses: []string{"mail@example.com"},
},
want: false,
wantErr: true,
},
{
name: "fail/mail-excluded",
fields: fields{
excludedEmailAddresses: []string{"example.local"},
},
csr: &x509.CertificateRequest{
EmailAddresses: []string{"mail@example.local"},
},
want: false,
wantErr: true,
},
{
name: "fail/uri-permitted",
fields: fields{
permittedURIDomains: []string{".example.com"},
},
csr: &x509.CertificateRequest{
URIs: []*url.URL{
{
Scheme: "https",
Host: "www.example.local",
},
},
},
want: false,
wantErr: true,
},
{
name: "fail/uri-excluded",
fields: fields{
excludedURIDomains: []string{".example.local"},
},
csr: &x509.CertificateRequest{
URIs: []*url.URL{
{
Scheme: "https",
Host: "www.example.local",
},
},
},
want: false,
wantErr: true,
},
{
name: "ok/no-constraints",
fields: fields{},
csr: &x509.CertificateRequest{
DNSNames: []string{"www.example.com"},
},
want: true,
wantErr: false,
},
{
name: "ok/dns",
fields: fields{
permittedDNSDomains: []string{".local"},
},
csr: &x509.CertificateRequest{
DNSNames: []string{"example.local"},
},
want: true,
wantErr: false,
},
{
name: "ok/ipv4",
fields: fields{
permittedIPRanges: []*net.IPNet{
{
IP: net.ParseIP("127.0.0.1"),
Mask: net.IPv4Mask(255, 255, 255, 0),
},
},
},
csr: &x509.CertificateRequest{
IPAddresses: []net.IP{net.ParseIP("127.0.0.20")},
},
want: true,
wantErr: false,
},
{
name: "ok/ipv6",
fields: fields{
permittedIPRanges: []*net.IPNet{
{
IP: net.ParseIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334"),
Mask: net.CIDRMask(120, 128),
},
},
},
csr: &x509.CertificateRequest{
IPAddresses: []net.IP{net.ParseIP("2001:0db8:85a3:0000:0000:8a2e:0370:7339")},
},
want: true,
wantErr: false,
},
{
name: "ok/mail",
fields: fields{
permittedEmailAddresses: []string{"example.local"},
},
csr: &x509.CertificateRequest{
EmailAddresses: []string{"mail@example.local"},
},
want: true,
wantErr: false,
},
{
name: "ok/uri",
fields: fields{
permittedURIDomains: []string{".example.com"},
},
csr: &x509.CertificateRequest{
URIs: []*url.URL{
{
Scheme: "https",
Host: "www.example.com",
},
},
},
want: true,
wantErr: false,
},
{
name: "ok/combined-simple",
fields: fields{
permittedDNSDomains: []string{".local"},
permittedIPRanges: []*net.IPNet{{IP: net.ParseIP("127.0.0.1"), Mask: net.IPv4Mask(255, 255, 255, 0)}},
permittedEmailAddresses: []string{"example.local"},
permittedURIDomains: []string{".example.local"},
},
csr: &x509.CertificateRequest{
DNSNames: []string{"example.local"},
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
EmailAddresses: []string{"mail@example.local"},
URIs: []*url.URL{
{
Scheme: "https",
Host: "www.example.local",
},
},
},
want: true,
wantErr: false,
},
// TODO: more complex uses cases that combine multiple names
// TODO: check errors (reasons) are as expected
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := &NamePolicyEngine{
permittedDNSDomains: tt.fields.permittedDNSDomains,
excludedDNSDomains: tt.fields.excludedDNSDomains,
permittedIPRanges: tt.fields.permittedIPRanges,
excludedIPRanges: tt.fields.excludedIPRanges,
permittedEmailAddresses: tt.fields.permittedEmailAddresses,
excludedEmailAddresses: tt.fields.excludedEmailAddresses,
permittedURIDomains: tt.fields.permittedURIDomains,
excludedURIDomains: tt.fields.excludedURIDomains,
}
got, err := g.AreCSRNamesAllowed(tt.csr)
if (err != nil) != tt.wantErr {
t.Errorf("Guard.IsAllowed() error = %v, wantErr %v", err, tt.wantErr)
return
}
if err != nil {
assert.NotEquals(t, "", err.Error()) // TODO(hs): make this a complete equality check
}
if got != tt.want {
t.Errorf("Guard.IsAllowed() = %v, want %v", got, tt.want)
}
})
}
}