mirror of
https://github.com/smallstep/certificates.git
synced 2024-11-19 09:25:37 +00:00
Merge pull request #1553 from smallstep/herman/change-scep-authority-initialization
Change SCEP authority initialization
This commit is contained in:
commit
f505acbaa3
@ -62,6 +62,8 @@ type Authority struct {
|
||||
x509Enforcers []provisioner.CertificateEnforcer
|
||||
|
||||
// SCEP CA
|
||||
scepOptions *scep.Options
|
||||
validateSCEP bool
|
||||
scepAuthority *scep.Authority
|
||||
|
||||
// SSH CA
|
||||
@ -123,6 +125,7 @@ func New(cfg *config.Config, opts ...Option) (*Authority, error) {
|
||||
var a = &Authority{
|
||||
config: cfg,
|
||||
certificates: new(sync.Map),
|
||||
validateSCEP: true,
|
||||
}
|
||||
|
||||
// Apply options.
|
||||
@ -671,54 +674,57 @@ func (a *Authority) init() error {
|
||||
// update that.
|
||||
switch {
|
||||
case a.requiresSCEP() && a.GetSCEP() == nil:
|
||||
var options scep.Options
|
||||
options.Roots = a.rootX509Certs
|
||||
options.Intermediates, err = pemutil.ReadCertificateBundle(a.config.IntermediateCert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options.SignerCert = options.Intermediates[0]
|
||||
if options.Signer, err = a.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{
|
||||
SigningKey: a.config.IntermediateKey,
|
||||
Password: a.password,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO(hs): instead of creating the decrypter here, pass the
|
||||
// intermediate key + chain down to the SCEP authority,
|
||||
// and only instantiate it when required there. Is that possible?
|
||||
// Also with entering passwords?
|
||||
// TODO(hs): if moving the logic, try improving the logic for the
|
||||
// decrypter password too? Right now it needs to be entered multiple
|
||||
// times; I've observed it to be three times maximum, every time
|
||||
// the intermediate key is read.
|
||||
_, isRSA := options.Signer.Public().(*rsa.PublicKey)
|
||||
if km, ok := a.keyManager.(kmsapi.Decrypter); ok && isRSA {
|
||||
if decrypter, err := km.CreateDecrypter(&kmsapi.CreateDecrypterRequest{
|
||||
DecryptionKey: a.config.IntermediateKey,
|
||||
Password: a.password,
|
||||
}); err == nil {
|
||||
// only pass the decrypter down when it was successfully created,
|
||||
// meaning it's an RSA key, and `CreateDecrypter` did not fail.
|
||||
options.Decrypter = decrypter
|
||||
options.DecrypterCert = options.Intermediates[0]
|
||||
if a.scepOptions == nil {
|
||||
options := &scep.Options{
|
||||
Roots: a.rootX509Certs,
|
||||
Intermediates: a.intermediateX509Certs,
|
||||
SignerCert: a.intermediateX509Certs[0],
|
||||
}
|
||||
if options.Signer, err = a.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{
|
||||
SigningKey: a.config.IntermediateKey,
|
||||
Password: a.password,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO(hs): instead of creating the decrypter here, pass the
|
||||
// intermediate key + chain down to the SCEP authority,
|
||||
// and only instantiate it when required there. Is that possible?
|
||||
// Also with entering passwords?
|
||||
// TODO(hs): if moving the logic, try improving the logic for the
|
||||
// decrypter password too? Right now it needs to be entered multiple
|
||||
// times; I've observed it to be three times maximum, every time
|
||||
// the intermediate key is read.
|
||||
_, isRSA := options.Signer.Public().(*rsa.PublicKey)
|
||||
if km, ok := a.keyManager.(kmsapi.Decrypter); ok && isRSA {
|
||||
if decrypter, err := km.CreateDecrypter(&kmsapi.CreateDecrypterRequest{
|
||||
DecryptionKey: a.config.IntermediateKey,
|
||||
Password: a.password,
|
||||
}); err == nil {
|
||||
// only pass the decrypter down when it was successfully created,
|
||||
// meaning it's an RSA key, and `CreateDecrypter` did not fail.
|
||||
options.Decrypter = decrypter
|
||||
options.DecrypterCert = options.Intermediates[0]
|
||||
}
|
||||
}
|
||||
|
||||
a.scepOptions = options
|
||||
}
|
||||
|
||||
// provide the current SCEP provisioner names, so that the provisioners
|
||||
// can be validated when the CA is started.
|
||||
options.SCEPProvisionerNames = a.getSCEPProvisionerNames()
|
||||
a.scepOptions.SCEPProvisionerNames = a.getSCEPProvisionerNames()
|
||||
|
||||
// create a new SCEP authority
|
||||
scepAuthority, err := scep.New(a, options)
|
||||
scepAuthority, err := scep.New(a, *a.scepOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// validate the SCEP authority
|
||||
if err := scepAuthority.Validate(); err != nil {
|
||||
a.initLogf("failed validating SCEP authority: %v", err)
|
||||
if a.validateSCEP {
|
||||
// validate the SCEP authority
|
||||
if err := scepAuthority.Validate(); err != nil {
|
||||
a.initLogf("failed validating SCEP authority: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// set the SCEP authority
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"github.com/smallstep/certificates/cas"
|
||||
casapi "github.com/smallstep/certificates/cas/apiv1"
|
||||
"github.com/smallstep/certificates/db"
|
||||
"github.com/smallstep/certificates/scep"
|
||||
)
|
||||
|
||||
// Option sets options to the Authority.
|
||||
@ -205,6 +206,17 @@ func WithX509SignerFunc(fn func() ([]*x509.Certificate, crypto.Signer, error)) O
|
||||
}
|
||||
}
|
||||
|
||||
// WithFullSCEPOptions defines the options used for SCEP support.
|
||||
//
|
||||
// This feature is EXPERIMENTAL and might change at any time.
|
||||
func WithFullSCEPOptions(options *scep.Options) Option {
|
||||
return func(a *Authority) error {
|
||||
a.scepOptions = options
|
||||
a.validateSCEP = false
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithSSHUserSigner defines the signer used to sign SSH user certificates.
|
||||
func WithSSHUserSigner(s crypto.Signer) Option {
|
||||
return func(a *Authority) error {
|
||||
|
Loading…
Reference in New Issue
Block a user