certificates/policy/x509/options.go
2022-01-04 15:41:40 +01:00

513 lines
13 KiB
Go
Executable file

package x509policy
import (
"fmt"
"net"
"strings"
"github.com/pkg/errors"
)
type NamePolicyOption func(e *NamePolicyEngine) error
// TODO: wrap (more) errors; and prove a set of known (exported) errors
func WithEnableSubjectCommonNameVerification() NamePolicyOption {
return func(e *NamePolicyEngine) error {
e.verifySubjectCommonName = true
return nil
}
}
func WithPermittedDNSDomains(domains []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, domain := range domains {
if err := validateDNSDomainConstraint(domain); err != nil {
return errors.Errorf("cannot parse permitted domain constraint %q", domain)
}
}
e.permittedDNSDomains = domains
return nil
}
}
func AddPermittedDNSDomains(domains []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, domain := range domains {
if err := validateDNSDomainConstraint(domain); err != nil {
return errors.Errorf("cannot parse permitted domain constraint %q", domain)
}
}
e.permittedDNSDomains = append(e.permittedDNSDomains, domains...)
return nil
}
}
func WithExcludedDNSDomains(domains []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, domain := range domains {
if err := validateDNSDomainConstraint(domain); err != nil {
return errors.Errorf("cannot parse excluded domain constraint %q", domain)
}
}
e.excludedDNSDomains = domains
return nil
}
}
func AddExcludedDNSDomains(domains []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, domain := range domains {
if err := validateDNSDomainConstraint(domain); err != nil {
return errors.Errorf("cannot parse excluded domain constraint %q", domain)
}
}
e.excludedDNSDomains = append(e.excludedDNSDomains, domains...)
return nil
}
}
func WithPermittedDNSDomain(domain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateDNSDomainConstraint(domain); err != nil {
return errors.Errorf("cannot parse permitted domain constraint %q", domain)
}
e.permittedDNSDomains = []string{domain}
return nil
}
}
func AddPermittedDNSDomain(domain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateDNSDomainConstraint(domain); err != nil {
return errors.Errorf("cannot parse permitted domain constraint %q", domain)
}
e.permittedDNSDomains = append(e.permittedDNSDomains, domain)
return nil
}
}
func WithExcludedDNSDomain(domain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateDNSDomainConstraint(domain); err != nil {
return errors.Errorf("cannot parse excluded domain constraint %q", domain)
}
e.excludedDNSDomains = []string{domain}
return nil
}
}
func AddExcludedDNSDomain(domain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateDNSDomainConstraint(domain); err != nil {
return errors.Errorf("cannot parse excluded domain constraint %q", domain)
}
e.excludedDNSDomains = append(e.excludedDNSDomains, domain)
return nil
}
}
func WithPermittedIPRanges(ipRanges []*net.IPNet) NamePolicyOption {
return func(e *NamePolicyEngine) error {
e.permittedIPRanges = ipRanges
return nil
}
}
func AddPermittedIPRanges(ipRanges []*net.IPNet) NamePolicyOption {
return func(e *NamePolicyEngine) error {
e.permittedIPRanges = append(e.permittedIPRanges, ipRanges...)
return nil
}
}
func WithPermittedCIDRs(cidrs []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
networks := []*net.IPNet{}
for _, cidr := range cidrs {
_, nw, err := net.ParseCIDR(cidr)
if err != nil {
return errors.Errorf("cannot parse permitted CIDR constraint %q", cidr)
}
networks = append(networks, nw)
}
e.permittedIPRanges = networks
return nil
}
}
func AddPermittedCIDRs(cidrs []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
networks := []*net.IPNet{}
for _, cidr := range cidrs {
_, nw, err := net.ParseCIDR(cidr)
if err != nil {
return errors.Errorf("cannot parse permitted CIDR constraint %q", cidr)
}
networks = append(networks, nw)
}
e.permittedIPRanges = append(e.permittedIPRanges, networks...)
return nil
}
}
func WithExcludedCIDRs(cidrs []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
networks := []*net.IPNet{}
for _, cidr := range cidrs {
_, nw, err := net.ParseCIDR(cidr)
if err != nil {
return errors.Errorf("cannot parse excluded CIDR constraint %q", cidr)
}
networks = append(networks, nw)
}
e.excludedIPRanges = networks
return nil
}
}
func AddExcludedCIDRs(cidrs []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
networks := []*net.IPNet{}
for _, cidr := range cidrs {
_, nw, err := net.ParseCIDR(cidr)
if err != nil {
return errors.Errorf("cannot parse excluded CIDR constraint %q", cidr)
}
networks = append(networks, nw)
}
e.excludedIPRanges = append(e.excludedIPRanges, networks...)
return nil
}
}
func WithPermittedCIDR(cidr string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
_, nw, err := net.ParseCIDR(cidr)
if err != nil {
return errors.Errorf("cannot parse permitted CIDR constraint %q", cidr)
}
e.permittedIPRanges = []*net.IPNet{nw}
return nil
}
}
func AddPermittedCIDR(cidr string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
_, nw, err := net.ParseCIDR(cidr)
if err != nil {
return errors.Errorf("cannot parse permitted CIDR constraint %q", cidr)
}
e.permittedIPRanges = append(e.permittedIPRanges, nw)
return nil
}
}
func WithPermittedIP(ip net.IP) NamePolicyOption {
return func(e *NamePolicyEngine) error {
var mask net.IPMask
if !isIPv4(ip) {
mask = net.CIDRMask(128, 128)
} else {
mask = net.CIDRMask(32, 32)
}
nw := &net.IPNet{
IP: ip,
Mask: mask,
}
e.permittedIPRanges = []*net.IPNet{nw}
return nil
}
}
func AddPermittedIP(ip net.IP) NamePolicyOption {
return func(e *NamePolicyEngine) error {
var mask net.IPMask
if !isIPv4(ip) {
mask = net.CIDRMask(128, 128)
} else {
mask = net.CIDRMask(32, 32)
}
nw := &net.IPNet{
IP: ip,
Mask: mask,
}
e.permittedIPRanges = append(e.permittedIPRanges, nw)
return nil
}
}
func WithExcludedIPRanges(ipRanges []*net.IPNet) NamePolicyOption {
return func(e *NamePolicyEngine) error {
e.excludedIPRanges = ipRanges
return nil
}
}
func AddExcludedIPRanges(ipRanges []*net.IPNet) NamePolicyOption {
return func(e *NamePolicyEngine) error {
e.excludedIPRanges = append(e.excludedIPRanges, ipRanges...)
return nil
}
}
func WithExcludedCIDR(cidr string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
_, nw, err := net.ParseCIDR(cidr)
if err != nil {
return errors.Errorf("cannot parse excluded CIDR constraint %q", cidr)
}
e.excludedIPRanges = []*net.IPNet{nw}
return nil
}
}
func AddExcludedCIDR(cidr string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
_, nw, err := net.ParseCIDR(cidr)
if err != nil {
return errors.Errorf("cannot parse excluded CIDR constraint %q", cidr)
}
e.excludedIPRanges = append(e.excludedIPRanges, nw)
return nil
}
}
func WithExcludedIP(ip net.IP) NamePolicyOption {
return func(e *NamePolicyEngine) error {
var mask net.IPMask
if !isIPv4(ip) {
mask = net.CIDRMask(128, 128)
} else {
mask = net.CIDRMask(32, 32)
}
nw := &net.IPNet{
IP: ip,
Mask: mask,
}
e.excludedIPRanges = []*net.IPNet{nw}
return nil
}
}
func AddExcludedIP(ip net.IP) NamePolicyOption {
return func(e *NamePolicyEngine) error {
var mask net.IPMask
if !isIPv4(ip) {
mask = net.CIDRMask(128, 128)
} else {
mask = net.CIDRMask(32, 32)
}
nw := &net.IPNet{
IP: ip,
Mask: mask,
}
e.excludedIPRanges = append(e.excludedIPRanges, nw)
return nil
}
}
func WithPermittedEmailAddresses(emailAddresses []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, email := range emailAddresses {
if err := validateEmailConstraint(email); err != nil {
return err
}
}
e.permittedEmailAddresses = emailAddresses
return nil
}
}
func AddPermittedEmailAddresses(emailAddresses []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, email := range emailAddresses {
if err := validateEmailConstraint(email); err != nil {
return err
}
}
e.permittedEmailAddresses = append(e.permittedEmailAddresses, emailAddresses...)
return nil
}
}
func WithExcludedEmailAddresses(emailAddresses []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, email := range emailAddresses {
if err := validateEmailConstraint(email); err != nil {
return err
}
}
e.excludedEmailAddresses = emailAddresses
return nil
}
}
func AddExcludedEmailAddresses(emailAddresses []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, email := range emailAddresses {
if err := validateEmailConstraint(email); err != nil {
return err
}
}
e.excludedEmailAddresses = append(e.excludedEmailAddresses, emailAddresses...)
return nil
}
}
func WithPermittedEmailAddress(emailAddress string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateEmailConstraint(emailAddress); err != nil {
return err
}
e.permittedEmailAddresses = []string{emailAddress}
return nil
}
}
func AddPermittedEmailAddress(emailAddress string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateEmailConstraint(emailAddress); err != nil {
return err
}
e.permittedEmailAddresses = append(e.permittedEmailAddresses, emailAddress)
return nil
}
}
func WithExcludedEmailAddress(emailAddress string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateEmailConstraint(emailAddress); err != nil {
return err
}
e.excludedEmailAddresses = []string{emailAddress}
return nil
}
}
func AddExcludedEmailAddress(emailAddress string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateEmailConstraint(emailAddress); err != nil {
return err
}
e.excludedEmailAddresses = append(e.excludedEmailAddresses, emailAddress)
return nil
}
}
func WithPermittedURIDomains(uriDomains []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, domain := range uriDomains {
if err := validateURIDomainConstraint(domain); err != nil {
return err
}
}
e.permittedURIDomains = uriDomains
return nil
}
}
func AddPermittedURIDomains(uriDomains []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, domain := range uriDomains {
if err := validateURIDomainConstraint(domain); err != nil {
return err
}
}
e.permittedURIDomains = append(e.permittedURIDomains, uriDomains...)
return nil
}
}
func WithPermittedURIDomain(uriDomain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateURIDomainConstraint(uriDomain); err != nil {
return err
}
e.permittedURIDomains = []string{uriDomain}
return nil
}
}
func AddPermittedURIDomain(uriDomain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateURIDomainConstraint(uriDomain); err != nil {
return err
}
e.permittedURIDomains = append(e.permittedURIDomains, uriDomain)
return nil
}
}
func WithExcludedURIDomains(uriDomains []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, domain := range uriDomains {
if err := validateURIDomainConstraint(domain); err != nil {
return err
}
}
e.excludedURIDomains = uriDomains
return nil
}
}
func AddExcludedURIDomains(uriDomains []string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
for _, domain := range uriDomains {
if err := validateURIDomainConstraint(domain); err != nil {
return err
}
}
e.excludedURIDomains = append(e.excludedURIDomains, uriDomains...)
return nil
}
}
func WithExcludedURIDomain(uriDomain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateURIDomainConstraint(uriDomain); err != nil {
return err
}
e.excludedURIDomains = []string{uriDomain}
return nil
}
}
func AddExcludedURIDomain(uriDomain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
if err := validateURIDomainConstraint(uriDomain); err != nil {
return err
}
e.excludedURIDomains = append(e.excludedURIDomains, uriDomain)
return nil
}
}
func validateDNSDomainConstraint(domain string) error {
if _, ok := domainToReverseLabels(domain); !ok {
return errors.Errorf("cannot parse permitted domain constraint %q", domain)
}
return nil
}
func validateEmailConstraint(constraint string) error {
if strings.Contains(constraint, "@") {
_, ok := parseRFC2821Mailbox(constraint)
if !ok {
return fmt.Errorf("cannot parse email constraint %q", constraint)
}
}
_, ok := domainToReverseLabels(constraint)
if !ok {
return fmt.Errorf("cannot parse email domain constraint %q", constraint)
}
return nil
}
func validateURIDomainConstraint(constraint string) error {
_, ok := domainToReverseLabels(constraint)
if !ok {
return fmt.Errorf("cannot parse URI domain constraint %q", constraint)
}
return nil
}