Merge pull request #111061 from pacoxu/key-encipherment-optional

modify the signing/approving controller to tolerate either set of usages for kubelet client and serving certificates
This commit is contained in:
Kubernetes Prow Robot
2022-08-02 18:55:51 -07:00
committed by GitHub
7 changed files with 191 additions and 39 deletions

View File

@@ -152,7 +152,7 @@ func isNodeClientCert(csr *capi.CertificateSigningRequest, x509cr *x509.Certific
if csr.Spec.SignerName != capi.KubeAPIServerClientKubeletSignerName {
return false
}
return capihelper.IsKubeletClientCSR(x509cr, usagesToSet(csr.Spec.Usages))
return capihelper.IsKubeletClientCSR(x509cr, usagesToSet(csr.Spec.Usages), true)
}
func isSelfNodeClientCert(csr *capi.CertificateSigningRequest, x509cr *x509.CertificateRequest) bool {

View File

@@ -211,6 +211,28 @@ func testRecognizer(t *testing.T, cases []func(b *csrBuilder), recognizeFunc fun
t.Errorf("expected recognized to be %v", shouldRecognize)
}
})
// reset the builder to run testcase without usage key encipherment
d := csrBuilder{
signerName: capi.KubeAPIServerClientKubeletSignerName,
cn: "system:node:foo",
orgs: []string{"system:nodes"},
requestor: "system:node:foo",
usages: []capi.KeyUsage{
capi.UsageDigitalSignature,
capi.UsageClientAuth,
},
}
c(&d)
t.Run(fmt.Sprintf("csr:%#v", d), func(t *testing.T) {
csr := makeFancyTestCsr(d)
x509cr, err := k8s_certificates_v1.ParseCSR(csr.Spec.Request)
if err != nil {
t.Errorf("unexpected err: %v", err)
}
if recognizeFunc(csr, x509cr) != shouldRecognize {
t.Errorf("expected recognized to be %v", shouldRecognize)
}
})
}
}

View File

@@ -248,14 +248,14 @@ func isKubeletServing(req *x509.CertificateRequest, usages []capi.KeyUsage, sign
if signerName != capi.KubeletServingSignerName {
return false, nil
}
return true, capihelper.ValidateKubeletServingCSR(req, usagesToSet(usages))
return true, capihelper.ValidateKubeletServingCSR(req, usagesToSet(usages), true)
}
func isKubeletClient(req *x509.CertificateRequest, usages []capi.KeyUsage, signerName string) (bool, error) {
if signerName != capi.KubeAPIServerClientKubeletSignerName {
return false, nil
}
return true, capihelper.ValidateKubeletClientCSR(req, usagesToSet(usages))
return true, capihelper.ValidateKubeletClientCSR(req, usagesToSet(usages), true)
}
func isKubeAPIServerClient(req *x509.CertificateRequest, usages []capi.KeyUsage, signerName string) (bool, error) {

View File

@@ -143,6 +143,24 @@ func TestHandle(t *testing.T) {
}
},
},
{
name: "should sign without key encipherment if signerName is kubernetes.io/kube-apiserver-client",
signerName: "kubernetes.io/kube-apiserver-client",
commonName: "hello-world",
org: []string{"some-org"},
usages: []capi.KeyUsage{capi.UsageClientAuth, capi.UsageDigitalSignature},
approved: true,
verify: func(t *testing.T, as []testclient.Action) {
if len(as) != 1 {
t.Errorf("expected one Update action but got %d", len(as))
return
}
csr := as[0].(testclient.UpdateAction).GetObject().(*capi.CertificateSigningRequest)
if len(csr.Status.Certificate) == 0 {
t.Errorf("expected certificate to be issued but it was not")
}
},
},
{
name: "should refuse to sign if signerName is kubernetes.io/kube-apiserver-client and contains an unexpected usage",
signerName: "kubernetes.io/kube-apiserver-client",
@@ -182,6 +200,24 @@ func TestHandle(t *testing.T) {
}
},
},
{
name: "should sign without usage key encipherment if signerName is kubernetes.io/kube-apiserver-client-kubelet",
signerName: "kubernetes.io/kube-apiserver-client-kubelet",
commonName: "system:node:hello-world",
org: []string{"system:nodes"},
usages: []capi.KeyUsage{capi.UsageClientAuth, capi.UsageDigitalSignature},
approved: true,
verify: func(t *testing.T, as []testclient.Action) {
if len(as) != 1 {
t.Errorf("expected one Update action but got %d", len(as))
return
}
csr := as[0].(testclient.UpdateAction).GetObject().(*capi.CertificateSigningRequest)
if len(csr.Status.Certificate) == 0 {
t.Errorf("expected certificate to be issued but it was not")
}
},
},
{
name: "should sign if signerName is kubernetes.io/legacy-unknown",
signerName: "kubernetes.io/legacy-unknown",
@@ -216,6 +252,25 @@ func TestHandle(t *testing.T) {
}
},
},
{
name: "should sign without usage key encipherment if signerName is kubernetes.io/kubelet-serving",
signerName: "kubernetes.io/kubelet-serving",
commonName: "system:node:testnode",
org: []string{"system:nodes"},
usages: []capi.KeyUsage{capi.UsageServerAuth, capi.UsageDigitalSignature},
dnsNames: []string{"example.com"},
approved: true,
verify: func(t *testing.T, as []testclient.Action) {
if len(as) != 1 {
t.Errorf("expected one Update action but got %d", len(as))
return
}
csr := as[0].(testclient.UpdateAction).GetObject().(*capi.CertificateSigningRequest)
if len(csr.Status.Certificate) == 0 {
t.Errorf("expected certificate to be issued but it was not")
}
},
},
{
name: "should do nothing if failed",
signerName: "kubernetes.io/kubelet-serving",