@@ -17,58 +17,33 @@ const (
17
17
nodeUserPrefix = nodeUser + ":"
18
18
)
19
19
20
- // authorizeCSR authorizes the CertificateSigningRequest req for a node's server certificate.
21
- // csr should be the parsed CSR from req.Spec.Request. Names contained in the CSR are checked against addresses in the
22
- // corresponding node's machine status.
23
- func authorizeCSR (machineList * capiclient.MachineList , req * certificatesv1beta1.CertificateSigningRequest , csr * x509.CertificateRequest ) bool {
24
- if machineList == nil || len (machineList .Items ) < 1 || req == nil || csr == nil {
25
- return false
20
+ func validateCSRContents (req * certificatesv1beta1.CertificateSigningRequest , csr * x509.CertificateRequest ) (string , bool ) {
21
+ if ! strings .HasPrefix (req .Spec .Username , nodeUserPrefix ) {
22
+ return "" ,false
26
23
}
27
24
28
- csrSubject := csr .Subject
29
- csrIPSan := csr .IPAddresses
30
- csrDNSSan := csr .DNSNames
31
-
32
- // Check username: system:node:ip-10-0-152-205.ec2.internal
33
- userName := req .Spec .Username
34
- if ! strings .HasPrefix (userName , nodeUserPrefix ) {
35
- return false
36
- }
37
-
38
- nodeAsking := strings .TrimPrefix (userName , nodeUserPrefix )
25
+ nodeAsking := strings .TrimPrefix (req .Spec .Username , nodeUserPrefix )
39
26
if len (nodeAsking ) < 1 {
40
- return false
41
- }
42
-
43
- // Check that we have a registered node with the request name
44
- var targetMachine * capiclient.MachineStatus
45
- for _ , machine := range machineList .Items {
46
- if machine .Status .NodeRef != nil && machine .Status .NodeRef .Name == nodeAsking {
47
- targetMachine = machine .Status .DeepCopy ()
48
- break
49
- }
50
- }
51
- if targetMachine == nil {
52
- return false
27
+ return "" ,false
53
28
}
54
29
55
30
// Check groups, we need at least:
56
31
// - system:nodes
57
32
// - system:authenticated
58
33
if len (req .Spec .Groups ) < 2 {
59
- return false
34
+ return "" , false
60
35
}
61
36
groupSet := sets .NewString (req .Spec .Groups ... )
62
37
if ! groupSet .HasAll (nodeGroup , "system:authenticated" ) {
63
- return false
38
+ return "" , false
64
39
}
65
40
66
41
// Check usages, we need only:
67
42
// - digital signature
68
43
// - key encipherment
69
44
// - server auth
70
45
if len (req .Spec .Usages ) != 3 {
71
- return false
46
+ return "" , false
72
47
}
73
48
74
49
usages := make ([]string , 0 )
@@ -78,7 +53,7 @@ func authorizeCSR(machineList *capiclient.MachineList, req *certificatesv1beta1.
78
53
79
54
// No extra usages!
80
55
if len (usages ) != 3 {
81
- return false
56
+ return "" , false
82
57
}
83
58
84
59
usageSet := sets .NewString (usages ... )
@@ -87,29 +62,56 @@ func authorizeCSR(machineList *capiclient.MachineList, req *certificatesv1beta1.
87
62
string (certificatesv1beta1 .UsageKeyEncipherment ),
88
63
string (certificatesv1beta1 .UsageServerAuth ),
89
64
) {
90
- return false
65
+ return "" , false
91
66
}
92
67
93
68
// Check subject: O = system:nodes, CN = system:node:ip-10-0-152-205.ec2.internal
94
- if csrSubject . CommonName != userName {
95
- return false
69
+ if csr . Subject . CommonName != req . Spec . Username {
70
+ return "" , false
96
71
}
97
72
98
73
var hasOrg bool
99
- for i := range csrSubject .Organization {
100
- if csrSubject .Organization [i ] == nodeGroup {
74
+ for i := range csr . Subject .Organization {
75
+ if csr . Subject .Organization [i ] == nodeGroup {
101
76
hasOrg = true
102
77
break
103
78
}
104
79
}
105
80
if ! hasOrg {
81
+ return "" ,false
82
+ }
83
+
84
+ return nodeAsking , true
85
+ }
86
+
87
+ // authorizeCSR authorizes the CertificateSigningRequest req for a node's server certificate.
88
+ // csr should be the parsed CSR from req.Spec.Request. Names contained in the CSR are checked against addresses in the
89
+ // corresponding node's machine status.
90
+ func authorizeCSR (machineList * capiclient.MachineList , req * certificatesv1beta1.CertificateSigningRequest , csr * x509.CertificateRequest ) bool {
91
+ if machineList == nil || len (machineList .Items ) < 1 || req == nil || csr == nil {
92
+ return false
93
+ }
94
+
95
+ nodeAsking , ok := validateCSRContents (req , csr )
96
+ if ! ok {
97
+ return false
98
+ }
99
+ // Check that we have a registered node with the request name
100
+ var targetMachine * capiclient.MachineStatus
101
+ for _ , machine := range machineList .Items {
102
+ if machine .Status .NodeRef != nil && machine .Status .NodeRef .Name == nodeAsking {
103
+ targetMachine = machine .Status .DeepCopy ()
104
+ break
105
+ }
106
+ }
107
+ if targetMachine == nil {
106
108
return false
107
109
}
108
110
109
111
// SAN checks for both DNS and IPs, e.g.,
110
112
// DNS:ip-10-0-152-205, DNS:ip-10-0-152-205.ec2.internal, IP Address:10.0.152.205, IP Address:10.0.152.205
111
113
// All names in the request must correspond to addresses assigned to a single machine.
112
- for _ , san := range csrDNSSan {
114
+ for _ , san := range csr . DNSNames {
113
115
if len (san ) < 1 {
114
116
continue
115
117
}
@@ -129,7 +131,7 @@ func authorizeCSR(machineList *capiclient.MachineList, req *certificatesv1beta1.
129
131
}
130
132
}
131
133
132
- for _ , san := range csrIPSan {
134
+ for _ , san := range csr . IPAddresses {
133
135
if len (san ) < 1 {
134
136
continue
135
137
}
0 commit comments