mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
csr: correctly handle backdating of short lived certs
This change updates the backdating logic to only be applied to the NotBefore date and not the NotAfter date when the certificate is short lived. Thus when such a certificate is issued, it will not be immediately expired. Long lived certificates continue to have the same lifetime as before. Consolidated all certificate lifetime logic into the PermissiveSigningPolicy.policy method. Signed-off-by: Monis Khan <mok@vmware.com>
This commit is contained in:
parent
2453f07e93
commit
7e891e5d6c
@ -298,7 +298,6 @@ func (s *csrSimulator) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
ca := &authority.CertificateAuthority{
|
ca := &authority.CertificateAuthority{
|
||||||
Certificate: s.serverCA,
|
Certificate: s.serverCA,
|
||||||
PrivateKey: s.serverPrivateKey,
|
PrivateKey: s.serverPrivateKey,
|
||||||
Backdate: s.backdate,
|
|
||||||
}
|
}
|
||||||
cr, err := capihelper.ParseCSR(csr.Spec.Request)
|
cr, err := capihelper.ParseCSR(csr.Spec.Request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -306,6 +305,7 @@ func (s *csrSimulator) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
der, err := ca.Sign(cr.Raw, authority.PermissiveSigningPolicy{
|
der, err := ca.Sign(cr.Raw, authority.PermissiveSigningPolicy{
|
||||||
TTL: time.Hour,
|
TTL: time.Hour,
|
||||||
|
Backdate: s.backdate,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -22,7 +22,6 @@ import (
|
|||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var serialNumberLimit = new(big.Int).Lsh(big.NewInt(1), 128)
|
var serialNumberLimit = new(big.Int).Lsh(big.NewInt(1), 128)
|
||||||
@ -37,23 +36,11 @@ type CertificateAuthority struct {
|
|||||||
|
|
||||||
Certificate *x509.Certificate
|
Certificate *x509.Certificate
|
||||||
PrivateKey crypto.Signer
|
PrivateKey crypto.Signer
|
||||||
Backdate time.Duration
|
|
||||||
Now func() time.Time
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign signs a certificate request, applying a SigningPolicy and returns a DER
|
// Sign signs a certificate request, applying a SigningPolicy and returns a DER
|
||||||
// encoded x509 certificate.
|
// encoded x509 certificate.
|
||||||
func (ca *CertificateAuthority) Sign(crDER []byte, policy SigningPolicy) ([]byte, error) {
|
func (ca *CertificateAuthority) Sign(crDER []byte, policy SigningPolicy) ([]byte, error) {
|
||||||
now := time.Now()
|
|
||||||
if ca.Now != nil {
|
|
||||||
now = ca.Now()
|
|
||||||
}
|
|
||||||
|
|
||||||
nbf := now.Add(-ca.Backdate)
|
|
||||||
if !nbf.Before(ca.Certificate.NotAfter) {
|
|
||||||
return nil, fmt.Errorf("the signer has expired: NotAfter=%v", ca.Certificate.NotAfter)
|
|
||||||
}
|
|
||||||
|
|
||||||
cr, err := x509.ParseCertificateRequest(crDER)
|
cr, err := x509.ParseCertificateRequest(crDER)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to parse certificate request: %v", err)
|
return nil, fmt.Errorf("unable to parse certificate request: %v", err)
|
||||||
@ -78,19 +65,11 @@ func (ca *CertificateAuthority) Sign(crDER []byte, policy SigningPolicy) ([]byte
|
|||||||
PublicKey: cr.PublicKey,
|
PublicKey: cr.PublicKey,
|
||||||
Extensions: cr.Extensions,
|
Extensions: cr.Extensions,
|
||||||
ExtraExtensions: cr.ExtraExtensions,
|
ExtraExtensions: cr.ExtraExtensions,
|
||||||
NotBefore: nbf,
|
|
||||||
}
|
}
|
||||||
if err := policy.apply(tmpl); err != nil {
|
if err := policy.apply(tmpl, ca.Certificate.NotAfter); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !tmpl.NotAfter.Before(ca.Certificate.NotAfter) {
|
|
||||||
tmpl.NotAfter = ca.Certificate.NotAfter
|
|
||||||
}
|
|
||||||
if !now.Before(ca.Certificate.NotAfter) {
|
|
||||||
return nil, fmt.Errorf("refusing to sign a certificate that expired in the past")
|
|
||||||
}
|
|
||||||
|
|
||||||
der, err := x509.CreateCertificate(rand.Reader, tmpl, ca.Certificate, cr.PublicKey, ca.PrivateKey)
|
der, err := x509.CreateCertificate(rand.Reader, tmpl, ca.Certificate, cr.PublicKey, ca.PrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to sign certificate: %v", err)
|
return nil, fmt.Errorf("failed to sign certificate: %v", err)
|
||||||
|
@ -40,6 +40,7 @@ func TestCertificateAuthority(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
nowFunc := func() time.Time { return now }
|
||||||
tmpl := &x509.Certificate{
|
tmpl := &x509.Certificate{
|
||||||
SerialNumber: big.NewInt(42),
|
SerialNumber: big.NewInt(42),
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
@ -68,15 +69,15 @@ func TestCertificateAuthority(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
cr x509.CertificateRequest
|
cr x509.CertificateRequest
|
||||||
backdate time.Duration
|
|
||||||
policy SigningPolicy
|
policy SigningPolicy
|
||||||
|
mutateCA func(ca *CertificateAuthority)
|
||||||
|
|
||||||
want x509.Certificate
|
want x509.Certificate
|
||||||
wantErr bool
|
wantErr string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "ca info",
|
name: "ca info",
|
||||||
policy: PermissiveSigningPolicy{TTL: time.Hour},
|
policy: PermissiveSigningPolicy{TTL: time.Hour, Now: nowFunc},
|
||||||
want: x509.Certificate{
|
want: x509.Certificate{
|
||||||
Issuer: caCert.Subject,
|
Issuer: caCert.Subject,
|
||||||
AuthorityKeyId: caCert.SubjectKeyId,
|
AuthorityKeyId: caCert.SubjectKeyId,
|
||||||
@ -87,7 +88,7 @@ func TestCertificateAuthority(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "key usage",
|
name: "key usage",
|
||||||
policy: PermissiveSigningPolicy{TTL: time.Hour, Usages: []capi.KeyUsage{"signing"}},
|
policy: PermissiveSigningPolicy{TTL: time.Hour, Usages: []capi.KeyUsage{"signing"}, Now: nowFunc},
|
||||||
want: x509.Certificate{
|
want: x509.Certificate{
|
||||||
NotBefore: now,
|
NotBefore: now,
|
||||||
NotAfter: now.Add(1 * time.Hour),
|
NotAfter: now.Add(1 * time.Hour),
|
||||||
@ -97,7 +98,7 @@ func TestCertificateAuthority(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ext key usage",
|
name: "ext key usage",
|
||||||
policy: PermissiveSigningPolicy{TTL: time.Hour, Usages: []capi.KeyUsage{"client auth"}},
|
policy: PermissiveSigningPolicy{TTL: time.Hour, Usages: []capi.KeyUsage{"client auth"}, Now: nowFunc},
|
||||||
want: x509.Certificate{
|
want: x509.Certificate{
|
||||||
NotBefore: now,
|
NotBefore: now,
|
||||||
NotAfter: now.Add(1 * time.Hour),
|
NotAfter: now.Add(1 * time.Hour),
|
||||||
@ -106,18 +107,53 @@ func TestCertificateAuthority(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "backdate",
|
name: "backdate without short",
|
||||||
policy: PermissiveSigningPolicy{TTL: time.Hour},
|
policy: PermissiveSigningPolicy{TTL: time.Hour, Backdate: 5 * time.Minute, Now: nowFunc},
|
||||||
backdate: 5 * time.Minute,
|
|
||||||
want: x509.Certificate{
|
want: x509.Certificate{
|
||||||
NotBefore: now.Add(-5 * time.Minute),
|
NotBefore: now.Add(-5 * time.Minute),
|
||||||
NotAfter: now.Add(55 * time.Minute),
|
NotAfter: now.Add(55 * time.Minute),
|
||||||
BasicConstraintsValid: true,
|
BasicConstraintsValid: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "backdate without short and super small ttl",
|
||||||
|
policy: PermissiveSigningPolicy{TTL: time.Minute, Backdate: 5 * time.Minute, Now: nowFunc},
|
||||||
|
want: x509.Certificate{
|
||||||
|
NotBefore: now.Add(-5 * time.Minute),
|
||||||
|
NotAfter: now.Add(-4 * time.Minute),
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "backdate with short",
|
||||||
|
policy: PermissiveSigningPolicy{TTL: time.Hour, Backdate: 5 * time.Minute, Short: 8 * time.Hour, Now: nowFunc},
|
||||||
|
want: x509.Certificate{
|
||||||
|
NotBefore: now.Add(-5 * time.Minute),
|
||||||
|
NotAfter: now.Add(time.Hour),
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "backdate with short and super small ttl",
|
||||||
|
policy: PermissiveSigningPolicy{TTL: time.Minute, Backdate: 5 * time.Minute, Short: 8 * time.Hour, Now: nowFunc},
|
||||||
|
want: x509.Certificate{
|
||||||
|
NotBefore: now.Add(-5 * time.Minute),
|
||||||
|
NotAfter: now.Add(time.Minute),
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "backdate with short but longer ttl",
|
||||||
|
policy: PermissiveSigningPolicy{TTL: 24 * time.Hour, Backdate: 5 * time.Minute, Short: 8 * time.Hour, Now: nowFunc},
|
||||||
|
want: x509.Certificate{
|
||||||
|
NotBefore: now.Add(-5 * time.Minute),
|
||||||
|
NotAfter: now.Add(24*time.Hour - 5*time.Minute),
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "truncate expiration",
|
name: "truncate expiration",
|
||||||
policy: PermissiveSigningPolicy{TTL: 48 * time.Hour},
|
policy: PermissiveSigningPolicy{TTL: 48 * time.Hour, Now: nowFunc},
|
||||||
want: x509.Certificate{
|
want: x509.Certificate{
|
||||||
NotBefore: now,
|
NotBefore: now,
|
||||||
NotAfter: now.Add(24 * time.Hour),
|
NotAfter: now.Add(24 * time.Hour),
|
||||||
@ -126,7 +162,7 @@ func TestCertificateAuthority(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "uri sans",
|
name: "uri sans",
|
||||||
policy: PermissiveSigningPolicy{TTL: time.Hour},
|
policy: PermissiveSigningPolicy{TTL: time.Hour, Now: nowFunc},
|
||||||
cr: x509.CertificateRequest{
|
cr: x509.CertificateRequest{
|
||||||
URIs: []*url.URL{uri},
|
URIs: []*url.URL{uri},
|
||||||
},
|
},
|
||||||
@ -137,6 +173,22 @@ func TestCertificateAuthority(t *testing.T) {
|
|||||||
BasicConstraintsValid: true,
|
BasicConstraintsValid: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "expired ca",
|
||||||
|
policy: PermissiveSigningPolicy{TTL: time.Hour, Now: nowFunc},
|
||||||
|
mutateCA: func(ca *CertificateAuthority) {
|
||||||
|
ca.Certificate.NotAfter = now // pretend that the CA has expired
|
||||||
|
},
|
||||||
|
wantErr: "the signer has expired: NotAfter=" + now.String(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "expired ca with backdate",
|
||||||
|
policy: PermissiveSigningPolicy{TTL: time.Hour, Backdate: 5 * time.Minute, Now: nowFunc},
|
||||||
|
mutateCA: func(ca *CertificateAuthority) {
|
||||||
|
ca.Certificate.NotAfter = now // pretend that the CA has expired
|
||||||
|
},
|
||||||
|
wantErr: "refusing to sign a certificate that expired in the past: NotAfter=" + now.String(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
crKey, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
crKey, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
||||||
@ -146,13 +198,15 @@ func TestCertificateAuthority(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
caCertShallowCopy := *caCert
|
||||||
|
|
||||||
ca := &CertificateAuthority{
|
ca := &CertificateAuthority{
|
||||||
Certificate: caCert,
|
Certificate: &caCertShallowCopy,
|
||||||
PrivateKey: caKey,
|
PrivateKey: caKey,
|
||||||
Now: func() time.Time {
|
}
|
||||||
return now
|
|
||||||
},
|
if test.mutateCA != nil {
|
||||||
Backdate: test.backdate,
|
test.mutateCA(ca)
|
||||||
}
|
}
|
||||||
|
|
||||||
csr, err := x509.CreateCertificateRequest(rand.Reader, &test.cr, crKey)
|
csr, err := x509.CreateCertificateRequest(rand.Reader, &test.cr, crKey)
|
||||||
@ -161,15 +215,15 @@ func TestCertificateAuthority(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
certDER, err := ca.Sign(csr, test.policy)
|
certDER, err := ca.Sign(csr, test.policy)
|
||||||
if err != nil {
|
if len(test.wantErr) > 0 {
|
||||||
t.Fatal(err)
|
if errStr := errString(err); test.wantErr != errStr {
|
||||||
}
|
t.Fatalf("expected error %s but got %s", test.wantErr, errStr)
|
||||||
if test.wantErr {
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("expected error")
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
cert, err := x509.ParseCertificate(certDER)
|
cert, err := x509.ParseCertificate(certDER)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -197,3 +251,11 @@ func TestCertificateAuthority(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func errString(err error) string {
|
||||||
|
if err == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
@ -31,7 +31,7 @@ import (
|
|||||||
type SigningPolicy interface {
|
type SigningPolicy interface {
|
||||||
// not-exporting apply forces signing policy implementations to be internal
|
// not-exporting apply forces signing policy implementations to be internal
|
||||||
// to this package.
|
// to this package.
|
||||||
apply(template *x509.Certificate) error
|
apply(template *x509.Certificate, signerNotAfter time.Time) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// PermissiveSigningPolicy is the signing policy historically used by the local
|
// PermissiveSigningPolicy is the signing policy historically used by the local
|
||||||
@ -39,32 +39,75 @@ type SigningPolicy interface {
|
|||||||
//
|
//
|
||||||
// * It forwards all SANs from the original signing request.
|
// * It forwards all SANs from the original signing request.
|
||||||
// * It sets allowed usages as configured in the policy.
|
// * It sets allowed usages as configured in the policy.
|
||||||
// * It sets NotAfter based on the TTL configured in the policy.
|
|
||||||
// * It zeros all extensions.
|
// * It zeros all extensions.
|
||||||
// * It sets BasicConstraints to true.
|
// * It sets BasicConstraints to true.
|
||||||
// * It sets IsCA to false.
|
// * It sets IsCA to false.
|
||||||
|
// * It validates that the signer has not expired.
|
||||||
|
// * It sets NotBefore and NotAfter:
|
||||||
|
// All certificates set NotBefore = Now() - Backdate.
|
||||||
|
// Long-lived certificates set NotAfter = Now() + TTL - Backdate.
|
||||||
|
// Short-lived certificates set NotAfter = Now() + TTL.
|
||||||
|
// All certificates truncate NotAfter to the expiration date of the signer.
|
||||||
type PermissiveSigningPolicy struct {
|
type PermissiveSigningPolicy struct {
|
||||||
// TTL is the certificate TTL. It's used to calculate the NotAfter value of
|
// TTL is used in certificate NotAfter calculation as described above.
|
||||||
// the certificate.
|
|
||||||
TTL time.Duration
|
TTL time.Duration
|
||||||
|
|
||||||
// Usages are the allowed usages of a certificate.
|
// Usages are the allowed usages of a certificate.
|
||||||
Usages []capi.KeyUsage
|
Usages []capi.KeyUsage
|
||||||
|
|
||||||
|
// Backdate is used in certificate NotBefore calculation as described above.
|
||||||
|
Backdate time.Duration
|
||||||
|
|
||||||
|
// Short is the duration used to determine if the lifetime of a certificate should be considered short.
|
||||||
|
Short time.Duration
|
||||||
|
|
||||||
|
// Now defaults to time.Now but can be stubbed for testing
|
||||||
|
Now func() time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p PermissiveSigningPolicy) apply(tmpl *x509.Certificate) error {
|
func (p PermissiveSigningPolicy) apply(tmpl *x509.Certificate, signerNotAfter time.Time) error {
|
||||||
|
var now time.Time
|
||||||
|
if p.Now != nil {
|
||||||
|
now = p.Now()
|
||||||
|
} else {
|
||||||
|
now = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
ttl := p.TTL
|
||||||
|
|
||||||
usage, extUsages, err := keyUsagesFromStrings(p.Usages)
|
usage, extUsages, err := keyUsagesFromStrings(p.Usages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tmpl.KeyUsage = usage
|
tmpl.KeyUsage = usage
|
||||||
tmpl.ExtKeyUsage = extUsages
|
tmpl.ExtKeyUsage = extUsages
|
||||||
tmpl.NotAfter = tmpl.NotBefore.Add(p.TTL)
|
|
||||||
|
|
||||||
tmpl.ExtraExtensions = nil
|
tmpl.ExtraExtensions = nil
|
||||||
tmpl.Extensions = nil
|
tmpl.Extensions = nil
|
||||||
tmpl.BasicConstraintsValid = true
|
tmpl.BasicConstraintsValid = true
|
||||||
tmpl.IsCA = false
|
tmpl.IsCA = false
|
||||||
|
|
||||||
|
tmpl.NotBefore = now.Add(-p.Backdate)
|
||||||
|
|
||||||
|
if ttl < p.Short {
|
||||||
|
// do not backdate the end time if we consider this to be a short lived certificate
|
||||||
|
tmpl.NotAfter = now.Add(ttl)
|
||||||
|
} else {
|
||||||
|
tmpl.NotAfter = now.Add(ttl - p.Backdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tmpl.NotAfter.Before(signerNotAfter) {
|
||||||
|
tmpl.NotAfter = signerNotAfter
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tmpl.NotBefore.Before(signerNotAfter) {
|
||||||
|
return fmt.Errorf("the signer has expired: NotAfter=%v", signerNotAfter)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !now.Before(signerNotAfter) {
|
||||||
|
return fmt.Errorf("refusing to sign a certificate that expired in the past: NotAfter=%v", signerNotAfter)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +167,7 @@ func keyUsagesFromStrings(usages []capi.KeyUsage) (x509.KeyUsage, []x509.ExtKeyU
|
|||||||
return 0, nil, fmt.Errorf("unrecognized usage values: %q", unrecognized)
|
return 0, nil, fmt.Errorf("unrecognized usage values: %q", unrecognized)
|
||||||
}
|
}
|
||||||
|
|
||||||
return keyUsage, []x509.ExtKeyUsage(sorted), nil
|
return keyUsage, sorted, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type sortedExtKeyUsage []x509.ExtKeyUsage
|
type sortedExtKeyUsage []x509.ExtKeyUsage
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
"crypto"
|
"crypto"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
||||||
"k8s.io/client-go/util/cert"
|
"k8s.io/client-go/util/cert"
|
||||||
@ -77,7 +76,6 @@ func (p *caProvider) setCA() error {
|
|||||||
|
|
||||||
Certificate: certs[0],
|
Certificate: certs[0],
|
||||||
PrivateKey: priv,
|
PrivateKey: priv,
|
||||||
Backdate: 5 * time.Minute,
|
|
||||||
}
|
}
|
||||||
p.caValue.Store(ca)
|
p.caValue.Store(ca)
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ func (s *signer) handle(csr *capi.CertificateSigningRequest) error {
|
|||||||
// Ignore requests for kubernetes.io signerNames we don't recognize
|
// Ignore requests for kubernetes.io signerNames we don't recognize
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cert, err := s.sign(x509cr, csr.Spec.Usages)
|
cert, err := s.sign(x509cr, csr.Spec.Usages, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error auto signing csr: %v", err)
|
return fmt.Errorf("error auto signing csr: %v", err)
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ func (s *signer) handle(csr *capi.CertificateSigningRequest) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *signer) sign(x509cr *x509.CertificateRequest, usages []capi.KeyUsage) ([]byte, error) {
|
func (s *signer) sign(x509cr *x509.CertificateRequest, usages []capi.KeyUsage, now func() time.Time) ([]byte, error) {
|
||||||
currCA, err := s.caProvider.currentCA()
|
currCA, err := s.caProvider.currentCA()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -193,6 +193,9 @@ func (s *signer) sign(x509cr *x509.CertificateRequest, usages []capi.KeyUsage) (
|
|||||||
der, err := currCA.Sign(x509cr.Raw, authority.PermissiveSigningPolicy{
|
der, err := currCA.Sign(x509cr.Raw, authority.PermissiveSigningPolicy{
|
||||||
TTL: s.certTTL,
|
TTL: s.certTTL,
|
||||||
Usages: usages,
|
Usages: usages,
|
||||||
|
Backdate: 5 * time.Minute, // this must always be less than the minimum TTL requested by a user
|
||||||
|
Short: 8 * time.Hour, // 5 minutes of backdating is roughly 1% of 8 hours
|
||||||
|
Now: now,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -35,25 +35,17 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
testclient "k8s.io/client-go/testing"
|
testclient "k8s.io/client-go/testing"
|
||||||
"k8s.io/client-go/util/cert"
|
"k8s.io/client-go/util/cert"
|
||||||
"k8s.io/kubernetes/pkg/controller/certificates"
|
|
||||||
|
|
||||||
capihelper "k8s.io/kubernetes/pkg/apis/certificates/v1"
|
capihelper "k8s.io/kubernetes/pkg/apis/certificates/v1"
|
||||||
|
"k8s.io/kubernetes/pkg/controller/certificates"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSigner(t *testing.T) {
|
func TestSigner(t *testing.T) {
|
||||||
clock := clock.FakeClock{}
|
fakeClock := clock.FakeClock{}
|
||||||
|
|
||||||
s, err := newSigner("kubernetes.io/legacy-unknown", "./testdata/ca.crt", "./testdata/ca.key", nil, 1*time.Hour)
|
s, err := newSigner("kubernetes.io/legacy-unknown", "./testdata/ca.crt", "./testdata/ca.key", nil, 1*time.Hour)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create signer: %v", err)
|
t.Fatalf("failed to create signer: %v", err)
|
||||||
}
|
}
|
||||||
currCA, err := s.caProvider.currentCA()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
currCA.Now = clock.Now
|
|
||||||
currCA.Backdate = 0
|
|
||||||
s.caProvider.caValue.Store(currCA)
|
|
||||||
|
|
||||||
csrb, err := ioutil.ReadFile("./testdata/kubelet.csr")
|
csrb, err := ioutil.ReadFile("./testdata/kubelet.csr")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -69,7 +61,7 @@ func TestSigner(t *testing.T) {
|
|||||||
capi.UsageKeyEncipherment,
|
capi.UsageKeyEncipherment,
|
||||||
capi.UsageServerAuth,
|
capi.UsageServerAuth,
|
||||||
capi.UsageClientAuth,
|
capi.UsageClientAuth,
|
||||||
})
|
}, fakeClock.Now)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to sign CSR: %v", err)
|
t.Fatalf("failed to sign CSR: %v", err)
|
||||||
}
|
}
|
||||||
@ -94,7 +86,8 @@ func TestSigner(t *testing.T) {
|
|||||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
||||||
BasicConstraintsValid: true,
|
BasicConstraintsValid: true,
|
||||||
NotAfter: clock.Now().Add(1 * time.Hour),
|
NotBefore: fakeClock.Now().Add(-5 * time.Minute),
|
||||||
|
NotAfter: fakeClock.Now().Add(1 * time.Hour),
|
||||||
PublicKeyAlgorithm: x509.ECDSA,
|
PublicKeyAlgorithm: x509.ECDSA,
|
||||||
SignatureAlgorithm: x509.SHA256WithRSA,
|
SignatureAlgorithm: x509.SHA256WithRSA,
|
||||||
MaxPathLen: -1,
|
MaxPathLen: -1,
|
||||||
|
Loading…
Reference in New Issue
Block a user