
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>
79 lines
2.5 KiB
Go
79 lines
2.5 KiB
Go
/*
|
|
Copyright 2019 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package authority
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/rand"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"math/big"
|
|
)
|
|
|
|
var serialNumberLimit = new(big.Int).Lsh(big.NewInt(1), 128)
|
|
|
|
// CertificateAuthority implements a certificate authority that supports policy
|
|
// based signing. It's used by the signing controller.
|
|
type CertificateAuthority struct {
|
|
// RawCert is an optional field to determine if signing cert/key pairs have changed
|
|
RawCert []byte
|
|
// RawKey is an optional field to determine if signing cert/key pairs have changed
|
|
RawKey []byte
|
|
|
|
Certificate *x509.Certificate
|
|
PrivateKey crypto.Signer
|
|
}
|
|
|
|
// Sign signs a certificate request, applying a SigningPolicy and returns a DER
|
|
// encoded x509 certificate.
|
|
func (ca *CertificateAuthority) Sign(crDER []byte, policy SigningPolicy) ([]byte, error) {
|
|
cr, err := x509.ParseCertificateRequest(crDER)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to parse certificate request: %v", err)
|
|
}
|
|
if err := cr.CheckSignature(); err != nil {
|
|
return nil, fmt.Errorf("unable to verify certificate request signature: %v", err)
|
|
}
|
|
|
|
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to generate a serial number for %s: %v", cr.Subject.CommonName, err)
|
|
}
|
|
|
|
tmpl := &x509.Certificate{
|
|
SerialNumber: serialNumber,
|
|
Subject: cr.Subject,
|
|
DNSNames: cr.DNSNames,
|
|
IPAddresses: cr.IPAddresses,
|
|
EmailAddresses: cr.EmailAddresses,
|
|
URIs: cr.URIs,
|
|
PublicKeyAlgorithm: cr.PublicKeyAlgorithm,
|
|
PublicKey: cr.PublicKey,
|
|
Extensions: cr.Extensions,
|
|
ExtraExtensions: cr.ExtraExtensions,
|
|
}
|
|
if err := policy.apply(tmpl, ca.Certificate.NotAfter); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
der, err := x509.CreateCertificate(rand.Reader, tmpl, ca.Certificate, cr.PublicKey, ca.PrivateKey)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to sign certificate: %v", err)
|
|
}
|
|
return der, nil
|
|
}
|