Clarify some SCEP properties

pull/1523/head
Herman Slatman 10 months ago
parent 70626b157d
commit e2e9bf5494
No known key found for this signature in database
GPG Key ID: F4D8A44EA0A75A4F

@ -702,6 +702,7 @@ func (a *Authority) init() error {
// only pass the decrypter down when it was successfully created, // only pass the decrypter down when it was successfully created,
// meaning it's an RSA key, and `CreateDecrypter` did not fail. // meaning it's an RSA key, and `CreateDecrypter` did not fail.
options.Decrypter = decrypter options.Decrypter = decrypter
options.DecrypterCert = options.Intermediates[0]
} }
} }

@ -57,6 +57,7 @@ type SCEP struct {
decrypter crypto.Decrypter decrypter crypto.Decrypter
decrypterCertificate *x509.Certificate decrypterCertificate *x509.Certificate
signer crypto.Signer signer crypto.Signer
signerCertificate *x509.Certificate
} }
// GetID returns the provisioner unique identifier. // GetID returns the provisioner unique identifier.
@ -246,6 +247,8 @@ func (s *SCEP) Init(config Config) (err error) {
if s.decrypterCertificate, err = x509.ParseCertificate(block.Bytes); err != nil { if s.decrypterCertificate, err = x509.ParseCertificate(block.Bytes); err != nil {
return fmt.Errorf("failed parsing decrypter certificate: %w", err) return fmt.Errorf("failed parsing decrypter certificate: %w", err)
} }
// the decrypter certificate is also the signer certificate
s.signerCertificate = s.decrypterCertificate
} }
// TODO(hs): alternatively, check if the KMS keyManager is a CertificateManager // TODO(hs): alternatively, check if the KMS keyManager is a CertificateManager
@ -361,5 +364,5 @@ func (s *SCEP) GetDecrypter() (*x509.Certificate, crypto.Decrypter) {
// of a crypto.Signer and a certificate for the public key // of a crypto.Signer and a certificate for the public key
// corresponding to the private key. // corresponding to the private key.
func (s *SCEP) GetSigner() (*x509.Certificate, crypto.Signer) { func (s *SCEP) GetSigner() (*x509.Certificate, crypto.Signer) {
return s.decrypterCertificate, s.signer return s.signerCertificate, s.signer
} }

@ -22,9 +22,10 @@ type Authority struct {
signAuth SignAuthority signAuth SignAuthority
roots []*x509.Certificate roots []*x509.Certificate
intermediates []*x509.Certificate intermediates []*x509.Certificate
signerCertificate *x509.Certificate
defaultSigner crypto.Signer defaultSigner crypto.Signer
signerCertificate *x509.Certificate
defaultDecrypter crypto.Decrypter defaultDecrypter crypto.Decrypter
decrypterCertificate *x509.Certificate
scepProvisionerNames []string scepProvisionerNames []string
mu sync.RWMutex mu sync.RWMutex
@ -64,16 +65,17 @@ func New(signAuth SignAuthority, opts Options) (*Authority, error) {
if err := opts.Validate(); err != nil { if err := opts.Validate(); err != nil {
return nil, err return nil, err
} }
authority := &Authority{
return &Authority{
signAuth: signAuth, // TODO: provide signAuth through context instead? signAuth: signAuth, // TODO: provide signAuth through context instead?
roots: opts.Roots, roots: opts.Roots,
intermediates: opts.Intermediates, intermediates: opts.Intermediates,
signerCertificate: opts.SignerCert,
defaultSigner: opts.Signer, defaultSigner: opts.Signer,
signerCertificate: opts.SignerCert,
defaultDecrypter: opts.Decrypter, defaultDecrypter: opts.Decrypter,
decrypterCertificate: opts.SignerCert, // the intermediate signer cert is also the decrypter cert (if RSA)
scepProvisionerNames: opts.SCEPProvisionerNames, scepProvisionerNames: opts.SCEPProvisionerNames,
} }, nil
return authority, nil
} }
// Validate validates if the SCEP Authority has a valid configuration. // Validate validates if the SCEP Authority has a valid configuration.
@ -181,12 +183,12 @@ func (a *Authority) DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) err
return fmt.Errorf("error parsing pkcs7 content: %w", err) return fmt.Errorf("error parsing pkcs7 content: %w", err)
} }
cert, pkey, err := a.selectDecrypter(ctx) cert, decrypter, err := a.selectDecrypter(ctx)
if err != nil { if err != nil {
return fmt.Errorf("failed selecting decrypter: %w", err) return fmt.Errorf("failed selecting decrypter: %w", err)
} }
envelope, err := p7c.Decrypt(cert, pkey) envelope, err := p7c.Decrypt(cert, decrypter)
if err != nil { if err != nil {
return fmt.Errorf("error decrypting encrypted pkcs7 content: %w", err) return fmt.Errorf("error decrypting encrypted pkcs7 content: %w", err)
} }
@ -209,7 +211,7 @@ func (a *Authority) DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) err
if err := csr.CheckSignature(); err != nil { if err := csr.CheckSignature(); err != nil {
return fmt.Errorf("invalid CSR signature; %w", err) return fmt.Errorf("invalid CSR signature; %w", err)
} }
// check for challengePassword // extract the challenge password
cp, err := microx509util.ParseChallengePassword(msg.pkiEnvelope) cp, err := microx509util.ParseChallengePassword(msg.pkiEnvelope)
if err != nil { if err != nil {
return fmt.Errorf("parse challenge password in pkiEnvelope: %w", err) return fmt.Errorf("parse challenge password in pkiEnvelope: %w", err)
@ -484,46 +486,46 @@ func (a *Authority) ValidateChallenge(ctx context.Context, challenge, transactio
return p.ValidateChallenge(ctx, challenge, transactionID) return p.ValidateChallenge(ctx, challenge, transactionID)
} }
func (a *Authority) selectDecrypter(ctx context.Context) (cert *x509.Certificate, pkey crypto.Decrypter, err error) { func (a *Authority) selectDecrypter(ctx context.Context) (cert *x509.Certificate, decrypter crypto.Decrypter, err error) {
p := provisionerFromContext(ctx) p := provisionerFromContext(ctx)
cert, pkey = p.GetDecrypter() cert, decrypter = p.GetDecrypter()
switch { switch {
case cert != nil && pkey != nil: case cert != nil && decrypter != nil:
return return
case cert == nil && pkey != nil: case cert == nil && decrypter != nil:
return nil, nil, fmt.Errorf("provisioner %q does not have a decrypter certificate available", p.GetName()) return nil, nil, fmt.Errorf("provisioner %q does not have a decrypter certificate available", p.GetName())
case cert != nil && pkey == nil: case cert != nil && decrypter == nil:
return nil, nil, fmt.Errorf("provisioner %q does not have a decrypter available", p.GetName()) return nil, nil, fmt.Errorf("provisioner %q does not have a decrypter available", p.GetName())
} }
cert, pkey = a.signerCertificate, a.defaultDecrypter cert, decrypter = a.decrypterCertificate, a.defaultDecrypter
switch { switch {
case cert == nil && pkey != nil: case cert == nil && decrypter != nil:
return nil, nil, fmt.Errorf("provisioner %q does not have a default decrypter certificate available", p.GetName()) return nil, nil, fmt.Errorf("provisioner %q does not have a default decrypter certificate available", p.GetName())
case cert != nil && pkey == nil: case cert != nil && decrypter == nil:
return nil, nil, fmt.Errorf("provisioner %q does not have a default decrypter available", p.GetName()) return nil, nil, fmt.Errorf("provisioner %q does not have a default decrypter available", p.GetName())
} }
return return
} }
func (a *Authority) selectSigner(ctx context.Context) (cert *x509.Certificate, pkey crypto.PrivateKey, err error) { func (a *Authority) selectSigner(ctx context.Context) (cert *x509.Certificate, signer crypto.Signer, err error) {
p := provisionerFromContext(ctx) p := provisionerFromContext(ctx)
cert, pkey = p.GetSigner() cert, signer = p.GetSigner()
switch { switch {
case cert != nil && pkey != nil: case cert != nil && signer != nil:
return return
case cert == nil && pkey != nil: case cert == nil && signer != nil:
return nil, nil, fmt.Errorf("provisioner %q does not have a signer certificate available", p.GetName()) return nil, nil, fmt.Errorf("provisioner %q does not have a signer certificate available", p.GetName())
case cert != nil && pkey == nil: case cert != nil && signer == nil:
return nil, nil, fmt.Errorf("provisioner %q does not have a signer available", p.GetName()) return nil, nil, fmt.Errorf("provisioner %q does not have a signer available", p.GetName())
} }
cert, pkey = a.signerCertificate, a.defaultSigner cert, signer = a.signerCertificate, a.defaultSigner
switch { switch {
case cert == nil && pkey != nil: case cert == nil && signer != nil:
return nil, nil, fmt.Errorf("provisioner %q does not have a default signer certificate available", p.GetName()) return nil, nil, fmt.Errorf("provisioner %q does not have a default signer certificate available", p.GetName())
case cert != nil && pkey == nil: case cert != nil && signer == nil:
return nil, nil, fmt.Errorf("provisioner %q does not have a default signer available", p.GetName()) return nil, nil, fmt.Errorf("provisioner %q does not have a default signer available", p.GetName())
} }

@ -20,6 +20,8 @@ type Options struct {
Signer crypto.Signer `json:"-"` Signer crypto.Signer `json:"-"`
// Decrypter decrypts encrypted SCEP messages. Configured in the ca.json key property. // Decrypter decrypts encrypted SCEP messages. Configured in the ca.json key property.
Decrypter crypto.Decrypter `json:"-"` Decrypter crypto.Decrypter `json:"-"`
// DecrypterCert points to the certificate of the CA decrypter.
DecrypterCert *x509.Certificate `json:"-"`
// SCEPProvisionerNames contains the currently configured SCEP provioner names. These // SCEPProvisionerNames contains the currently configured SCEP provioner names. These
// are used to be able to load the provisioners when the SCEP authority is being // are used to be able to load the provisioners when the SCEP authority is being
// validated. // validated.

Loading…
Cancel
Save