aboutsummaryrefslogtreecommitdiffhomepage
path: root/modules/caddytls/certselection.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/caddytls/certselection.go')
-rw-r--r--modules/caddytls/certselection.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/modules/caddytls/certselection.go b/modules/caddytls/certselection.go
index 1bef890aa..84ca2e118 100644
--- a/modules/caddytls/certselection.go
+++ b/modules/caddytls/certselection.go
@@ -22,6 +22,8 @@ import (
"math/big"
"github.com/caddyserver/certmagic"
+
+ "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
)
// CustomCertSelectionPolicy represents a policy for selecting the certificate
@@ -122,6 +124,79 @@ nextChoice:
return certmagic.DefaultCertificateSelector(hello, viable)
}
+// UnmarshalCaddyfile sets up the CustomCertSelectionPolicy from Caddyfile tokens. Syntax:
+//
+// cert_selection {
+// all_tags <values...>
+// any_tag <values...>
+// public_key_algorithm <dsa|ecdsa|rsa>
+// serial_number <big_integers...>
+// subject_organization <values...>
+// }
+func (p *CustomCertSelectionPolicy) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
+ _, wrapper := d.Next(), d.Val() // consume wrapper name
+
+ // No same-line options are supported
+ if d.CountRemainingArgs() > 0 {
+ return d.ArgErr()
+ }
+
+ var hasPublicKeyAlgorithm bool
+ for nesting := d.Nesting(); d.NextBlock(nesting); {
+ optionName := d.Val()
+ switch optionName {
+ case "all_tags":
+ if d.CountRemainingArgs() == 0 {
+ return d.ArgErr()
+ }
+ p.AllTags = append(p.AllTags, d.RemainingArgs()...)
+ case "any_tag":
+ if d.CountRemainingArgs() == 0 {
+ return d.ArgErr()
+ }
+ p.AnyTag = append(p.AnyTag, d.RemainingArgs()...)
+ case "public_key_algorithm":
+ if hasPublicKeyAlgorithm {
+ return d.Errf("duplicate %s option '%s'", wrapper, optionName)
+ }
+ if d.CountRemainingArgs() != 1 {
+ return d.ArgErr()
+ }
+ d.NextArg()
+ if err := p.PublicKeyAlgorithm.UnmarshalJSON([]byte(d.Val())); err != nil {
+ return d.Errf("parsing %s option '%s': %v", wrapper, optionName, err)
+ }
+ hasPublicKeyAlgorithm = true
+ case "serial_number":
+ if d.CountRemainingArgs() == 0 {
+ return d.ArgErr()
+ }
+ for d.NextArg() {
+ val, bi := d.Val(), bigInt{}
+ _, ok := bi.SetString(val, 10)
+ if !ok {
+ return d.Errf("parsing %s option '%s': invalid big.int value %s", wrapper, optionName, val)
+ }
+ p.SerialNumber = append(p.SerialNumber, bi)
+ }
+ case "subject_organization":
+ if d.CountRemainingArgs() == 0 {
+ return d.ArgErr()
+ }
+ p.SubjectOrganization = append(p.SubjectOrganization, d.RemainingArgs()...)
+ default:
+ return d.ArgErr()
+ }
+
+ // No nested blocks are supported
+ if d.NextBlock(nesting + 1) {
+ return d.Errf("malformed %s option '%s': blocks are not supported", wrapper, optionName)
+ }
+ }
+
+ return nil
+}
+
// bigInt is a big.Int type that interops with JSON encodings as a string.
type bigInt struct{ big.Int }
@@ -144,3 +219,6 @@ func (bi *bigInt) UnmarshalJSON(p []byte) error {
}
return nil
}
+
+// Interface guard
+var _ caddyfile.Unmarshaler = (*CustomCertSelectionPolicy)(nil)