...
1 package signer
2
3 import (
4 "crypto/x509"
5 "fmt"
6 "sort"
7 "time"
8
9 capi "k8s.io/api/certificates/v1beta1"
10 )
11
12
13
14
15 type SigningPolicy interface {
16
17
18 apply(template *x509.Certificate) error
19 }
20
21
22
23
24
25
26
27
28
29
30 type PermissiveSigningPolicy struct {
31
32
33 TTL time.Duration
34
35 Usages []capi.KeyUsage
36 }
37
38 func (p PermissiveSigningPolicy) apply(tmpl *x509.Certificate) error {
39 usage, extUsages, err := keyUsagesFromStrings(p.Usages)
40 if err != nil {
41 return err
42 }
43 tmpl.KeyUsage = usage
44 tmpl.ExtKeyUsage = extUsages
45 tmpl.NotAfter = tmpl.NotBefore.Add(p.TTL)
46
47 tmpl.ExtraExtensions = nil
48 tmpl.Extensions = nil
49 tmpl.BasicConstraintsValid = true
50 tmpl.IsCA = false
51
52 return nil
53 }
54
55 var keyUsageDict = map[capi.KeyUsage]x509.KeyUsage{
56 capi.UsageSigning: x509.KeyUsageDigitalSignature,
57 capi.UsageDigitalSignature: x509.KeyUsageDigitalSignature,
58 capi.UsageContentCommitment: x509.KeyUsageContentCommitment,
59 capi.UsageKeyEncipherment: x509.KeyUsageKeyEncipherment,
60 capi.UsageKeyAgreement: x509.KeyUsageKeyAgreement,
61 capi.UsageDataEncipherment: x509.KeyUsageDataEncipherment,
62 capi.UsageCertSign: x509.KeyUsageCertSign,
63 capi.UsageCRLSign: x509.KeyUsageCRLSign,
64 capi.UsageEncipherOnly: x509.KeyUsageEncipherOnly,
65 capi.UsageDecipherOnly: x509.KeyUsageDecipherOnly,
66 }
67
68 var extKeyUsageDict = map[capi.KeyUsage]x509.ExtKeyUsage{
69 capi.UsageAny: x509.ExtKeyUsageAny,
70 capi.UsageServerAuth: x509.ExtKeyUsageServerAuth,
71 capi.UsageClientAuth: x509.ExtKeyUsageClientAuth,
72 capi.UsageCodeSigning: x509.ExtKeyUsageCodeSigning,
73 capi.UsageEmailProtection: x509.ExtKeyUsageEmailProtection,
74 capi.UsageSMIME: x509.ExtKeyUsageEmailProtection,
75 capi.UsageIPsecEndSystem: x509.ExtKeyUsageIPSECEndSystem,
76 capi.UsageIPsecTunnel: x509.ExtKeyUsageIPSECTunnel,
77 capi.UsageIPsecUser: x509.ExtKeyUsageIPSECUser,
78 capi.UsageTimestamping: x509.ExtKeyUsageTimeStamping,
79 capi.UsageOCSPSigning: x509.ExtKeyUsageOCSPSigning,
80 capi.UsageMicrosoftSGC: x509.ExtKeyUsageMicrosoftServerGatedCrypto,
81 capi.UsageNetscapeSGC: x509.ExtKeyUsageNetscapeServerGatedCrypto,
82 }
83
84
85
86
87 func keyUsagesFromStrings(usages []capi.KeyUsage) (x509.KeyUsage, []x509.ExtKeyUsage, error) {
88 var keyUsage x509.KeyUsage
89 var unrecognized []capi.KeyUsage
90 extKeyUsages := make(map[x509.ExtKeyUsage]struct{})
91 for _, usage := range usages {
92 if val, ok := keyUsageDict[usage]; ok {
93 keyUsage |= val
94 } else if val, ok := extKeyUsageDict[usage]; ok {
95 extKeyUsages[val] = struct{}{}
96 } else {
97 unrecognized = append(unrecognized, usage)
98 }
99 }
100
101 var sorted sortedExtKeyUsage
102 for eku := range extKeyUsages {
103 sorted = append(sorted, eku)
104 }
105 sort.Sort(sorted)
106
107 if len(unrecognized) > 0 {
108 return 0, nil, fmt.Errorf("unrecognized usage values: %q", unrecognized)
109 }
110
111 return keyUsage, []x509.ExtKeyUsage(sorted), nil
112 }
113
114 type sortedExtKeyUsage []x509.ExtKeyUsage
115
116 func (s sortedExtKeyUsage) Len() int {
117 return len(s)
118 }
119
120 func (s sortedExtKeyUsage) Swap(i, j int) {
121 s[i], s[j] = s[j], s[i]
122 }
123
124 func (s sortedExtKeyUsage) Less(i, j int) bool {
125 return s[i] < s[j]
126 }
127
View as plain text