Improve initialization of SCEP authority

This commit is contained in:
Herman Slatman 2021-03-12 15:49:39 +01:00
parent 8c5b12e21d
commit e1cab4966f
No known key found for this signature in database
GPG key ID: F4D8A44EA0A75A4F
5 changed files with 57 additions and 42 deletions

View file

@ -234,10 +234,12 @@ func (a *Authority) init() error {
} }
} }
a.scepService = &scep.Service{ a.scepService, err = scep.NewService(context.Background(), options)
Signer: options.Signer, if err != nil {
Decrypter: options.Decrypter, return err
} }
// TODO: mimick the x509CAService GetCertificateAuthority here too?
} }
// Read root certificates and store them in the certificates map. // Read root certificates and store them in the certificates map.

View file

@ -151,12 +151,11 @@ func (ca *CA) Init(config *authority.Config) (*CA, error) {
scepPrefix := "scep" scepPrefix := "scep"
scepAuthority, err := scep.New(auth, scep.AuthorityOptions{ scepAuthority, err := scep.New(auth, scep.AuthorityOptions{
IntermediateCertificatePath: config.IntermediateCert, Service: auth.GetSCEPService(),
Service: auth.GetSCEPService(), Backdate: *config.AuthorityConfig.Backdate,
Backdate: *config.AuthorityConfig.Backdate, DB: auth.GetDatabase().(nosql.DB),
DB: auth.GetDatabase().(nosql.DB), DNS: dns,
DNS: dns, Prefix: scepPrefix,
Prefix: scepPrefix,
}) })
if err != nil { if err != nil {
return nil, errors.Wrap(err, "error creating SCEP authority") return nil, errors.Wrap(err, "error creating SCEP authority")
@ -358,13 +357,13 @@ func (ca *CA) getTLSConfig(auth *authority.Authority) (*tls.Config, error) {
return tlsConfig, nil return tlsConfig, nil
} }
func dumpRoutes(mux chi.Routes) { // func dumpRoutes(mux chi.Routes) {
// helpful routine for logging all routes // // // helpful routine for logging all routes //
walkFunc := func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error { // walkFunc := func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error {
fmt.Printf("%s %s\n", method, route) // fmt.Printf("%s %s\n", method, route)
return nil // return nil
} // }
if err := chi.Walk(mux, walkFunc); err != nil { // if err := chi.Walk(mux, walkFunc); err != nil {
fmt.Printf("Logging err: %s\n", err.Error()) // fmt.Printf("Logging err: %s\n", err.Error())
} // }
} // }

View file

@ -18,7 +18,7 @@ func Register(t Type, fn CertificateAuthorityServiceNewFunc) {
registry.Store(t.String(), fn) registry.Store(t.String(), fn)
} }
// LoadCertificateAuthorityServiceNewFunc returns the function initialize a KayManager. // LoadCertificateAuthorityServiceNewFunc returns the function to initialize a KeyManager.
func LoadCertificateAuthorityServiceNewFunc(t Type) (CertificateAuthorityServiceNewFunc, bool) { func LoadCertificateAuthorityServiceNewFunc(t Type) (CertificateAuthorityServiceNewFunc, bool) {
v, ok := registry.Load(t.String()) v, ok := registry.Load(t.String())
if !ok { if !ok {

View file

@ -11,8 +11,6 @@ import (
"github.com/smallstep/certificates/authority/provisioner" "github.com/smallstep/certificates/authority/provisioner"
database "github.com/smallstep/certificates/db" database "github.com/smallstep/certificates/db"
"go.step.sm/crypto/pemutil"
"github.com/smallstep/nosql" "github.com/smallstep/nosql"
microx509util "github.com/micromdm/scep/crypto/x509util" microx509util "github.com/micromdm/scep/crypto/x509util"
@ -59,10 +57,8 @@ type Authority struct {
// AuthorityOptions required to create a new SCEP Authority. // AuthorityOptions required to create a new SCEP Authority.
type AuthorityOptions struct { type AuthorityOptions struct {
IntermediateCertificatePath string // Service provides the SCEP functions to Authority
Service Service Service Service
// Backdate // Backdate
Backdate provisioner.Duration Backdate provisioner.Duration
// DB is the database used by nosql. // DB is the database used by nosql.
@ -96,21 +92,12 @@ func New(signAuth SignAuthority, ops AuthorityOptions) (*Authority, error) {
} }
} }
// TODO: the below is a bit similar as what happens in the core Authority class, which
// creates the full x509 service. However, those aren't accessible directly, which is
// why I reimplemented this (for now). There might be an alternative that I haven't
// found yet.
certificateChain, err := pemutil.ReadCertificateBundle(ops.IntermediateCertificatePath)
if err != nil {
return nil, err
}
return &Authority{ return &Authority{
backdate: ops.Backdate, backdate: ops.Backdate,
db: ops.DB, db: ops.DB,
prefix: ops.Prefix, prefix: ops.Prefix,
dns: ops.DNS, dns: ops.DNS,
intermediateCertificate: certificateChain[0], intermediateCertificate: ops.Service.certificateChain[0],
service: ops.Service, service: ops.Service,
signAuth: signAuth, signAuth: signAuth,
}, nil }, nil
@ -208,7 +195,7 @@ func (a *Authority) DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) err
return err return err
} }
envelope, err := p7c.Decrypt(a.intermediateCertificate, a.service.Decrypter) envelope, err := p7c.Decrypt(a.intermediateCertificate, a.service.decrypter)
if err != nil { if err != nil {
return err return err
} }
@ -351,7 +338,7 @@ func (a *Authority) SignCSR(ctx context.Context, csr *x509.CertificateRequest, m
authCert := a.intermediateCertificate authCert := a.intermediateCertificate
// sign the attributes // sign the attributes
if err := signedData.AddSigner(authCert, a.service.Signer, config); err != nil { if err := signedData.AddSigner(authCert, a.service.signer, config); err != nil {
return nil, err return nil, err
} }
@ -430,7 +417,7 @@ func (a *Authority) CreateFailureResponse(ctx context.Context, csr *x509.Certifi
} }
// sign the attributes // sign the attributes
if err := signedData.AddSigner(a.intermediateCertificate, a.service.Signer, config); err != nil { if err := signedData.AddSigner(a.intermediateCertificate, a.service.signer, config); err != nil {
return nil, err return nil, err
} }

View file

@ -1,9 +1,36 @@
package scep package scep
import "crypto" import (
"context"
"crypto"
"crypto/x509"
"strings"
// Service is a (temporary?) wrapper for signer/decrypters "github.com/smallstep/certificates/cas/apiv1"
)
// Service is a wrapper for crypto.Signer and crypto.Decrypter
type Service struct { type Service struct {
Signer crypto.Signer certificateChain []*x509.Certificate
Decrypter crypto.Decrypter signer crypto.Signer
decrypter crypto.Decrypter
}
func NewService(ctx context.Context, opts apiv1.Options) (*Service, error) {
if err := opts.Validate(); err != nil {
return nil, err
}
t := apiv1.Type(strings.ToLower(opts.Type))
if t == apiv1.DefaultCAS {
t = apiv1.SoftCAS
}
// TODO: should this become similar to the New CertificateAuthorityService as in x509CAService?
return &Service{
chain: opts.CertificateChain,
signer: opts.Signer,
decrypter: opts.Decrypter,
}, nil
} }