1
16
17 package authority
18
19 import (
20 "crypto/x509"
21 "fmt"
22 "sort"
23 "time"
24
25 capi "k8s.io/api/certificates/v1"
26 )
27
28
29
30
31 type SigningPolicy interface {
32
33
34 apply(template *x509.Certificate, signerNotAfter time.Time) error
35 }
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 type PermissiveSigningPolicy struct {
52
53 TTL time.Duration
54
55
56 Usages []capi.KeyUsage
57
58
59 Backdate time.Duration
60
61
62 Short time.Duration
63
64
65 Now func() time.Time
66 }
67
68 func (p PermissiveSigningPolicy) apply(tmpl *x509.Certificate, signerNotAfter time.Time) error {
69 var now time.Time
70 if p.Now != nil {
71 now = p.Now()
72 } else {
73 now = time.Now()
74 }
75
76 ttl := p.TTL
77
78 usage, extUsages, err := keyUsagesFromStrings(p.Usages)
79 if err != nil {
80 return err
81 }
82 tmpl.KeyUsage = usage
83 tmpl.ExtKeyUsage = extUsages
84
85 tmpl.ExtraExtensions = nil
86 tmpl.Extensions = nil
87 tmpl.BasicConstraintsValid = true
88 tmpl.IsCA = false
89
90 tmpl.NotBefore = now.Add(-p.Backdate)
91
92 if ttl < p.Short {
93
94 tmpl.NotAfter = now.Add(ttl)
95 } else {
96 tmpl.NotAfter = now.Add(ttl - p.Backdate)
97 }
98
99 if !tmpl.NotAfter.Before(signerNotAfter) {
100 tmpl.NotAfter = signerNotAfter
101 }
102
103 if !tmpl.NotBefore.Before(signerNotAfter) {
104 return fmt.Errorf("the signer has expired: NotAfter=%v", signerNotAfter)
105 }
106
107 if !now.Before(signerNotAfter) {
108 return fmt.Errorf("refusing to sign a certificate that expired in the past: NotAfter=%v", signerNotAfter)
109 }
110
111 return nil
112 }
113
114 var keyUsageDict = map[capi.KeyUsage]x509.KeyUsage{
115 capi.UsageSigning: x509.KeyUsageDigitalSignature,
116 capi.UsageDigitalSignature: x509.KeyUsageDigitalSignature,
117 capi.UsageContentCommitment: x509.KeyUsageContentCommitment,
118 capi.UsageKeyEncipherment: x509.KeyUsageKeyEncipherment,
119 capi.UsageKeyAgreement: x509.KeyUsageKeyAgreement,
120 capi.UsageDataEncipherment: x509.KeyUsageDataEncipherment,
121 capi.UsageCertSign: x509.KeyUsageCertSign,
122 capi.UsageCRLSign: x509.KeyUsageCRLSign,
123 capi.UsageEncipherOnly: x509.KeyUsageEncipherOnly,
124 capi.UsageDecipherOnly: x509.KeyUsageDecipherOnly,
125 }
126
127 var extKeyUsageDict = map[capi.KeyUsage]x509.ExtKeyUsage{
128 capi.UsageAny: x509.ExtKeyUsageAny,
129 capi.UsageServerAuth: x509.ExtKeyUsageServerAuth,
130 capi.UsageClientAuth: x509.ExtKeyUsageClientAuth,
131 capi.UsageCodeSigning: x509.ExtKeyUsageCodeSigning,
132 capi.UsageEmailProtection: x509.ExtKeyUsageEmailProtection,
133 capi.UsageSMIME: x509.ExtKeyUsageEmailProtection,
134 capi.UsageIPsecEndSystem: x509.ExtKeyUsageIPSECEndSystem,
135 capi.UsageIPsecTunnel: x509.ExtKeyUsageIPSECTunnel,
136 capi.UsageIPsecUser: x509.ExtKeyUsageIPSECUser,
137 capi.UsageTimestamping: x509.ExtKeyUsageTimeStamping,
138 capi.UsageOCSPSigning: x509.ExtKeyUsageOCSPSigning,
139 capi.UsageMicrosoftSGC: x509.ExtKeyUsageMicrosoftServerGatedCrypto,
140 capi.UsageNetscapeSGC: x509.ExtKeyUsageNetscapeServerGatedCrypto,
141 }
142
143
144
145
146 func keyUsagesFromStrings(usages []capi.KeyUsage) (x509.KeyUsage, []x509.ExtKeyUsage, error) {
147 var keyUsage x509.KeyUsage
148 var unrecognized []capi.KeyUsage
149 extKeyUsages := make(map[x509.ExtKeyUsage]struct{})
150 for _, usage := range usages {
151 if val, ok := keyUsageDict[usage]; ok {
152 keyUsage |= val
153 } else if val, ok := extKeyUsageDict[usage]; ok {
154 extKeyUsages[val] = struct{}{}
155 } else {
156 unrecognized = append(unrecognized, usage)
157 }
158 }
159
160 var sorted sortedExtKeyUsage
161 for eku := range extKeyUsages {
162 sorted = append(sorted, eku)
163 }
164 sort.Sort(sorted)
165
166 if len(unrecognized) > 0 {
167 return 0, nil, fmt.Errorf("unrecognized usage values: %q", unrecognized)
168 }
169
170 return keyUsage, sorted, nil
171 }
172
173 type sortedExtKeyUsage []x509.ExtKeyUsage
174
175 func (s sortedExtKeyUsage) Len() int {
176 return len(s)
177 }
178
179 func (s sortedExtKeyUsage) Swap(i, j int) {
180 s[i], s[j] = s[j], s[i]
181 }
182
183 func (s sortedExtKeyUsage) Less(i, j int) bool {
184 return s[i] < s[j]
185 }
186
View as plain text