/
helpers.go
101 lines (89 loc) · 2.44 KB
/
helpers.go
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package certsigner
import (
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"reflect"
"strings"
capi "k8s.io/api/certificates/v1beta1"
)
func getCertApprovalCondition(status *capi.CertificateSigningRequestStatus) (approved bool, denied bool) {
for _, c := range status.Conditions {
if c.Type == capi.CertificateApproved {
approved = true
}
if c.Type == capi.CertificateDenied {
denied = true
}
}
return
}
func isApproved(csr *capi.CertificateSigningRequest) bool {
approved, denied := getCertApprovalCondition(&csr.Status)
return approved && !denied
}
// parseCSR extracts the CSR from the API object and decodes it.
func parseCSR(obj *capi.CertificateSigningRequest) (*x509.CertificateRequest, error) {
// extract PEM from request object
pemBytes := obj.Spec.Request
block, _ := pem.Decode(pemBytes)
if block == nil || block.Type != "CERTIFICATE REQUEST" {
return nil, errors.New("PEM block type must be CERTIFICATE REQUEST")
}
csr, err := x509.ParseCertificateRequest(block.Bytes)
if err != nil {
return nil, err
}
return csr, nil
}
func hasExactUsages(csr *capi.CertificateSigningRequest, usages []capi.KeyUsage) bool {
if len(usages) != len(csr.Spec.Usages) {
return false
}
usageMap := map[capi.KeyUsage]struct{}{}
for _, u := range usages {
usageMap[u] = struct{}{}
}
for _, u := range csr.Spec.Usages {
if _, ok := usageMap[u]; !ok {
return false
}
}
return true
}
var nodeUsages = []capi.KeyUsage{
capi.UsageKeyEncipherment,
capi.UsageDigitalSignature,
capi.UsageServerAuth,
capi.UsageClientAuth,
}
var clientUsages = []capi.KeyUsage{
capi.UsageKeyEncipherment,
capi.UsageDigitalSignature,
capi.UsageClientAuth,
}
func isCockroachServingCert(csr *capi.CertificateSigningRequest, x509cr *x509.CertificateRequest) bool {
log.Info(fmt.Sprintf("Introspecting cert: %+v", x509cr.Subject))
if !reflect.DeepEqual([]string{"Cockroach"}, x509cr.Subject.Organization) {
log.Info(fmt.Sprintf("Org does not match: %s", x509cr.Subject.Organization))
return false
}
if strings.HasPrefix(x509cr.Subject.CommonName, "node") {
if !hasExactUsages(csr, nodeUsages) {
log.Info(fmt.Sprintf("Usage does not match: %s", csr.Spec.Usages))
return false
} else {
return true
}
}
if strings.HasPrefix(x509cr.Subject.CommonName, "root") {
if !hasExactUsages(csr, clientUsages) {
log.Info(fmt.Sprintf("Usage does not match: %s", csr.Spec.Usages))
return false
} else {
return true
}
}
return false
}