forked from TrueCloudLab/certificates
Remove unnecessary properties.
This commit is contained in:
parent
f2dd5c48cc
commit
60515d92c5
4 changed files with 60 additions and 59 deletions
|
@ -2,7 +2,6 @@ package authority
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto"
|
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
@ -39,8 +38,6 @@ type Authority struct {
|
||||||
x509CAService cas.CertificateAuthorityService
|
x509CAService cas.CertificateAuthorityService
|
||||||
rootX509Certs []*x509.Certificate
|
rootX509Certs []*x509.Certificate
|
||||||
federatedX509Certs []*x509.Certificate
|
federatedX509Certs []*x509.Certificate
|
||||||
x509Signer crypto.Signer
|
|
||||||
x509Issuer *x509.Certificate
|
|
||||||
certificates *sync.Map
|
certificates *sync.Map
|
||||||
|
|
||||||
// SSH CA
|
// SSH CA
|
||||||
|
@ -110,9 +107,9 @@ func NewEmbedded(opts ...Option) (*Authority, error) {
|
||||||
return nil, errors.New("cannot create an authority without a configuration")
|
return nil, errors.New("cannot create an authority without a configuration")
|
||||||
case len(a.rootX509Certs) == 0 && a.config.Root.HasEmpties():
|
case len(a.rootX509Certs) == 0 && a.config.Root.HasEmpties():
|
||||||
return nil, errors.New("cannot create an authority without a root certificate")
|
return nil, errors.New("cannot create an authority without a root certificate")
|
||||||
case a.x509Issuer == nil && a.config.IntermediateCert == "":
|
case a.x509CAService == nil && a.config.IntermediateCert == "":
|
||||||
return nil, errors.New("cannot create an authority without an issuer certificate")
|
return nil, errors.New("cannot create an authority without an issuer certificate")
|
||||||
case a.x509Signer == nil && a.config.IntermediateKey == "":
|
case a.x509CAService == nil && a.config.IntermediateKey == "":
|
||||||
return nil, errors.New("cannot create an authority without an issuer signer")
|
return nil, errors.New("cannot create an authority without an issuer signer")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,38 +185,26 @@ func (a *Authority) init() error {
|
||||||
a.certificates.Store(hex.EncodeToString(sum[:]), crt)
|
a.certificates.Store(hex.EncodeToString(sum[:]), crt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read intermediate and create X509 signer.
|
// Initialize the X.509 CA Service if it has not been set in the options.
|
||||||
if a.x509Signer == nil {
|
|
||||||
crt, err := pemutil.ReadCertificate(a.config.IntermediateCert)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
a.x509Issuer = crt
|
|
||||||
|
|
||||||
// Read signer only is the CAS is the default one.
|
|
||||||
if a.config.CAS.HasType(casapi.SoftCAS) {
|
|
||||||
signer, err := a.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{
|
|
||||||
SigningKey: a.config.IntermediateKey,
|
|
||||||
Password: []byte(a.config.Password),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
a.x509Signer = signer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the X.509 CA Service if it has not been set in the options
|
|
||||||
if a.x509CAService == nil {
|
if a.x509CAService == nil {
|
||||||
var options casapi.Options
|
var options casapi.Options
|
||||||
if a.config.CAS != nil {
|
if a.config.CAS != nil {
|
||||||
options = *a.config.CAS
|
options = *a.config.CAS
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set issuer and signer for default CAS.
|
// Read intermediate and create X509 signer for default CAS.
|
||||||
if options.HasType(casapi.SoftCAS) {
|
if options.HasType(casapi.SoftCAS) {
|
||||||
options.Issuer = a.x509Issuer
|
options.Issuer, err = pemutil.ReadCertificate(a.config.IntermediateCert)
|
||||||
options.Signer = a.x509Signer
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
options.Signer, err = a.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{
|
||||||
|
SigningKey: a.config.IntermediateKey,
|
||||||
|
Password: []byte(a.config.Password),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a.x509CAService, err = cas.New(context.Background(), options)
|
a.x509CAService, err = cas.New(context.Background(), options)
|
||||||
|
|
|
@ -143,8 +143,7 @@ func TestAuthorityNew(t *testing.T) {
|
||||||
assert.Equals(t, auth.rootX509Certs[0], root)
|
assert.Equals(t, auth.rootX509Certs[0], root)
|
||||||
|
|
||||||
assert.True(t, auth.initOnce)
|
assert.True(t, auth.initOnce)
|
||||||
assert.NotNil(t, auth.x509Signer)
|
assert.NotNil(t, auth.x509CAService)
|
||||||
assert.NotNil(t, auth.x509Issuer)
|
|
||||||
for _, p := range tc.config.AuthorityConfig.Provisioners {
|
for _, p := range tc.config.AuthorityConfig.Provisioners {
|
||||||
var _p provisioner.Interface
|
var _p provisioner.Interface
|
||||||
_p, ok = auth.provisioners.Load(p.GetID())
|
_p, ok = auth.provisioners.Load(p.GetID())
|
||||||
|
@ -256,8 +255,7 @@ func TestNewEmbedded(t *testing.T) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
assert.True(t, got.initOnce)
|
assert.True(t, got.initOnce)
|
||||||
assert.NotNil(t, got.rootX509Certs)
|
assert.NotNil(t, got.rootX509Certs)
|
||||||
assert.NotNil(t, got.x509Signer)
|
assert.NotNil(t, got.x509CAService)
|
||||||
assert.NotNil(t, got.x509Issuer)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ import (
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/authority/provisioner"
|
"github.com/smallstep/certificates/authority/provisioner"
|
||||||
|
"github.com/smallstep/certificates/cas"
|
||||||
|
casapi "github.com/smallstep/certificates/cas/apiv1"
|
||||||
"github.com/smallstep/certificates/db"
|
"github.com/smallstep/certificates/db"
|
||||||
"github.com/smallstep/certificates/kms"
|
"github.com/smallstep/certificates/kms"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
|
@ -92,8 +94,15 @@ func WithKeyManager(k kms.KeyManager) Option {
|
||||||
// WithX509Signer defines the signer used to sign X509 certificates.
|
// WithX509Signer defines the signer used to sign X509 certificates.
|
||||||
func WithX509Signer(crt *x509.Certificate, s crypto.Signer) Option {
|
func WithX509Signer(crt *x509.Certificate, s crypto.Signer) Option {
|
||||||
return func(a *Authority) error {
|
return func(a *Authority) error {
|
||||||
a.x509Issuer = crt
|
srv, err := cas.New(context.Background(), casapi.Options{
|
||||||
a.x509Signer = s
|
Type: casapi.SoftCAS,
|
||||||
|
Issuer: crt,
|
||||||
|
Signer: s,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
a.x509CAService = srv
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,14 @@ func (m *certificateDurationEnforcer) Enforce(cert *x509.Certificate) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getDefaultIssuer(a *Authority) *x509.Certificate {
|
||||||
|
return a.x509CAService.(*softcas.SoftCAS).Issuer
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDefaultSigner(a *Authority) crypto.Signer {
|
||||||
|
return a.x509CAService.(*softcas.SoftCAS).Signer
|
||||||
|
}
|
||||||
|
|
||||||
func generateCertificate(t *testing.T, commonName string, sans []string, opts ...interface{}) *x509.Certificate {
|
func generateCertificate(t *testing.T, commonName string, sans []string, opts ...interface{}) *x509.Certificate {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
@ -541,17 +549,15 @@ ZYtQ9Ot36qc=
|
||||||
assert.Equals(t, leaf.DNSNames, []string{"test.smallstep.com"})
|
assert.Equals(t, leaf.DNSNames, []string{"test.smallstep.com"})
|
||||||
}
|
}
|
||||||
assert.Equals(t, leaf.Issuer, intermediate.Subject)
|
assert.Equals(t, leaf.Issuer, intermediate.Subject)
|
||||||
|
|
||||||
assert.Equals(t, leaf.SignatureAlgorithm, x509.ECDSAWithSHA256)
|
assert.Equals(t, leaf.SignatureAlgorithm, x509.ECDSAWithSHA256)
|
||||||
assert.Equals(t, leaf.PublicKeyAlgorithm, x509.ECDSA)
|
assert.Equals(t, leaf.PublicKeyAlgorithm, x509.ECDSA)
|
||||||
assert.Equals(t, leaf.ExtKeyUsage,
|
assert.Equals(t, leaf.ExtKeyUsage, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth})
|
||||||
[]x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth})
|
|
||||||
|
|
||||||
|
issuer := getDefaultIssuer(a)
|
||||||
subjectKeyID, err := generateSubjectKeyID(pub)
|
subjectKeyID, err := generateSubjectKeyID(pub)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, leaf.SubjectKeyId, subjectKeyID)
|
assert.Equals(t, leaf.SubjectKeyId, subjectKeyID)
|
||||||
|
assert.Equals(t, leaf.AuthorityKeyId, issuer.SubjectKeyId)
|
||||||
assert.Equals(t, leaf.AuthorityKeyId, a.x509Issuer.SubjectKeyId)
|
|
||||||
|
|
||||||
// Verify Provisioner OID
|
// Verify Provisioner OID
|
||||||
found := 0
|
found := 0
|
||||||
|
@ -587,8 +593,7 @@ ZYtQ9Ot36qc=
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert.Equals(t, found, 1)
|
assert.Equals(t, found, 1)
|
||||||
|
realIntermediate, err := x509.ParseCertificate(issuer.Raw)
|
||||||
realIntermediate, err := x509.ParseCertificate(a.x509Issuer.Raw)
|
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, intermediate, realIntermediate)
|
assert.Equals(t, intermediate, realIntermediate)
|
||||||
}
|
}
|
||||||
|
@ -616,17 +621,20 @@ func TestAuthority_Renew(t *testing.T) {
|
||||||
NotAfter: provisioner.NewTimeDuration(na1),
|
NotAfter: provisioner.NewTimeDuration(na1),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issuer := getDefaultIssuer(a)
|
||||||
|
signer := getDefaultSigner(a)
|
||||||
|
|
||||||
cert := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
|
cert := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
|
||||||
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
|
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
|
||||||
withDefaultASN1DN(a.config.AuthorityConfig.Template),
|
withDefaultASN1DN(a.config.AuthorityConfig.Template),
|
||||||
withProvisionerOID("Max", a.config.AuthorityConfig.Provisioners[0].(*provisioner.JWK).Key.KeyID),
|
withProvisionerOID("Max", a.config.AuthorityConfig.Provisioners[0].(*provisioner.JWK).Key.KeyID),
|
||||||
withSigner(a.x509Issuer, a.x509Signer))
|
withSigner(issuer, signer))
|
||||||
|
|
||||||
certNoRenew := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
|
certNoRenew := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
|
||||||
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
|
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
|
||||||
withDefaultASN1DN(a.config.AuthorityConfig.Template),
|
withDefaultASN1DN(a.config.AuthorityConfig.Template),
|
||||||
withProvisionerOID("dev", a.config.AuthorityConfig.Provisioners[2].(*provisioner.JWK).Key.KeyID),
|
withProvisionerOID("dev", a.config.AuthorityConfig.Provisioners[2].(*provisioner.JWK).Key.KeyID),
|
||||||
withSigner(a.x509Issuer, a.x509Signer))
|
withSigner(issuer, signer))
|
||||||
|
|
||||||
type renewTest struct {
|
type renewTest struct {
|
||||||
auth *Authority
|
auth *Authority
|
||||||
|
@ -665,8 +673,6 @@ func TestAuthority_Renew(t *testing.T) {
|
||||||
_a := testAuthority(t)
|
_a := testAuthority(t)
|
||||||
_a.x509CAService.(*softcas.SoftCAS).Issuer = intCert
|
_a.x509CAService.(*softcas.SoftCAS).Issuer = intCert
|
||||||
_a.x509CAService.(*softcas.SoftCAS).Signer = intSigner
|
_a.x509CAService.(*softcas.SoftCAS).Signer = intSigner
|
||||||
_a.x509Signer = intSigner
|
|
||||||
_a.x509Issuer = intCert
|
|
||||||
return &renewTest{
|
return &renewTest{
|
||||||
auth: _a,
|
auth: _a,
|
||||||
cert: cert,
|
cert: cert,
|
||||||
|
@ -733,8 +739,9 @@ func TestAuthority_Renew(t *testing.T) {
|
||||||
assert.Equals(t, leaf.SubjectKeyId, subjectKeyID)
|
assert.Equals(t, leaf.SubjectKeyId, subjectKeyID)
|
||||||
|
|
||||||
// We did not change the intermediate before renewing.
|
// We did not change the intermediate before renewing.
|
||||||
if a.x509Issuer.SerialNumber == tc.auth.x509Issuer.SerialNumber {
|
authIssuer := getDefaultIssuer(tc.auth)
|
||||||
assert.Equals(t, leaf.AuthorityKeyId, a.x509Issuer.SubjectKeyId)
|
if issuer.SerialNumber == authIssuer.SerialNumber {
|
||||||
|
assert.Equals(t, leaf.AuthorityKeyId, issuer.SubjectKeyId)
|
||||||
// Compare extensions: they can be in a different order
|
// Compare extensions: they can be in a different order
|
||||||
for _, ext1 := range tc.cert.Extensions {
|
for _, ext1 := range tc.cert.Extensions {
|
||||||
//skip SubjectKeyIdentifier
|
//skip SubjectKeyIdentifier
|
||||||
|
@ -754,7 +761,7 @@ func TestAuthority_Renew(t *testing.T) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We did change the intermediate before renewing.
|
// We did change the intermediate before renewing.
|
||||||
assert.Equals(t, leaf.AuthorityKeyId, tc.auth.x509Issuer.SubjectKeyId)
|
assert.Equals(t, leaf.AuthorityKeyId, authIssuer.SubjectKeyId)
|
||||||
// Compare extensions: they can be in a different order
|
// Compare extensions: they can be in a different order
|
||||||
for _, ext1 := range tc.cert.Extensions {
|
for _, ext1 := range tc.cert.Extensions {
|
||||||
//skip SubjectKeyIdentifier
|
//skip SubjectKeyIdentifier
|
||||||
|
@ -782,7 +789,7 @@ func TestAuthority_Renew(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
realIntermediate, err := x509.ParseCertificate(tc.auth.x509Issuer.Raw)
|
realIntermediate, err := x509.ParseCertificate(authIssuer.Raw)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, intermediate, realIntermediate)
|
assert.Equals(t, intermediate, realIntermediate)
|
||||||
}
|
}
|
||||||
|
@ -813,17 +820,20 @@ func TestAuthority_Rekey(t *testing.T) {
|
||||||
NotAfter: provisioner.NewTimeDuration(na1),
|
NotAfter: provisioner.NewTimeDuration(na1),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issuer := getDefaultIssuer(a)
|
||||||
|
signer := getDefaultSigner(a)
|
||||||
|
|
||||||
cert := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
|
cert := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
|
||||||
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
|
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
|
||||||
withDefaultASN1DN(a.config.AuthorityConfig.Template),
|
withDefaultASN1DN(a.config.AuthorityConfig.Template),
|
||||||
withProvisionerOID("Max", a.config.AuthorityConfig.Provisioners[0].(*provisioner.JWK).Key.KeyID),
|
withProvisionerOID("Max", a.config.AuthorityConfig.Provisioners[0].(*provisioner.JWK).Key.KeyID),
|
||||||
withSigner(a.x509Issuer, a.x509Signer))
|
withSigner(issuer, signer))
|
||||||
|
|
||||||
certNoRenew := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
|
certNoRenew := generateCertificate(t, "renew", []string{"test.smallstep.com", "test"},
|
||||||
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
|
withNotBeforeNotAfter(so.NotBefore.Time(), so.NotAfter.Time()),
|
||||||
withDefaultASN1DN(a.config.AuthorityConfig.Template),
|
withDefaultASN1DN(a.config.AuthorityConfig.Template),
|
||||||
withProvisionerOID("dev", a.config.AuthorityConfig.Provisioners[2].(*provisioner.JWK).Key.KeyID),
|
withProvisionerOID("dev", a.config.AuthorityConfig.Provisioners[2].(*provisioner.JWK).Key.KeyID),
|
||||||
withSigner(a.x509Issuer, a.x509Signer))
|
withSigner(issuer, signer))
|
||||||
|
|
||||||
type renewTest struct {
|
type renewTest struct {
|
||||||
auth *Authority
|
auth *Authority
|
||||||
|
@ -870,8 +880,6 @@ func TestAuthority_Rekey(t *testing.T) {
|
||||||
_a := testAuthority(t)
|
_a := testAuthority(t)
|
||||||
_a.x509CAService.(*softcas.SoftCAS).Issuer = intCert
|
_a.x509CAService.(*softcas.SoftCAS).Issuer = intCert
|
||||||
_a.x509CAService.(*softcas.SoftCAS).Signer = intSigner
|
_a.x509CAService.(*softcas.SoftCAS).Signer = intSigner
|
||||||
_a.x509Signer = intSigner
|
|
||||||
_a.x509Issuer = intCert
|
|
||||||
return &renewTest{
|
return &renewTest{
|
||||||
auth: _a,
|
auth: _a,
|
||||||
cert: cert,
|
cert: cert,
|
||||||
|
@ -948,8 +956,9 @@ func TestAuthority_Rekey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We did not change the intermediate before renewing.
|
// We did not change the intermediate before renewing.
|
||||||
if a.x509Issuer.SerialNumber == tc.auth.x509Issuer.SerialNumber {
|
authIssuer := getDefaultIssuer(tc.auth)
|
||||||
assert.Equals(t, leaf.AuthorityKeyId, a.x509Issuer.SubjectKeyId)
|
if issuer.SerialNumber == authIssuer.SerialNumber {
|
||||||
|
assert.Equals(t, leaf.AuthorityKeyId, issuer.SubjectKeyId)
|
||||||
// Compare extensions: they can be in a different order
|
// Compare extensions: they can be in a different order
|
||||||
for _, ext1 := range tc.cert.Extensions {
|
for _, ext1 := range tc.cert.Extensions {
|
||||||
//skip SubjectKeyIdentifier
|
//skip SubjectKeyIdentifier
|
||||||
|
@ -969,7 +978,7 @@ func TestAuthority_Rekey(t *testing.T) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We did change the intermediate before renewing.
|
// We did change the intermediate before renewing.
|
||||||
assert.Equals(t, leaf.AuthorityKeyId, tc.auth.x509Issuer.SubjectKeyId)
|
assert.Equals(t, leaf.AuthorityKeyId, authIssuer.SubjectKeyId)
|
||||||
// Compare extensions: they can be in a different order
|
// Compare extensions: they can be in a different order
|
||||||
for _, ext1 := range tc.cert.Extensions {
|
for _, ext1 := range tc.cert.Extensions {
|
||||||
//skip SubjectKeyIdentifier
|
//skip SubjectKeyIdentifier
|
||||||
|
@ -997,7 +1006,7 @@ func TestAuthority_Rekey(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
realIntermediate, err := x509.ParseCertificate(tc.auth.x509Issuer.Raw)
|
realIntermediate, err := x509.ParseCertificate(authIssuer.Raw)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, intermediate, realIntermediate)
|
assert.Equals(t, intermediate, realIntermediate)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue