leverage intermediate_ca.crt for appending certs.

This commit is contained in:
Miclain Keffeler 2020-12-23 22:41:10 -06:00
parent c255863816
commit 7545b4a625
8 changed files with 53 additions and 59 deletions

View file

@ -164,7 +164,7 @@ func (a *Authority) init() error {
// Read intermediate and create X509 signer for default CAS.
if options.Is(casapi.SoftCAS) {
options.Issuer, err = pemutil.ReadCertificate(a.config.IntermediateCert)
options.CertificateChain, err = pemutil.ReadCertificateBundle(a.config.IntermediateCert)
if err != nil {
return err
}

View file

@ -96,8 +96,8 @@ func WithX509Signer(crt *x509.Certificate, s crypto.Signer) Option {
return func(a *Authority) error {
srv, err := cas.New(context.Background(), casapi.Options{
Type: casapi.SoftCAS,
Issuer: crt,
Signer: s,
CertificateChain: []*x509.Certificate{crt},
})
if err != nil {
return err

View file

@ -56,7 +56,7 @@ func (m *certificateDurationEnforcer) Enforce(cert *x509.Certificate) error {
}
func getDefaultIssuer(a *Authority) *x509.Certificate {
return a.x509CAService.(*softcas.SoftCAS).Issuer
return a.x509CAService.(*softcas.SoftCAS).CertificateChain[len(a.x509CAService.(*softcas.SoftCAS).CertificateChain)-1]
}
func getDefaultSigner(a *Authority) crypto.Signer {
@ -671,7 +671,7 @@ func TestAuthority_Renew(t *testing.T) {
intCert, intSigner := generateIntermidiateCertificate(t, rootCert, rootSigner)
_a := testAuthority(t)
_a.x509CAService.(*softcas.SoftCAS).Issuer = intCert
_a.x509CAService.(*softcas.SoftCAS).CertificateChain = []*x509.Certificate{intCert}
_a.x509CAService.(*softcas.SoftCAS).Signer = intSigner
return &renewTest{
auth: _a,
@ -878,7 +878,7 @@ func TestAuthority_Rekey(t *testing.T) {
intCert, intSigner := generateIntermidiateCertificate(t, rootCert, rootSigner)
_a := testAuthority(t)
_a.x509CAService.(*softcas.SoftCAS).Issuer = intCert
_a.x509CAService.(*softcas.SoftCAS).CertificateChain = []*x509.Certificate{intCert}
_a.x509CAService.(*softcas.SoftCAS).Signer = intSigner
return &renewTest{
auth: _a,

View file

@ -23,7 +23,7 @@ type Options struct {
// Issuer and signer are the issuer certificate and signer used in SoftCAS.
// They are configured in ca.json crt and key properties.
Issuer *x509.Certificate `json:"-"`
CertificateChain []*x509.Certificate
Signer crypto.Signer `json:"-"`
// IsCreator is set to true when we're creating a certificate authority. Is

View file

@ -70,7 +70,7 @@ func TestOptions_Validate(t *testing.T) {
Type: tt.fields.Type,
CredentialsFile: tt.fields.CredentialsFile,
CertificateAuthority: tt.fields.CertificateAuthority,
Issuer: tt.fields.Issuer,
CertificateChain: []*x509.Certificate{tt.fields.Issuer},
Signer: tt.fields.Signer,
}
if err := o.Validate(); (err != nil) != tt.wantErr {
@ -120,7 +120,7 @@ func TestOptions_Is(t *testing.T) {
Type: tt.fields.Type,
CredentialsFile: tt.fields.CredentialsFile,
CertificateAuthority: tt.fields.CertificateAuthority,
Issuer: tt.fields.Issuer,
CertificateChain: []*x509.Certificate{tt.fields.Issuer},
Signer: tt.fields.Signer,
}
if got := o.Is(tt.args.t); got != tt.want {

View file

@ -31,7 +31,7 @@ func (m *mockCAS) RevokeCertificate(req *apiv1.RevokeCertificateRequest) (*apiv1
func TestNew(t *testing.T) {
expected := &softcas.SoftCAS{
Issuer: &x509.Certificate{Subject: pkix.Name{CommonName: "Test Issuer"}},
CertificateChain: []*x509.Certificate{{Subject: pkix.Name{CommonName: "Test Issuer"}}},
Signer: ed25519.PrivateKey{},
}
@ -50,17 +50,17 @@ func TestNew(t *testing.T) {
wantErr bool
}{
{"ok default", args{context.Background(), apiv1.Options{
Issuer: &x509.Certificate{Subject: pkix.Name{CommonName: "Test Issuer"}},
CertificateChain: []*x509.Certificate{{Subject: pkix.Name{CommonName: "Test Issuer"}}},
Signer: ed25519.PrivateKey{},
}}, expected, false},
{"ok softcas", args{context.Background(), apiv1.Options{
Type: "softcas",
Issuer: &x509.Certificate{Subject: pkix.Name{CommonName: "Test Issuer"}},
CertificateChain: []*x509.Certificate{{Subject: pkix.Name{CommonName: "Test Issuer"}}},
Signer: ed25519.PrivateKey{},
}}, expected, false},
{"ok SoftCAS", args{context.Background(), apiv1.Options{
Type: "SoftCAS",
Issuer: &x509.Certificate{Subject: pkix.Name{CommonName: "Test Issuer"}},
CertificateChain: []*x509.Certificate{{Subject: pkix.Name{CommonName: "Test Issuer"}}},
Signer: ed25519.PrivateKey{},
}}, expected, false},
{"fail empty", args{context.Background(), apiv1.Options{}}, (*softcas.SoftCAS)(nil), true},

View file

@ -26,7 +26,7 @@ var now = func() time.Time {
// SoftCAS implements a Certificate Authority Service using Golang or KMS
// crypto. This is the default CAS used in step-ca.
type SoftCAS struct {
Issuer *x509.Certificate
CertificateChain []*x509.Certificate
Signer crypto.Signer
KeyManager kms.KeyManager
}
@ -36,14 +36,14 @@ type SoftCAS struct {
func New(ctx context.Context, opts apiv1.Options) (*SoftCAS, error) {
if !opts.IsCreator {
switch {
case opts.Issuer == nil:
return nil, errors.New("softCAS 'issuer' cannot be nil")
case opts.CertificateChain == nil:
return nil, errors.New("softCAS 'CertificateChain' cannot be nil")
case opts.Signer == nil:
return nil, errors.New("softCAS 'signer' cannot be nil")
}
}
return &SoftCAS{
Issuer: opts.Issuer,
CertificateChain: opts.CertificateChain,
Signer: opts.Signer,
KeyManager: opts.KeyManager,
}, nil
@ -66,18 +66,16 @@ func (c *SoftCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1
if req.Template.NotAfter.IsZero() {
req.Template.NotAfter = t.Add(req.Lifetime)
}
req.Template.Issuer = c.Issuer.Subject
req.Template.Issuer = c.CertificateChain[0].Subject
cert, err := x509util.CreateCertificate(req.Template, c.Issuer, req.Template.PublicKey, c.Signer)
cert, err := x509util.CreateCertificate(req.Template, c.CertificateChain[0], req.Template.PublicKey, c.Signer)
if err != nil {
return nil, err
}
return &apiv1.CreateCertificateResponse{
Certificate: cert,
CertificateChain: []*x509.Certificate{
c.Issuer,
},
CertificateChain: c.CertificateChain,
}, nil
}
@ -93,18 +91,16 @@ func (c *SoftCAS) RenewCertificate(req *apiv1.RenewCertificateRequest) (*apiv1.R
t := now()
req.Template.NotBefore = t.Add(-1 * req.Backdate)
req.Template.NotAfter = t.Add(req.Lifetime)
req.Template.Issuer = c.Issuer.Subject
req.Template.Issuer = c.CertificateChain[0].Subject
cert, err := x509util.CreateCertificate(req.Template, c.Issuer, req.Template.PublicKey, c.Signer)
cert, err := x509util.CreateCertificate(req.Template, c.CertificateChain[0], req.Template.PublicKey, c.Signer)
if err != nil {
return nil, err
}
return &apiv1.RenewCertificateResponse{
Certificate: cert,
CertificateChain: []*x509.Certificate{
c.Issuer,
},
CertificateChain: c.CertificateChain,
}, nil
}
@ -114,9 +110,7 @@ func (c *SoftCAS) RenewCertificate(req *apiv1.RenewCertificateRequest) (*apiv1.R
func (c *SoftCAS) RevokeCertificate(req *apiv1.RevokeCertificateRequest) (*apiv1.RevokeCertificateResponse, error) {
return &apiv1.RevokeCertificateResponse{
Certificate: req.Certificate,
CertificateChain: []*x509.Certificate{
c.Issuer,
},
CertificateChain: c.CertificateChain,
}, nil
}

View file

@ -182,9 +182,9 @@ func TestNew(t *testing.T) {
want *SoftCAS
wantErr bool
}{
{"ok", args{context.Background(), apiv1.Options{Issuer: testIssuer, Signer: testSigner}}, &SoftCAS{Issuer: testIssuer, Signer: testSigner}, false},
{"ok", args{context.Background(), apiv1.Options{CertificateChain: []*x509.Certificate{testIssuer}, Signer: testSigner}}, &SoftCAS{CertificateChain: []*x509.Certificate{testIssuer}, Signer: testSigner}, false},
{"fail no issuer", args{context.Background(), apiv1.Options{Signer: testSigner}}, nil, true},
{"fail no signer", args{context.Background(), apiv1.Options{Issuer: testIssuer}}, nil, true},
{"fail no signer", args{context.Background(), apiv1.Options{CertificateChain: []*x509.Certificate{testIssuer}}}, nil, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -208,11 +208,11 @@ func TestNew_register(t *testing.T) {
}
want := &SoftCAS{
Issuer: testIssuer,
CertificateChain: []*x509.Certificate{testIssuer},
Signer: testSigner,
}
got, err := newFn(context.Background(), apiv1.Options{Issuer: testIssuer, Signer: testSigner})
got, err := newFn(context.Background(), apiv1.Options{CertificateChain: []*x509.Certificate{testIssuer}, Signer: testSigner})
if err != nil {
t.Errorf("New() error = %v", err)
return
@ -286,7 +286,7 @@ func TestSoftCAS_CreateCertificate(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &SoftCAS{
Issuer: tt.fields.Issuer,
CertificateChain: []*x509.Certificate{tt.fields.Issuer},
Signer: tt.fields.Signer,
}
got, err := c.CreateCertificate(tt.args.req)
@ -342,7 +342,7 @@ func TestSoftCAS_RenewCertificate(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &SoftCAS{
Issuer: tt.fields.Issuer,
CertificateChain: []*x509.Certificate{tt.fields.Issuer},
Signer: tt.fields.Signer,
}
got, err := c.RenewCertificate(tt.args.req)
@ -395,7 +395,7 @@ func TestSoftCAS_RevokeCertificate(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &SoftCAS{
Issuer: tt.fields.Issuer,
CertificateChain: []*x509.Certificate{tt.fields.Issuer},
Signer: tt.fields.Signer,
}
got, err := c.RevokeCertificate(tt.args.req)
@ -524,7 +524,7 @@ func TestSoftCAS_CreateCertificateAuthority(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &SoftCAS{
Issuer: tt.fields.Issuer,
CertificateChain: []*x509.Certificate{tt.fields.Issuer},
Signer: tt.fields.Signer,
KeyManager: tt.fields.KeyManager,
}