blob: b56185ac0741e88fc92ab1d640d4a4968a7e9077 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
package caddytls
import (
"crypto/tls"
"crypto/x509"
"fmt"
"math/big"
"github.com/caddyserver/caddy/v2"
"github.com/mholt/certmagic"
)
func init() {
caddy.RegisterModule(Policy{})
}
// Policy represents a policy for selecting the certificate used to
// complete a handshake when there may be multiple options. All fields
// specified must match the candidate certificate for it to be chosen.
// This was needed to solve https://github.com/caddyserver/caddy/issues/2588.
type Policy struct {
SerialNumber *big.Int `json:"serial_number,omitempty"`
SubjectOrganization string `json:"subject_organization,omitempty"`
PublicKeyAlgorithm PublicKeyAlgorithm `json:"public_key_algorithm,omitempty"`
Tag string `json:"tag,omitempty"`
}
// CaddyModule returns the Caddy module information.
func (Policy) CaddyModule() caddy.ModuleInfo {
return caddy.ModuleInfo{
Name: "tls.certificate_selection.custom",
New: func() caddy.Module { return new(Policy) },
}
}
// SelectCertificate implements certmagic.CertificateSelector.
func (p Policy) SelectCertificate(_ *tls.ClientHelloInfo, choices []certmagic.Certificate) (certmagic.Certificate, error) {
for _, cert := range choices {
if p.SerialNumber != nil && cert.SerialNumber.Cmp(p.SerialNumber) != 0 {
continue
}
if p.PublicKeyAlgorithm != PublicKeyAlgorithm(x509.UnknownPublicKeyAlgorithm) &&
PublicKeyAlgorithm(cert.PublicKeyAlgorithm) != p.PublicKeyAlgorithm {
continue
}
if p.SubjectOrganization != "" {
var matchOrg bool
for _, org := range cert.Subject.Organization {
if p.SubjectOrganization == org {
matchOrg = true
break
}
}
if !matchOrg {
continue
}
}
if p.Tag != "" && !cert.HasTag(p.Tag) {
continue
}
return cert, nil
}
return certmagic.Certificate{}, fmt.Errorf("no certificates matched custom selection policy")
}
// Interface guard
var _ certmagic.CertificateSelector = (*Policy)(nil)
|