Compare commits

...

46 Commits

Author SHA1 Message Date
Herman Slatman 7426edb6d7
Merge branch 'master' into wire-acme-extensions 2 weeks ago
Herman Slatman d6bf551f87
Merge pull request #1803 from smallstep/herman/fix-scep-vault-ra
Fix CA startup with Vault RA configuration
2 weeks ago
github-actions[bot] f4d506f659
Merge pull request #1811 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api-1.13.0
Bump github.com/hashicorp/vault/api from 1.12.2 to 1.13.0
2 weeks ago
Herman Slatman 1e5e267b2b
Remove leftover debug print 2 weeks ago
max furman 760014c64b
go mod tidy 2 weeks ago
Herman Slatman 2561a7271e
Dedupe CA and SCEP client creation logic 2 weeks ago
dependabot[bot] 39653050dc
Bump github.com/hashicorp/vault/api from 1.12.2 to 1.13.0
Bumps [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) from 1.12.2 to 1.13.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v1.12.2...v1.13.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 weeks ago
github-actions[bot] 65cfee56df
Merge pull request #1810 from smallstep/dependabot/go_modules/google.golang.org/api-0.176.0
Bump google.golang.org/api from 0.172.0 to 0.176.0
2 weeks ago
dependabot[bot] 8d4effcce8
Bump google.golang.org/api from 0.172.0 to 0.176.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.172.0 to 0.176.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.172.0...v0.176.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 weeks ago
github-actions[bot] 4a375592d3
Merge pull request #1809 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.44.6
Bump go.step.sm/crypto from 0.44.4 to 0.44.6
2 weeks ago
github-actions[bot] d7ed03124f
Merge pull request #1808 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.16.0
Bump cloud.google.com/go/security from 1.15.6 to 1.16.0
2 weeks ago
Herman Slatman 87202001a8
Rewrite SCEP integration tests to only use the HTTPS endpoint 2 weeks ago
dependabot[bot] 57a6b85388
Bump go.step.sm/crypto from 0.44.4 to 0.44.6
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.44.4 to 0.44.6.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.44.4...v0.44.6)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 weeks ago
dependabot[bot] 0ba61c58e8
Bump cloud.google.com/go/security from 1.15.6 to 1.16.0
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.15.6 to 1.16.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/kms/v1.15.6...asset/v1.16.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 weeks ago
Herman Slatman b0fabe1346
Add some SCEP integration tests 2 weeks ago
Herman Slatman 113a6dd8ab
Remove reporting the CA mode from startup logs 3 weeks ago
Herman Slatman 6bc0a86207
Fix CA startup with Vault RA configuration 3 weeks ago
Herman Slatman 07279dd248
Merge pull request #1801 from smallstep/herman/upgrade-crypto-v0.44.4
Upgrade `go.step.sm/crypto` to `v0.44.4`
3 weeks ago
Herman Slatman 4c6b0b318e
Upgrade `go.step.sm/crypto` to `v0.44.4` 3 weeks ago
Herman Slatman f1a2c68f43
Merge pull request #1798 from smallstep/herman/fix-instrumented-key-manager
Add support for `kmsapi.Decrypter` to instrumented key manager
3 weeks ago
Mariano Cano 7df3ad05ed
Merge pull request #1797 from smallstep/mariano/init-scep
Allow custom SCEP key manager
4 weeks ago
Mariano Cano 4202d6673c
Remove debug statement 4 weeks ago
Herman Slatman d6bbe5b06b
Add support for `kmsapi.Decrypter` to instrumented key manager 4 weeks ago
Herman Slatman 721345eea6
Merge pull request #1793 from verytrap/master
chore: fix function names in comment
4 weeks ago
verytrap db92404342 chore: fix function names in comment
Signed-off-by: verytrap <wangqiuyue@outlook.com>
4 weeks ago
Mariano Cano 725a913f66
Allow custom SCEP key manager
This commit allows to inject a custom key manger for SCEP.
4 weeks ago
Herman Slatman 397877a7b6
Merge pull request #1795 from smallstep/herman/fix-scep-failinfo-oid
Prevent exposing any internal details in SCEP failure message
4 weeks ago
Herman Slatman b226b6eb4c
Prevent exposing any internal details in SCEP failure message
To be on the safe side, block errors from signing operations from
being returned to the client. We should revisit, and make it return
a more informative error, but with high assurance that no sensitive
information is added to the message.
4 weeks ago
Herman Slatman 02956ad0e3
Merge pull request #1794 from smallstep/herman/fix-scep-failinfo-oid
Fix the `id-scep-failInfoText` OID
4 weeks ago
Herman Slatman 037554e774
Fix the `id-scep-failInfoText` OID 4 weeks ago
github-actions[bot] 1513152cb2
Merge pull request #1791 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.32.0
Bump github.com/newrelic/go-agent/v3 from 3.31.0 to 3.32.0
4 weeks ago
dependabot[bot] c9ba31ae61
Bump github.com/newrelic/go-agent/v3 from 3.31.0 to 3.32.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.31.0 to 3.32.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.31.0...v3.32.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 weeks ago
github-actions[bot] 1f69ff84a1
Merge pull request #1792 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.63.2
Bump google.golang.org/grpc from 1.62.1 to 1.63.2
4 weeks ago
dependabot[bot] a76f07143b
Bump google.golang.org/grpc from 1.62.1 to 1.63.2
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.62.1 to 1.63.2.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.62.1...v1.63.2)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 weeks ago
github-actions[bot] 08ef9fe245
Merge pull request #1789 from smallstep/dependabot/go_modules/golang.org/x/net-0.24.0
Bump golang.org/x/net from 0.22.0 to 0.24.0
4 weeks ago
dependabot[bot] 57d628513b
Bump golang.org/x/net from 0.22.0 to 0.24.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.22.0 to 0.24.0.
- [Commits](https://github.com/golang/net/compare/v0.22.0...v0.24.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 month ago
github-actions[bot] d5758ba3a3
Merge pull request #1784 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.31.0
Bump github.com/newrelic/go-agent/v3 from 3.30.0 to 3.31.0
1 month ago
github-actions[bot] 166c4968cf
Merge pull request #1785 from smallstep/dependabot/go_modules/google.golang.org/api-0.172.0
Bump google.golang.org/api from 0.171.0 to 0.172.0
1 month ago
Carl Tashian 1be0932a0f
Merge pull request #1786 from smallstep/carl/winget-fix
Fix winget release notes URL
1 month ago
Carl Tashian f04a5e39c4
Fix winget release URL 1 month ago
dependabot[bot] d1523c93bc
Bump google.golang.org/api from 0.171.0 to 0.172.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.171.0 to 0.172.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.171.0...v0.172.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 month ago
dependabot[bot] 44c48a7494
Bump github.com/newrelic/go-agent/v3 from 3.30.0 to 3.31.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.30.0 to 3.31.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.30.0...v3.31.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 month ago
Carl Tashian 188e4e3ff3
Add version number to winget branch name (#1783) 1 month ago
Max 395a3eeb93
Update go.step.sm/crypto (#1781) 1 month ago
Herman Slatman 4772d7cc28
Merge pull request #1780 from smallstep/herman/update-changelog-20240328
Update changelog for `v0.26.0` release
1 month ago
Herman Slatman 854288a0cb
Update changelog for `v0.26.0` release 1 month ago

@ -268,7 +268,7 @@ winget:
# Release notes URL.
#
# Templates: allowed
release_notes_url: "https://github.com/smallstep/certificates/releases/tag/{{.Version}}"
release_notes_url: "https://github.com/smallstep/certificates/releases/tag/{{ .Tag }}"
# Create the PR - for testing
skip_upload: auto
@ -283,7 +283,7 @@ winget:
repository:
owner: smallstep
name: winget-pkgs
branch: step
branch: "step-ca-{{.Version}}"
# Optionally a token can be provided, if it differs from the token
# provided to GoReleaser

@ -25,6 +25,35 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
---
## [0.26.0] - 2024-03-28
### Added
- [TPM KMS](https://github.com/smallstep/crypto/tree/master/kms/tpmkms) support for CA keys (smallstep/certificates#1772)
- Propagation of HTTP request identifier using X-Request-Id header (smallstep/certificates#1743, smallstep/certificates#1542)
- Expires header in CRL response (smallstep/certificates#1708)
- Support for providing TLS configuration programmatically (smallstep/certificates#1685)
- Support for providing external CAS implementation (smallstep/certificates#1684)
- AWS `ca-west-1` identity document root certificate (smallstep/certificates#1715)
- [COSE RS1](https://www.rfc-editor.org/rfc/rfc8812.html#section-2) as a supported algorithm with ACME `device-attest-01` challenge (smallstep/certificates#1663)
### Changed
- In an RA setup, let the CA decide the RA certificate lifetime (smallstep/certificates#1764)
- Use Debian Bookworm in Docker containers (smallstep/certificates#1615)
- Error message for CSR validation (smallstep/certificates#1665)
- Updated dependencies
### Fixed
- Stop CA when any of the required servers fails to start (smallstep/certificates#1751). Before the fix, the CA would continue running and only log the server failure when stopped.
- Configuration loading errors when not using context were not returned. Fixed in [cli-utils/109](https://github.com/smallstep/cli-utils/pull/109).
- HTTP_PROXY and HTTPS_PROXY support for ACME validation client (smallstep/certificates#1658).
### Security
- Upgrade to using cosign v2 for signing artifacts
## [0.25.1] - 2023-11-28
### Added

@ -1117,7 +1117,7 @@ var (
oidTCGKpAIKCertificate = asn1.ObjectIdentifier{2, 23, 133, 8, 3}
)
// validateAKCertifiate validates the X.509 AK certificate to be
// validateAKCertificate validates the X.509 AK certificate to be
// in accordance with the required properties. The requirements come from:
// https://www.w3.org/TR/webauthn-2/#sctn-tpm-cert-requirements.
//
@ -1126,7 +1126,7 @@ var (
// - The Subject Alternative Name extension MUST be set as defined
// in [TPMv2-EK-Profile] section 3.2.9.
// - The Extended Key Usage extension MUST contain the OID 2.23.133.8.3
// ("joint-iso-itu-t(2) internationalorganizations(23) 133 tcg-kp(8) tcg-kp-AIKCertificate(3)").
// ("joint-iso-itu-t(2) international-organizations(23) 133 tcg-kp(8) tcg-kp-AIKCertificate(3)").
// - The Basic Constraints extension MUST have the CA component set to false.
// - An Authority Information Access (AIA) extension with entry id-ad-ocsp
// and a CRL Distribution Point extension [RFC5280] are both OPTIONAL as

@ -130,7 +130,7 @@ func (m *MockProvisioner) GetName() string {
return m.Mret1.(string)
}
// AuthorizeOrderIdentifiers mock
// AuthorizeOrderIdentifier mock
func (m *MockProvisioner) AuthorizeOrderIdentifier(ctx context.Context, identifier provisioner.ACMEIdentifier) error {
if m.MauthorizeOrderIdentifier != nil {
return m.MauthorizeOrderIdentifier(ctx, identifier)

@ -138,7 +138,7 @@ func (o *Order) UpdateStatus(ctx context.Context, db DB) error {
return nil
}
// getKeyFingerprint returns a fingerprint from the list of authorizations. This
// getAuthorizationFingerprint returns a fingerprint from the list of authorizations. This
// fingerprint is used on the device-attest-01 flow to verify the attestation
// certificate public key with the CSR public key.
//

@ -97,7 +97,7 @@ func (s *SCEP) AuthorizeSSHSign(context.Context, string) ([]provisioner.SignOpti
return nil, errDummyImplementation
}
// AuthorizeRevoke returns an unimplemented error. Provisioners should overwrite
// AuthorizeSSHRevoke returns an unimplemented error. Provisioners should overwrite
// this method if they will support authorizing tokens for revoking SSH Certificates.
func (s *SCEP) AuthorizeSSHRevoke(context.Context, string) error {
return errDummyImplementation

@ -35,7 +35,7 @@ type PolicyAdminResponder interface {
// policyAdminResponder implements PolicyAdminResponder.
type policyAdminResponder struct{}
// NewACMEAdminResponder returns a new PolicyAdminResponder.
// NewPolicyAdminResponder returns a new PolicyAdminResponder.
func NewPolicyAdminResponder() PolicyAdminResponder {
return &policyAdminResponder{}
}

@ -62,9 +62,10 @@ type Authority struct {
x509Enforcers []provisioner.CertificateEnforcer
// SCEP CA
scepOptions *scep.Options
validateSCEP bool
scepAuthority *scep.Authority
scepOptions *scep.Options
validateSCEP bool
scepAuthority *scep.Authority
scepKeyManager provisioner.SCEPKeyManager
// SSH CA
sshHostPassword []byte
@ -139,7 +140,7 @@ func New(cfg *config.Config, opts ...Option) (*Authority, error) {
}
}
if a.keyManager != nil {
a.keyManager = &instrumentedKeyManager{a.keyManager, a.meter}
a.keyManager = newInstrumentedKeyManager(a.keyManager, a.meter)
}
if !a.skipInit {
@ -168,7 +169,7 @@ func NewEmbedded(opts ...Option) (*Authority, error) {
}
}
if a.keyManager != nil {
a.keyManager = &instrumentedKeyManager{a.keyManager, a.meter}
a.keyManager = newInstrumentedKeyManager(a.keyManager, a.meter)
}
// Validate required options
@ -349,7 +350,7 @@ func (a *Authority) init() error {
return err
}
a.keyManager = &instrumentedKeyManager{a.keyManager, a.meter}
a.keyManager = newInstrumentedKeyManager(a.keyManager, a.meter)
}
// Initialize linkedca client if necessary. On a linked RA, the issuer
@ -446,6 +447,7 @@ func (a *Authority) init() error {
return err
}
a.rootX509Certs = append(a.rootX509Certs, resp.RootCertificate)
a.intermediateX509Certs = append(a.intermediateX509Certs, resp.IntermediateCertificates...)
}
}
@ -694,32 +696,42 @@ func (a *Authority) init() error {
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
// intermediate certificates can be empty in RA mode
if len(a.intermediateX509Certs) > 0 {
options.SignerCert = a.intermediateX509Certs[0]
}
// 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]
// attempt to create the (default) SCEP signer if the intermediate
// key is configured.
if a.config.IntermediateKey != "" {
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.
_, isRSAKey := options.Signer.Public().(*rsa.PublicKey)
if km, ok := a.keyManager.(kmsapi.Decrypter); ok && isRSAKey {
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]
}
}
}

@ -66,6 +66,22 @@ type instrumentedKeyManager struct {
meter Meter
}
type instrumentedKeyAndDecrypterManager struct {
kms.KeyManager
decrypter kmsapi.Decrypter
meter Meter
}
func newInstrumentedKeyManager(k kms.KeyManager, m Meter) kms.KeyManager {
decrypter, isDecrypter := k.(kmsapi.Decrypter)
switch {
case isDecrypter:
return &instrumentedKeyAndDecrypterManager{&instrumentedKeyManager{k, m}, decrypter, m}
default:
return &instrumentedKeyManager{k, m}
}
}
func (i *instrumentedKeyManager) CreateSigner(req *kmsapi.CreateSignerRequest) (s crypto.Signer, err error) {
if s, err = i.KeyManager.CreateSigner(req); err == nil {
s = &instrumentedKMSSigner{s, i.meter}
@ -74,6 +90,10 @@ func (i *instrumentedKeyManager) CreateSigner(req *kmsapi.CreateSignerRequest) (
return
}
func (i *instrumentedKeyAndDecrypterManager) CreateDecrypter(req *kmsapi.CreateDecrypterRequest) (s crypto.Decrypter, err error) {
return i.decrypter.CreateDecrypter(req)
}
type instrumentedKMSSigner struct {
crypto.Signer
meter Meter
@ -85,3 +105,7 @@ func (i *instrumentedKMSSigner) Sign(rand io.Reader, digest []byte, opts crypto.
return
}
var _ kms.KeyManager = (*instrumentedKeyManager)(nil)
var _ kms.KeyManager = (*instrumentedKeyAndDecrypterManager)(nil)
var _ kmsapi.Decrypter = (*instrumentedKeyAndDecrypterManager)(nil)

@ -226,6 +226,16 @@ func WithFullSCEPOptions(options *scep.Options) Option {
}
}
// WithSCEPKeyManager defines the key manager used on SCEP provisioners.
//
// This feature is EXPERIMENTAL and might change at any time.
func WithSCEPKeyManager(skm provisioner.SCEPKeyManager) Option {
return func(a *Authority) error {
a.scepKeyManager = skm
return nil
}
}
// WithSSHUserSigner defines the signer used to sign SSH user certificates.
func WithSSHUserSigner(s crypto.Signer) Option {
return func(a *Authority) error {

@ -10,6 +10,7 @@ import (
"strings"
"github.com/pkg/errors"
kmsapi "go.step.sm/crypto/kms/apiv1"
"golang.org/x/crypto/ssh"
"github.com/smallstep/certificates/errs"
@ -206,6 +207,13 @@ type SSHKeys struct {
HostKeys []ssh.PublicKey
}
// SCEPKeyManager is a KMS interface that combines a KeyManager with a
// Decrypter.
type SCEPKeyManager interface {
kmsapi.KeyManager
kmsapi.Decrypter
}
// Config defines the default parameters used in the initialization of
// provisioners.
type Config struct {
@ -226,6 +234,8 @@ type Config struct {
AuthorizeSSHRenewFunc AuthorizeSSHRenewFunc
// WebhookClient is an http client to use in webhook request
WebhookClient *http.Client
// SCEPKeyManager, if defined, is the interface used by SCEP provisioners.
SCEPKeyManager SCEPKeyManager
}
type provisioner struct {
@ -320,7 +330,7 @@ func (b *base) AuthorizeSSHSign(context.Context, string) ([]SignOption, error) {
return nil, errs.Unauthorized("provisioner.AuthorizeSSHSign not implemented")
}
// AuthorizeRevoke returns an unimplemented error. Provisioners should overwrite
// AuthorizeSSHRevoke returns an unimplemented error. Provisioners should overwrite
// this method if they will support authorizing tokens for revoking SSH Certificates.
func (b *base) AuthorizeSSHRevoke(context.Context, string) error {
return errs.Unauthorized("provisioner.AuthorizeSSHRevoke not implemented")

@ -15,7 +15,6 @@ import (
"go.step.sm/crypto/kms"
kmsapi "go.step.sm/crypto/kms/apiv1"
"go.step.sm/crypto/kms/uri"
"go.step.sm/linkedca"
"github.com/smallstep/certificates/webhook"
@ -59,7 +58,7 @@ type SCEP struct {
encryptionAlgorithm int
challengeValidationController *challengeValidationController
notificationController *notificationController
keyManager kmsapi.KeyManager
keyManager SCEPKeyManager
decrypter crypto.Decrypter
decrypterCertificate *x509.Certificate
signer crypto.Signer
@ -269,34 +268,38 @@ func (s *SCEP) Init(config Config) (err error) {
)
// parse the decrypter key PEM contents if available
if decryptionKeyPEM := s.DecrypterKeyPEM; len(decryptionKeyPEM) > 0 {
if len(s.DecrypterKeyPEM) > 0 {
// try reading the PEM for validation
block, rest := pem.Decode(decryptionKeyPEM)
block, rest := pem.Decode(s.DecrypterKeyPEM)
if len(rest) > 0 {
return errors.New("failed parsing decrypter key: trailing data")
}
if block == nil {
return errors.New("failed parsing decrypter key: no PEM block found")
}
opts := kms.Options{
Type: kmsapi.SoftKMS,
}
if s.keyManager, err = kms.New(context.Background(), opts); err != nil {
km, err := kms.New(context.Background(), opts)
if err != nil {
return fmt.Errorf("failed initializing kms: %w", err)
}
kmsDecrypter, ok := s.keyManager.(kmsapi.Decrypter)
scepKeyManager, ok := km.(SCEPKeyManager)
if !ok {
return fmt.Errorf("%q is not a kmsapi.Decrypter", opts.Type)
}
if s.decrypter, err = kmsDecrypter.CreateDecrypter(&kmsapi.CreateDecrypterRequest{
DecryptionKeyPEM: decryptionKeyPEM,
s.keyManager = scepKeyManager
if s.decrypter, err = s.keyManager.CreateDecrypter(&kmsapi.CreateDecrypterRequest{
DecryptionKeyPEM: s.DecrypterKeyPEM,
Password: []byte(s.DecrypterKeyPassword),
PasswordPrompter: kmsapi.NonInteractivePasswordPrompter,
}); err != nil {
return fmt.Errorf("failed creating decrypter: %w", err)
}
if s.signer, err = s.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{
SigningKeyPEM: decryptionKeyPEM, // TODO(hs): support distinct signer key in the future?
SigningKeyPEM: s.DecrypterKeyPEM, // TODO(hs): support distinct signer key in the future?
Password: []byte(s.DecrypterKeyPassword),
PasswordPrompter: kmsapi.NonInteractivePasswordPrompter,
}); err != nil {
@ -304,41 +307,44 @@ func (s *SCEP) Init(config Config) (err error) {
}
}
if decryptionKeyURI := s.DecrypterKeyURI; decryptionKeyURI != "" {
u, err := uri.Parse(s.DecrypterKeyURI)
if s.DecrypterKeyURI != "" {
kmsType, err := kmsapi.TypeOf(s.DecrypterKeyURI)
if err != nil {
return fmt.Errorf("failed parsing decrypter key: %w", err)
}
var kmsType kmsapi.Type
switch {
case u.Scheme != "":
kmsType = kms.Type(u.Scheme)
default:
kmsType = kmsapi.SoftKMS
}
opts := kms.Options{
Type: kmsType,
URI: s.DecrypterKeyURI,
}
if s.keyManager, err = kms.New(context.Background(), opts); err != nil {
return fmt.Errorf("failed initializing kms: %w", err)
}
kmsDecrypter, ok := s.keyManager.(kmsapi.Decrypter)
if !ok {
return fmt.Errorf("%q is not a kmsapi.Decrypter", opts.Type)
}
if kmsType != "softkms" { // TODO(hs): this should likely become more transparent?
decryptionKeyURI = u.Opaque
}
if s.decrypter, err = kmsDecrypter.CreateDecrypter(&kmsapi.CreateDecrypterRequest{
DecryptionKey: decryptionKeyURI,
if config.SCEPKeyManager != nil {
s.keyManager = config.SCEPKeyManager
} else {
if kmsType == kmsapi.DefaultKMS {
kmsType = kmsapi.SoftKMS
}
opts := kms.Options{
Type: kmsType,
URI: s.DecrypterKeyURI,
}
km, err := kms.New(context.Background(), opts)
if err != nil {
return fmt.Errorf("failed initializing kms: %w", err)
}
scepKeyManager, ok := km.(SCEPKeyManager)
if !ok {
return fmt.Errorf("%q is not a kmsapi.Decrypter", opts.Type)
}
s.keyManager = scepKeyManager
}
// Create decrypter and signer with the same key:
// TODO(hs): support distinct signer key in the future?
if s.decrypter, err = s.keyManager.CreateDecrypter(&kmsapi.CreateDecrypterRequest{
DecryptionKey: s.DecrypterKeyURI,
Password: []byte(s.DecrypterKeyPassword),
PasswordPrompter: kmsapi.NonInteractivePasswordPrompter,
}); err != nil {
return fmt.Errorf("failed creating decrypter: %w", err)
}
if s.signer, err = s.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{
SigningKey: decryptionKeyURI, // TODO(hs): support distinct signer key in the future?
SigningKey: s.DecrypterKeyURI,
Password: []byte(s.DecrypterKeyPassword),
PasswordPrompter: kmsapi.NonInteractivePasswordPrompter,
}); err != nil {

@ -2,19 +2,27 @@ package provisioner
import (
"context"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/json"
"encoding/pem"
"errors"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"github.com/smallstep/certificates/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.step.sm/crypto/kms/softkms"
"go.step.sm/crypto/minica"
"go.step.sm/crypto/pemutil"
"go.step.sm/linkedca"
"github.com/smallstep/certificates/webhook"
)
func Test_challengeValidationController_Validate(t *testing.T) {
@ -366,3 +374,270 @@ func TestSCEP_ValidateChallenge(t *testing.T) {
})
}
}
func TestSCEP_Init(t *testing.T) {
serialize := func(key crypto.PrivateKey, password string) []byte {
var opts []pemutil.Options
if password == "" {
opts = append(opts, pemutil.WithPasswordPrompt("no password", func(s string) ([]byte, error) {
return nil, nil
}))
} else {
opts = append(opts, pemutil.WithPassword([]byte("password")))
}
block, err := pemutil.Serialize(key, opts...)
require.NoError(t, err)
return pem.EncodeToMemory(block)
}
ca, err := minica.New()
require.NoError(t, err)
key, err := rsa.GenerateKey(rand.Reader, 2048)
require.NoError(t, err)
badKey, err := rsa.GenerateKey(rand.Reader, 2048)
require.NoError(t, err)
cert, err := ca.Sign(&x509.Certificate{
Subject: pkix.Name{CommonName: "SCEP decryptor"},
PublicKey: key.Public(),
})
require.NoError(t, err)
certPEM := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE", Bytes: cert.Raw,
})
certPEMWithIntermediate := append(pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE", Bytes: cert.Raw,
}), pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE", Bytes: ca.Intermediate.Raw,
})...)
keyPEM := serialize(key, "password")
keyPEMNoPassword := serialize(key, "")
badKeyPEM := serialize(badKey, "password")
tmp := t.TempDir()
path := filepath.Join(tmp, "rsa.priv")
pathNoPassword := filepath.Join(tmp, "rsa.key")
require.NoError(t, os.WriteFile(path, keyPEM, 0600))
require.NoError(t, os.WriteFile(pathNoPassword, keyPEMNoPassword, 0600))
type args struct {
config Config
}
tests := []struct {
name string
s *SCEP
args args
wantErr bool
}{
{"ok", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyPEM: keyPEM,
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, false},
{"ok no password", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyPEM: keyPEMNoPassword,
DecrypterKeyPassword: "",
EncryptionAlgorithmIdentifier: 1,
}, args{Config{Claims: globalProvisionerClaims}}, false},
{"ok with uri", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 1024,
DecrypterCertificate: certPEM,
DecrypterKeyURI: "softkms:path=" + path,
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 2,
}, args{Config{Claims: globalProvisionerClaims}}, false},
{"ok with uri no password", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 2048,
DecrypterCertificate: certPEM,
DecrypterKeyURI: "softkms:path=" + pathNoPassword,
DecrypterKeyPassword: "",
EncryptionAlgorithmIdentifier: 3,
}, args{Config{Claims: globalProvisionerClaims}}, false},
{"ok with SCEPKeyManager", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 2048,
DecrypterCertificate: certPEM,
DecrypterKeyURI: "softkms:path=" + pathNoPassword,
DecrypterKeyPassword: "",
EncryptionAlgorithmIdentifier: 4,
}, args{Config{Claims: globalProvisionerClaims, SCEPKeyManager: &softkms.SoftKMS{}}}, false},
{"ok intermediate", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: nil,
DecrypterKeyPEM: nil,
DecrypterKeyPassword: "",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, false},
{"fail type", &SCEP{
Type: "",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyPEM: keyPEM,
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail name", &SCEP{
Type: "SCEP",
Name: "",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyPEM: keyPEM,
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail minimumPublicKeyLength", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 2001,
DecrypterCertificate: certPEM,
DecrypterKeyPEM: keyPEM,
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail encryptionAlgorithmIdentifier", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyPEM: keyPEM,
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 5,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail negative encryptionAlgorithmIdentifier", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyPEM: keyPEM,
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: -1,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail key decode", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyPEM: []byte("not a pem"),
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail certificate decode", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: []byte("not a pem"),
DecrypterKeyPEM: keyPEM,
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail certificate with intermediate", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEMWithIntermediate,
DecrypterKeyPEM: keyPEM,
DecrypterKeyPassword: "password",
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail decrypter password", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyPEM: keyPEM,
DecrypterKeyPassword: "badpassword",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail uri", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyURI: "softkms:path=missing.key",
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail uri password", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyURI: "softkms:path=" + path,
DecrypterKeyPassword: "badpassword",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail uri type", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyURI: "foo:path=" + path,
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail missing certificate", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: nil,
DecrypterKeyPEM: keyPEM,
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, true},
{"fail key match", &SCEP{
Type: "SCEP",
Name: "scep",
ChallengePassword: "password123",
MinimumPublicKeyLength: 0,
DecrypterCertificate: certPEM,
DecrypterKeyPEM: badKeyPEM,
DecrypterKeyPassword: "password",
EncryptionAlgorithmIdentifier: 0,
}, args{Config{Claims: globalProvisionerClaims}}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.s.Init(tt.args.config); (err != nil) != tt.wantErr {
t.Errorf("SCEP.Init() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

@ -201,6 +201,7 @@ func (a *Authority) generateProvisionerConfig(ctx context.Context) (provisioner.
AuthorizeRenewFunc: a.authorizeRenewFunc,
AuthorizeSSHRenewFunc: a.authorizeSSHRenewFunc,
WebhookClient: a.webhookClient,
SCEPKeyManager: a.scepKeyManager,
}, nil
}

@ -116,7 +116,8 @@ type GetCertificateAuthorityRequest struct {
// GetCertificateAuthorityResponse is the response that contains
// the root certificate.
type GetCertificateAuthorityResponse struct {
RootCertificate *x509.Certificate
RootCertificate *x509.Certificate
IntermediateCertificates []*x509.Certificate
}
// CreateKeyRequest is the request used to generate a new key using a KMS.

@ -165,7 +165,8 @@ func (v *VaultCAS) GetCertificateAuthority(*apiv1.GetCertificateAuthorityRequest
}
return &apiv1.GetCertificateAuthorityResponse{
RootCertificate: cert.root,
RootCertificate: cert.root,
IntermediateCertificates: cert.intermediates,
}, nil
}

@ -1,10 +1,10 @@
module github.com/smallstep/certificates
go 1.20
go 1.21
require (
cloud.google.com/go/longrunning v0.5.6
cloud.google.com/go/security v1.15.6
cloud.google.com/go/security v1.16.0
github.com/Masterminds/sprig/v3 v3.2.3
github.com/coreos/go-oidc/v3 v3.4.0
github.com/dgraph-io/badger v1.6.2
@ -17,10 +17,10 @@ require (
github.com/google/go-tpm v0.9.0
github.com/google/uuid v1.6.0
github.com/googleapis/gax-go/v2 v2.12.3
github.com/hashicorp/vault/api v1.12.2
github.com/hashicorp/vault/api v1.13.0
github.com/hashicorp/vault/api/auth/approle v0.6.0
github.com/hashicorp/vault/api/auth/kubernetes v0.6.0
github.com/newrelic/go-agent/v3 v3.30.0
github.com/newrelic/go-agent/v3 v3.32.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.19.0
github.com/rs/xid v1.5.0
@ -34,47 +34,48 @@ require (
github.com/stretchr/testify v1.9.0
github.com/urfave/cli v1.22.14
go.step.sm/cli-utils v0.9.0
go.step.sm/crypto v0.44.1
go.step.sm/crypto v0.44.6
go.step.sm/linkedca v0.20.1
golang.org/x/crypto v0.21.0
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc
golang.org/x/net v0.22.0
google.golang.org/api v0.171.0
google.golang.org/grpc v1.62.1
golang.org/x/crypto v0.22.0
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81
golang.org/x/net v0.24.0
google.golang.org/api v0.176.0
google.golang.org/grpc v1.63.2
google.golang.org/protobuf v1.33.0
)
require (
cloud.google.com/go v0.112.1 // indirect
cloud.google.com/go/compute v1.24.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.6 // indirect
cloud.google.com/go/kms v1.15.7 // indirect
cloud.google.com/go/auth v0.2.2 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.1 // indirect
cloud.google.com/go/compute/metadata v0.3.0 // indirect
cloud.google.com/go/iam v1.1.7 // indirect
cloud.google.com/go/kms v1.15.8 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/ThalesIgnite/crypto11 v1.2.5 // indirect
github.com/aws/aws-sdk-go-v2 v1.26.0 // indirect
github.com/aws/aws-sdk-go-v2/config v1.27.8 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.8 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 // indirect
github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect
github.com/aws/aws-sdk-go-v2/config v1.27.11 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.11 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.30.0 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.20.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.28.5 // indirect
github.com/aws/smithy-go v1.20.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.31.0 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.20.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.28.6 // indirect
github.com/aws/smithy-go v1.20.2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
@ -86,6 +87,7 @@ require (
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-jose/go-jose/v4 v4.0.1 // indirect
github.com/go-kit/kit v0.13.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
@ -93,14 +95,14 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-piv/piv-go v1.11.0 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/golang-jwt/jwt/v5 v5.2.0 // indirect
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
github.com/golang/glog v1.2.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/certificate-transparency-go v1.1.6 // indirect
github.com/google/go-tpm-tools v0.4.3 // indirect
github.com/google/go-tpm-tools v0.4.4 // indirect
github.com/google/go-tspi v0.3.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
@ -155,15 +157,14 @@ require (
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
golang.org/x/oauth2 v0.18.0 // indirect
golang.org/x/oauth2 v0.19.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

169
go.sum

@ -30,6 +30,10 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM=
cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
cloud.google.com/go/auth v0.2.2 h1:gmxNJs4YZYcw6YvKRtVBaF2fyUE6UrWPyzU8jHvYfmI=
cloud.google.com/go/auth v0.2.2/go.mod h1:2bDNJWtWziDT3Pu1URxHHbkHE/BbOCuyUiKIGcNvafo=
cloud.google.com/go/auth/oauth2adapt v0.2.1 h1:VSPmMmUlT8CkIZ2PzD9AlLN+R3+D1clXMWHHa6vG/Ag=
cloud.google.com/go/auth/oauth2adapt v0.2.1/go.mod h1:tOdK/k+D2e4GEwfBRA48dKNQiDsqIXxLh7VU319eV0g=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@ -42,25 +46,23 @@ cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6m
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg=
cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc=
cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=
cloud.google.com/go/kms v1.15.7 h1:7caV9K3yIxvlQPAcaFffhlT7d1qpxjB1wHBtjWa13SM=
cloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI=
cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM=
cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA=
cloud.google.com/go/kms v1.15.8 h1:szIeDCowID8th2i8XE4uRev5PMxQFqW+JjwYxL9h6xs=
cloud.google.com/go/kms v1.15.8/go.mod h1:WoUHcDjD9pluCg7pNds131awnH429QGvRM3N/4MyoVs=
cloud.google.com/go/longrunning v0.5.6 h1:xAe8+0YaWoCKr9t1+aWe+OeQgN/iJK1fEgZSXmjuEaE=
cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/security v1.15.6 h1:LYMj7ISEEjVQ0ub6E6ygGhjVbNQTH5CawKZz0bbPMVE=
cloud.google.com/go/security v1.15.6/go.mod h1:UMEAGVBMqE6xZvkCR1FvUIeBEmGOCRIDwtwT357xmok=
cloud.google.com/go/security v1.16.0 h1:dzc3oYxFG/9+uMwmxpnG+te4ZEEkbzvBoAFR1Va36N4=
cloud.google.com/go/security v1.16.0/go.mod h1:e1GsICfB1nLCRXOq0yaRlKE/6RUAlBqmalTYQH4J2Xo=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
@ -72,18 +74,18 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M=
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 h1:n1DH8TPV4qqPTje2RcUBYwtrTWlabVp4n46+74X2pn4=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0/go.mod h1:HDcZnuGbiyppErN6lB+idp4CKhjbc8gwjto6OPpyggM=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 h1:FDif4R1+UUR+00q6wquyX90K7A8dN+R5E8GEadoP7sU=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2/go.mod h1:aiYBYui4BJ/BJCAIKs92XiPyQfTaBWqvHujDwKb6CBU=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc=
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 h1:m/sWOGCREuSBqg2htVQTBY8nOZpyajYztF0vUvSZTuM=
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0/go.mod h1:Pu5Zksi2KrU7LPbZbNINx6fuVrUp/ffvpxdDj+i8LeE=
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 h1:FbH3BbSb4bvGluTesZZ+ttN/MDsnMmQP36OSnDuSXqw=
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1/go.mod h1:9V2j0jn9jDEkCkv8w/bKTNppX/d0FVA1ud77xCIP4KA=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@ -101,34 +103,34 @@ github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go-v2 v1.26.0 h1:/Ce4OCiM3EkpW7Y+xUnfAFpchU78K7/Ug01sZni9PgA=
github.com/aws/aws-sdk-go-v2 v1.26.0/go.mod h1:35hUlJVYd+M++iLI3ALmVwMOyRYMmRqUXpTtRGW+K9I=
github.com/aws/aws-sdk-go-v2/config v1.27.8 h1:0r8epOsiJ7YJz65MGcb8i91ehFp4kvvFe2qkq5oYeRI=
github.com/aws/aws-sdk-go-v2/config v1.27.8/go.mod h1:XsmYKxYNuIhLsFddpNds+j9H5XKzjWDdg/SZngiwFio=
github.com/aws/aws-sdk-go-v2/credentials v1.17.8 h1:WUdNLXbyNbU07V/WFrSOBXqZTDgmmMNMgUFzpYOKJhw=
github.com/aws/aws-sdk-go-v2/credentials v1.17.8/go.mod h1:iPZzLpaBIfhyvVS/XGD3JvR1GP3YdHTqpySKDlqkfs8=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.4 h1:S+L2QSKhUuShih3aq9P/mkzDBiOO5tTyVg+vXREfsfg=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.4/go.mod h1:nQ3how7DMnFMWiU1SpECohgC82fpn4cKZ875NDMmwtA=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 h1:0ScVK/4qZ8CIW0k8jOeFVsyS/sAiXpYxRBLolMkuLQM=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4/go.mod h1:84KyjNZdHC6QZW08nfHI6yZgPd+qRgaWcYsyLUo3QY8=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 h1:sHmMWWX5E7guWEFQ9SVo6A3S4xpPrWnd77a6y4WM6PU=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4/go.mod h1:WjpDrhWisWOIoS9n3nk67A3Ll1vfULJ9Kq6h29HTD48=
github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA=
github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM=
github.com/aws/aws-sdk-go-v2/config v1.27.11 h1:f47rANd2LQEYHda2ddSCKYId18/8BhSRM4BULGmfgNA=
github.com/aws/aws-sdk-go-v2/config v1.27.11/go.mod h1:SMsV78RIOYdve1vf36z8LmnszlRWkwMQtomCAI0/mIE=
github.com/aws/aws-sdk-go-v2/credentials v1.17.11 h1:YuIB1dJNf1Re822rriUOTxopaHHvIq0l/pX3fwO+Tzs=
github.com/aws/aws-sdk-go-v2/credentials v1.17.11/go.mod h1:AQtFPsDH9bI2O+71anW6EKL+NcD7LG3dpKGMV4SShgo=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 h1:FVJ0r5XTHSmIHJV6KuDmdYhEpvlHpiSd38RQWhut5J4=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1/go.mod h1:zusuAeqezXzAB24LGuzuekqMAEgWkVYukBec3kr3jUg=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 h1:aw39xVGeRWlWx9EzGVnhOR4yOjQDHPQ6o6NmBlscyQg=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5/go.mod h1:FSaRudD0dXiMPK2UjknVwwTYyZMRsHv3TtkabsZih5I=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 h1:PG1F3OD1szkuQPzDw3CIQsRIrtTlUC3lP84taWzHlq0=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5/go.mod h1:jU1li6RFryMz+so64PpKtudI+QzbKoIEivqdf6LNpOc=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 h1:EyBZibRTVAs6ECHZOw5/wlylS9OcTzwyjeQMudmREjE=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1/go.mod h1:JKpmtYhhPs7D97NL/ltqz7yCkERFW5dOlHyVl66ZYF8=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6 h1:b+E7zIUHMmcB4Dckjpkapoy47W6C9QBv/zoUP+Hn8Kc=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6/go.mod h1:S2fNV0rxrP78NhPbCZeQgY8H9jdDMeGtwcfZIRxzBqU=
github.com/aws/aws-sdk-go-v2/service/kms v1.30.0 h1:yS0JkEdV6h9JOo8sy2JSpjX+i7vsKifU8SIeHrqiDhU=
github.com/aws/aws-sdk-go-v2/service/kms v1.30.0/go.mod h1:+I8VUUSVD4p5ISQtzpgSva4I8cJ4SQ4b1dcBcof7O+g=
github.com/aws/aws-sdk-go-v2/service/sso v1.20.3 h1:mnbuWHOcM70/OFUlZZ5rcdfA8PflGXXiefU/O+1S3+8=
github.com/aws/aws-sdk-go-v2/service/sso v1.20.3/go.mod h1:5HFu51Elk+4oRBZVxmHrSds5jFXmFj8C3w7DVF2gnrs=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3 h1:uLq0BKatTmDzWa/Nu4WO0M1AaQDaPpwTKAeByEc6WFM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3/go.mod h1:b+qdhjnxj8GSR6t5YfphOffeoQSQ1KmpoVVuBn+PWxs=
github.com/aws/aws-sdk-go-v2/service/sts v1.28.5 h1:J/PpTf/hllOjx8Xu9DMflff3FajfLxqM5+tepvVXmxg=
github.com/aws/aws-sdk-go-v2/service/sts v1.28.5/go.mod h1:0ih0Z83YDH/QeQ6Ori2yGE2XvWYv/Xm+cZc01LC6oK0=
github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw=
github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 h1:ogRAwT1/gxJBcSWDMZlgyFUM962F51A5CRhDLbxLdmo=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7/go.mod h1:YCsIZhXfRPLFFCl5xxY+1T9RKzOKjCut+28JSX2DnAk=
github.com/aws/aws-sdk-go-v2/service/kms v1.31.0 h1:yl7wcqbisxPzknJVfWTLnK83McUvXba+pz2+tPbIUmQ=
github.com/aws/aws-sdk-go-v2/service/kms v1.31.0/go.mod h1:2snWQJQUKsbN66vAawJuOGX7dr37pfOq9hb0tZDGIqQ=
github.com/aws/aws-sdk-go-v2/service/sso v1.20.5 h1:vN8hEbpRnL7+Hopy9dzmRle1xmDc7o8tmY0klsr175w=
github.com/aws/aws-sdk-go-v2/service/sso v1.20.5/go.mod h1:qGzynb/msuZIE8I75DVRCUXw3o3ZyBmUvMwQ2t/BrGM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4 h1:Jux+gDDyi1Lruk+KHF91tK2KCuY61kzoCpvtvJJBtOE=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4/go.mod h1:mUYPBhaF2lGiukDEjJX2BLRRKTmoUSitGDUgM4tRxak=
github.com/aws/aws-sdk-go-v2/service/sts v1.28.6 h1:cwIxeBttqPN3qkaAjcEcsh8NYr8n2HZPkcKgPAi1phU=
github.com/aws/aws-sdk-go-v2/service/sts v1.28.6/go.mod h1:FZf1/nKNEkHdGGJP/cI2MoIMquumuRK6ol3QQJNDxmw=
github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q=
github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
@ -187,6 +189,7 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
@ -202,6 +205,7 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@ -216,6 +220,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
github.com/go-kit/kit v0.4.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU=
github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg=
@ -241,8 +247,8 @@ github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68=
github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
@ -308,15 +314,19 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98=
github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo=
github.com/google/go-sev-guest v0.9.3 h1:GOJ+EipURdeWFl/YYdgcCxyPeMgQUWlI056iFkBD8UU=
github.com/google/go-sev-guest v0.9.3/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs=
github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw=
github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE=
github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk=
github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU=
github.com/google/go-tpm-tools v0.4.3 h1:L5dc34fttMIREoKRmnIJfv2NSZDSZ+RfBD+izN0EZoA=
github.com/google/go-tpm-tools v0.4.3/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY=
github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98=
github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY=
github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus=
github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI=
github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ=
github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@ -365,6 +375,7 @@ github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/S
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.2.2 h1:ihRI7YFwcZdiSD7SIenIhHfQH3OuDvWerAUBZbeQS3M=
github.com/hashicorp/go-hclog v1.2.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
@ -384,8 +395,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/vault/api v1.12.0/go.mod h1:si+lJCYO7oGkIoNPAN8j3azBLTn9SjMGS+jFaHd1Cck=
github.com/hashicorp/vault/api v1.12.2 h1:7YkCTE5Ni90TcmYHDBExdt4WGJxhpzaHqR6uGbQb/rE=
github.com/hashicorp/vault/api v1.12.2/go.mod h1:LSGf1NGT1BnvFFnKVtnvcaLBM2Lz+gJdpL6HUYed8KE=
github.com/hashicorp/vault/api v1.13.0 h1:RTCGpE2Rgkn9jyPcFlc7YmNocomda44k5ck8FKMH41Y=
github.com/hashicorp/vault/api v1.13.0/go.mod h1:0cb/uZUv1w2cVu9DIvuW1SMlXXC6qtATJt+LXJRx+kg=
github.com/hashicorp/vault/api/auth/approle v0.6.0 h1:ELfFFQlTM/e97WJKu1HvNFa7lQ3tlTwwzrR1NJE1V7Y=
github.com/hashicorp/vault/api/auth/approle v0.6.0/go.mod h1:CCoIl1xBC3lAWpd1HV+0ovk76Z8b8Mdepyk21h3pGk0=
github.com/hashicorp/vault/api/auth/kubernetes v0.6.0 h1:K8sKGhtTAqGKfzaaYvUSIOAqTOIn3Gk1EsCEAMzZHtM=
@ -456,10 +467,12 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
@ -467,6 +480,7 @@ github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
@ -504,9 +518,10 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/newrelic/go-agent/v3 v3.30.0 h1:ZXHCT/Cot4iIPwcegCZURuRQOsfmGA6wilW+S3bfBjY=
github.com/newrelic/go-agent/v3 v3.30.0/go.mod h1:9utrgxlSryNqRrTvII2XBL+0lpofXbqXApvVWPpbzUg=
github.com/newrelic/go-agent/v3 v3.32.0 h1:99Et9lXXzeQV1CfYldfeTXv+d9W9KatpMbb50kIscWo=
github.com/newrelic/go-agent/v3 v3.32.0/go.mod h1:SMdqPzE/ghkWdY0rYGSD7Clw2daK/XH6pUnVd4albg4=
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv/v3 v3.0.1 h1:x06SQA46+PKIUftmEujdwSEpIx8kR+M9eLYsUxeYveU=
github.com/peterbourgon/diskv/v3 v3.0.1/go.mod h1:kJ5Ny7vLdARGU3WUuy6uzO6T0nb/2gWcT1JiBvRmb5o=
@ -530,6 +545,7 @@ github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3c
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
@ -629,13 +645,14 @@ go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw=
go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.step.sm/cli-utils v0.9.0 h1:55jYcsQbnArNqepZyAwcato6Zy2MoZDRkWW+jF+aPfQ=
go.step.sm/cli-utils v0.9.0/go.mod h1:Y/CRoWl1FVR9j+7PnAewufAwKmBOTzR6l9+7EYGAnp8=
go.step.sm/crypto v0.44.1 h1:8ouq8JEYXVxSymuVuX54Ilh5X2dqyjgOGGXyPeXDzV8=
go.step.sm/crypto v0.44.1/go.mod h1:hKl+QUIS4oJFRwQBRcVPz8NOYhRaoOJmwXHd2Y3XTA0=
go.step.sm/crypto v0.44.6 h1:vQg8ujce7fNXDO8EWdriSz+ZSJpYnNh22QrFtRjdyoY=
go.step.sm/crypto v0.44.6/go.mod h1:oKRO4jaf2MaCohJDN+/8ShImkvIgUKfJxxy87gqsnXs=
go.step.sm/linkedca v0.20.1 h1:bHDn1+UG1NgRrERkWbbCiAIvv4lD5NOFaswPDTyO5vU=
go.step.sm/linkedca v0.20.1/go.mod h1:Vaq4+Umtjh7DLFI1KuIxeo598vfBzgSYZUjgVJ7Syxw=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@ -646,6 +663,7 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
@ -667,8 +685,8 @@ golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -679,8 +697,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM=
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 h1:6R2FC06FonbXQ8pK11/PDFY6N6LWlf9KlzibaCapmqc=
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -757,8 +775,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -780,8 +798,8 @@ golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -881,8 +899,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -892,7 +910,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -902,7 +921,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
@ -1021,8 +1039,8 @@ google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU=
google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o=
google.golang.org/api v0.176.0 h1:dHj1/yv5Dm/eQTXiP9hNCRT3xzJHWXeNdRq29XbMxoE=
google.golang.org/api v0.176.0/go.mod h1:Rra+ltKu14pps/4xTycZfobMgLpbosoaaL7c+SEMrO8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -1030,8 +1048,6 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -1110,12 +1126,12 @@ google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP
google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ=
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c h1:lfpJ/2rWPa/kJgxyyXM8PrNnfCzcmxJ265mADgwmvLI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda h1:b6F6WIV4xHHD0FA4oIyzU6mHWg2WI2X1RBehwa5QN38=
google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda/go.mod h1:AHcE/gZH76Bk/ROZhQphlRoWo5xKDEtz3eVEO1LfA8c=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -1147,8 +1163,8 @@ google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@ -1170,6 +1186,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=

@ -387,9 +387,10 @@ func PKIOperation(ctx context.Context, req request) (Response, error) {
if msg.MessageType == smallscep.PKCSReq || msg.MessageType == smallscep.RenewalReq {
if err := auth.ValidateChallenge(ctx, csr, challengePassword, transactionID); err != nil {
if errors.Is(err, provisioner.ErrSCEPChallengeInvalid) {
return createFailureResponse(ctx, csr, msg, smallscep.BadRequest, err)
return createFailureResponse(ctx, csr, msg, smallscep.BadRequest, err.Error(), err)
}
return createFailureResponse(ctx, csr, msg, smallscep.BadRequest, errors.New("failed validating challenge password"))
scepErr := errors.New("failed validating challenge password")
return createFailureResponse(ctx, csr, msg, smallscep.BadRequest, scepErr.Error(), scepErr)
}
}
@ -407,7 +408,7 @@ func PKIOperation(ctx context.Context, req request) (Response, error) {
// TODO(hs): ignore this error case? It's not critical if the notification fails; but logging it might be good
_ = notifyErr
}
return createFailureResponse(ctx, csr, msg, smallscep.BadRequest, fmt.Errorf("error when signing new certificate: %w", err))
return createFailureResponse(ctx, csr, msg, smallscep.BadRequest, "internal server error; please see the certificate authority logs for more info", fmt.Errorf("error when signing new certificate: %w", err))
}
if notifyErr := auth.NotifySuccess(ctx, csr, certRep.Certificate, transactionID); notifyErr != nil {
@ -448,9 +449,9 @@ func fail(w http.ResponseWriter, err error) {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
func createFailureResponse(ctx context.Context, csr *x509.CertificateRequest, msg *scep.PKIMessage, info smallscep.FailInfo, failError error) (Response, error) {
func createFailureResponse(ctx context.Context, csr *x509.CertificateRequest, msg *scep.PKIMessage, info smallscep.FailInfo, infoText string, failError error) (Response, error) {
auth := scep.MustFromContext(ctx)
certRepMsg, err := auth.CreateFailureResponse(ctx, csr, msg, scep.FailInfoName(info), failError.Error())
certRepMsg, err := auth.CreateFailureResponse(ctx, csr, msg, scep.FailInfoName(info), infoText)
if err != nil {
return Response{}, err
}

@ -308,7 +308,7 @@ func (a *Authority) SignCSR(ctx context.Context, csr *x509.CertificateRequest, m
certChain, err := a.signAuth.SignWithContext(ctx, csr, opts, signOps...)
if err != nil {
return nil, fmt.Errorf("error generating certificate for order: %w", err)
return nil, fmt.Errorf("error generating certificate: %w", err)
}
// take the issued certificate (only); https://tools.ietf.org/html/rfc8894#section-3.3.2

@ -37,19 +37,21 @@ func (o *Options) Validate() error {
switch {
case len(o.Intermediates) == 0:
return errors.New("no intermediate certificate available for SCEP authority")
case o.Signer == nil:
return errors.New("no signer available for SCEP authority")
case o.SignerCert == nil:
return errors.New("no signer certificate available for SCEP authority")
}
// check if the signer (intermediate CA) certificate has the same public key as
// the signer. According to the RFC it seems valid to have different keys for
// the intermediate and the CA signing new certificates, so this might change
// in the future.
signerPublicKey := o.Signer.Public().(comparablePublicKey)
if !signerPublicKey.Equal(o.SignerCert.PublicKey) {
return errors.New("mismatch between signer certificate and public key")
// the signer is optional, but if it's set, its public key must match the signer
// certificate public key.
if o.Signer != nil {
// check if the signer (intermediate CA) certificate has the same public key as
// the signer. According to the RFC it seems valid to have different keys for
// the intermediate and the CA signing new certificates, so this might change
// in the future.
signerPublicKey := o.Signer.Public().(comparablePublicKey)
if !signerPublicKey.Equal(o.SignerCert.PublicKey) {
return errors.New("mismatch between signer certificate and public key")
}
}
// decrypter can be nil in case a signing only key is used; validation complete.

@ -29,7 +29,7 @@ var (
oidSCEPsenderNonce = asn1.ObjectIdentifier{2, 16, 840, 1, 113733, 1, 9, 5}
oidSCEPrecipientNonce = asn1.ObjectIdentifier{2, 16, 840, 1, 113733, 1, 9, 6}
oidSCEPtransactionID = asn1.ObjectIdentifier{2, 16, 840, 1, 113733, 1, 9, 7}
oidSCEPfailInfoText = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 24}
oidSCEPfailInfoText = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 24, 1}
//oidChallengePassword = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 7}
)

@ -0,0 +1,273 @@
package sceptest
import (
"context"
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"errors"
"fmt"
"io"
"math/big"
"net"
"net/http"
"net/url"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/smallstep/pkcs7"
"github.com/smallstep/scep"
"go.step.sm/crypto/minica"
"go.step.sm/crypto/x509util"
"github.com/smallstep/certificates/ca"
"github.com/smallstep/certificates/cas/apiv1"
)
func newCAClient(t *testing.T, caURL, rootFilepath string) *ca.Client {
caClient, err := ca.NewClient(
caURL,
ca.WithRootFile(rootFilepath),
)
require.NoError(t, err)
return caClient
}
func requireHealthyCA(t *testing.T, caClient *ca.Client) {
ctx := context.Background()
healthResponse, err := caClient.HealthWithContext(ctx)
require.NoError(t, err)
if assert.NotNil(t, healthResponse) {
require.Equal(t, "ok", healthResponse.Status)
}
}
// reservePort "reserves" a TCP port by opening a listener on a random
// port and immediately closing it. The port can then be assumed to be
// available for running a server on.
func reservePort(t *testing.T) (host, port string) {
t.Helper()
l, err := net.Listen("tcp", ":0")
require.NoError(t, err)
address := l.Addr().String()
err = l.Close()
require.NoError(t, err)
host, port, err = net.SplitHostPort(address)
require.NoError(t, err)
return
}
type client struct {
caURL string
caCert *x509.Certificate
httpClient *http.Client
}
func createSCEPClient(t *testing.T, caURL string, root *x509.Certificate) *client {
t.Helper()
trustedRoots := x509.NewCertPool()
trustedRoots.AddCert(root)
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.TLSClientConfig = &tls.Config{
RootCAs: trustedRoots,
}
httpClient := &http.Client{
Transport: transport,
}
return &client{
caURL: caURL,
httpClient: httpClient,
}
}
func (c *client) getCACert(t *testing.T) error {
// return early if CA certificate already available
if c.caCert != nil {
return nil
}
resp, err := c.httpClient.Get(fmt.Sprintf("%s?operation=GetCACert&message=test", c.caURL))
if err != nil {
return fmt.Errorf("failed get request: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed reading response body: %w", err)
}
t.Log(string(body))
// SCEP CA/RA certificate selection. If there's only a single certificate, it will
// be used as the CA certificate at all times. If there's multiple, the first certificate
// is assumed to be the certificate of the recipient to encrypt messages to.
switch ct := resp.Header.Get("Content-Type"); ct {
case "application/x-x509-ca-cert":
cert, err := x509.ParseCertificate(body)
if err != nil {
return fmt.Errorf("failed parsing response body: %w", err)
}
if _, ok := cert.PublicKey.(*rsa.PublicKey); !ok {
return fmt.Errorf("certificate has unexpected public key type %T", cert.PublicKey)
}
c.caCert = cert
case "application/x-x509-ca-ra-cert":
certs, err := scep.CACerts(body)
if err != nil {
return fmt.Errorf("failed parsing response body: %w", err)
}
cert := certs[0]
if _, ok := cert.PublicKey.(*rsa.PublicKey); !ok {
return fmt.Errorf("certificate has unexpected public key type %T", cert.PublicKey)
}
c.caCert = cert
default:
return fmt.Errorf("unexpected content-type value %q", ct)
}
return nil
}
func (c *client) requestCertificate(t *testing.T, commonName string, sans []string) (*x509.Certificate, error) {
if err := c.getCACert(t); err != nil {
return nil, fmt.Errorf("failed getting CA certificate: %w", err)
}
signer, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, fmt.Errorf("failed creating SCEP private key: %w", err)
}
csr, err := x509util.CreateCertificateRequest(commonName, sans, signer)
if err != nil {
return nil, fmt.Errorf("failed creating CSR: %w", err)
}
tmpl := &x509.Certificate{
Subject: csr.Subject,
PublicKey: signer.Public(),
SerialNumber: big.NewInt(1),
NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().Add(1 * time.Hour),
DNSNames: csr.DNSNames,
IPAddresses: csr.IPAddresses,
EmailAddresses: csr.EmailAddresses,
URIs: csr.URIs,
}
selfSigned, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, signer.Public(), signer)
if err != nil {
return nil, fmt.Errorf("failed creating self signed certificate: %w", err)
}
selfSignedCertificate, err := x509.ParseCertificate(selfSigned)
if err != nil {
return nil, fmt.Errorf("failed parsing self signed certificate: %w", err)
}
msgTmpl := &scep.PKIMessage{
TransactionID: "test-1",
MessageType: scep.PKCSReq,
SenderNonce: []byte("test-nonce-1"),
Recipients: []*x509.Certificate{c.caCert},
SignerCert: selfSignedCertificate,
SignerKey: signer,
}
msg, err := scep.NewCSRRequest(csr, msgTmpl)
if err != nil {
return nil, fmt.Errorf("failed creating SCEP PKCSReq message: %w", err)
}
t.Log(string(msg.Raw))
u, err := url.Parse(c.caURL)
if err != nil {
return nil, fmt.Errorf("failed parsing CA URL: %w", err)
}
opURL := u.ResolveReference(&url.URL{RawQuery: fmt.Sprintf("operation=PKIOperation&message=%s", url.QueryEscape(base64.StdEncoding.EncodeToString(msg.Raw)))})
resp, err := c.httpClient.Get(opURL.String())
if err != nil {
return nil, fmt.Errorf("failed get request: %w", err)
}
defer resp.Body.Close()
if ct := resp.Header.Get("Content-Type"); ct != "application/x-pki-message" {
return nil, fmt.Errorf("received unexpected content type %q", ct)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed reading response body: %w", err)
}
t.Log(string(body))
signedData, err := pkcs7.Parse(body)
if err != nil {
return nil, fmt.Errorf("failed parsing response body: %w", err)
}
// TODO: verify the signature?
p7, err := pkcs7.Parse(signedData.Content)
if err != nil {
return nil, fmt.Errorf("failed decrypting inner p7: %w", err)
}
content, err := p7.Decrypt(selfSignedCertificate, signer)
if err != nil {
return nil, fmt.Errorf("failed decrypting response: %w", err)
}
p7, err = pkcs7.Parse(content)
if err != nil {
return nil, fmt.Errorf("failed parsing p7 content: %w", err)
}
cert := p7.Certificates[0]
return cert, nil
}
type testCAS struct {
ca *minica.CA
}
func (c *testCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1.CreateCertificateResponse, error) {
cert, err := c.ca.SignCSR(req.CSR)
if err != nil {
return nil, fmt.Errorf("failed signing CSR: %w", err)
}
return &apiv1.CreateCertificateResponse{
Certificate: cert,
CertificateChain: []*x509.Certificate{cert, c.ca.Intermediate},
}, nil
}
func (c *testCAS) RenewCertificate(req *apiv1.RenewCertificateRequest) (*apiv1.RenewCertificateResponse, error) {
return nil, errors.New("not implemented")
}
func (c *testCAS) RevokeCertificate(req *apiv1.RevokeCertificateRequest) (*apiv1.RevokeCertificateResponse, error) {
return nil, errors.New("not implemented")
}
func (c *testCAS) GetCertificateAuthority(req *apiv1.GetCertificateAuthorityRequest) (*apiv1.GetCertificateAuthorityResponse, error) {
return &apiv1.GetCertificateAuthorityResponse{
RootCertificate: c.ca.Root,
IntermediateCertificates: []*x509.Certificate{c.ca.Intermediate},
}, nil
}
var _ apiv1.CertificateAuthorityService = (*testCAS)(nil)
var _ apiv1.CertificateAuthorityGetter = (*testCAS)(nil)

@ -0,0 +1,149 @@
package sceptest
import (
"context"
"crypto"
"crypto/x509"
"crypto/x509/pkix"
"encoding/json"
"encoding/pem"
"fmt"
"math/big"
"net"
"net/http"
"path/filepath"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/minica"
"go.step.sm/crypto/pemutil"
"github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/ca"
"github.com/smallstep/certificates/cas/apiv1"
)
func TestIssuesCertificateUsingSCEPWithDecrypterAndUpstreamCAS(t *testing.T) {
signer, err := keyutil.GenerateSigner("EC", "P-256", 0)
require.NoError(t, err)
dir := t.TempDir()
m, err := minica.New(minica.WithName("Step E2E | SCEP Decrypter w/ Upstream CAS"), minica.WithGetSignerFunc(func() (crypto.Signer, error) {
return signer, nil
}))
require.NoError(t, err)
rootFilepath := filepath.Join(dir, "root.crt")
_, err = pemutil.Serialize(m.Root, pemutil.WithFilename(rootFilepath))
require.NoError(t, err)
intermediateCertFilepath := filepath.Join(dir, "intermediate.crt")
_, err = pemutil.Serialize(m.Intermediate, pemutil.WithFilename(intermediateCertFilepath))
require.NoError(t, err)
intermediateKeyFilepath := filepath.Join(dir, "intermediate.key")
_, err = pemutil.Serialize(m.Signer, pemutil.WithFilename(intermediateKeyFilepath))
require.NoError(t, err)
decrypterKey, err := keyutil.GenerateKey("RSA", "", 2048)
require.NoError(t, err)
decrypter, ok := decrypterKey.(crypto.Decrypter)
require.True(t, ok)
decrypterCertifiate, err := m.Sign(&x509.Certificate{
Subject: pkix.Name{CommonName: "decrypter"},
PublicKey: decrypter.Public(),
SerialNumber: big.NewInt(1),
NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().Add(1 * time.Hour),
DNSNames: []string{"decrypter"},
})
require.NoError(t, err)
b, err := pemutil.Serialize(decrypterCertifiate)
require.NoError(t, err)
decrypterCertificatePEMBytes := pem.EncodeToMemory(b)
b, err = pemutil.Serialize(decrypter, pemutil.WithPassword([]byte("1234")))
require.NoError(t, err)
decrypterKeyPEMBytes := pem.EncodeToMemory(b)
// get a random address to listen on and connect to; currently no nicer way to get one before starting the server
// TODO(hs): find/implement a nicer way to expose the CA URL, similar to how e.g. httptest.Server exposes it?
host, port := reservePort(t)
prov := &provisioner.SCEP{
ID: "scep",
Name: "scep",
Type: "SCEP",
ForceCN: false,
ChallengePassword: "",
EncryptionAlgorithmIdentifier: 2,
MinimumPublicKeyLength: 2048,
Claims: &config.GlobalProvisionerClaims,
DecrypterCertificate: decrypterCertificatePEMBytes,
DecrypterKeyPEM: decrypterKeyPEMBytes,
DecrypterKeyPassword: "1234",
}
err = prov.Init(provisioner.Config{})
require.NoError(t, err)
apiv1.Register("test-scep-cas", func(_ context.Context, opts apiv1.Options) (apiv1.CertificateAuthorityService, error) {
return &testCAS{
ca: m,
}, nil
})
cfg := &config.Config{
Address: net.JoinHostPort(host, port), // reuse the address that was just "reserved"
DNSNames: []string{"127.0.0.1", "[::1]", "localhost"},
AuthorityConfig: &config.AuthConfig{
Options: &apiv1.Options{
AuthorityID: "stepca-test-scep",
Type: "test-scep-cas",
CertificateAuthority: "test-cas",
},
AuthorityID: "stepca-test-scep",
DeploymentType: "standalone-test",
Provisioners: provisioner.List{prov},
},
Logger: json.RawMessage(`{"format": "text"}`),
}
c, err := ca.New(cfg)
require.NoError(t, err)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
err = c.Run()
require.ErrorIs(t, err, http.ErrServerClosed)
}()
// instantiate a client for the CA running at the random address
caClient := newCAClient(t, fmt.Sprintf("https://localhost:%s", port), rootFilepath)
requireHealthyCA(t, caClient)
scepClient := createSCEPClient(t, fmt.Sprintf("https://localhost:%s/scep/scep", port), m.Root)
cert, err := scepClient.requestCertificate(t, "test.localhost", []string{"test.localhost"})
assert.NoError(t, err)
require.NotNil(t, cert)
assert.Equal(t, "test.localhost", cert.Subject.CommonName)
assert.Equal(t, "Step E2E | SCEP Decrypter w/ Upstream CAS Intermediate CA", cert.Issuer.CommonName)
// done testing; stop and wait for the server to quit
err = c.Stop()
require.NoError(t, err)
wg.Wait()
}

@ -0,0 +1,139 @@
package sceptest
import (
"crypto"
"crypto/x509"
"crypto/x509/pkix"
"encoding/json"
"encoding/pem"
"fmt"
"math/big"
"net"
"net/http"
"path/filepath"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/minica"
"go.step.sm/crypto/pemutil"
"github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/ca"
)
func TestIssuesCertificateUsingSCEPWithDecrypter(t *testing.T) {
signer, err := keyutil.GenerateSigner("EC", "P-256", 0)
require.NoError(t, err)
dir := t.TempDir()
m, err := minica.New(minica.WithName("Step E2E | SCEP Decrypter"), minica.WithGetSignerFunc(func() (crypto.Signer, error) {
return signer, nil
}))
require.NoError(t, err)
rootFilepath := filepath.Join(dir, "root.crt")
_, err = pemutil.Serialize(m.Root, pemutil.WithFilename(rootFilepath))
require.NoError(t, err)
intermediateCertFilepath := filepath.Join(dir, "intermediate.crt")
_, err = pemutil.Serialize(m.Intermediate, pemutil.WithFilename(intermediateCertFilepath))
require.NoError(t, err)
intermediateKeyFilepath := filepath.Join(dir, "intermediate.key")
_, err = pemutil.Serialize(m.Signer, pemutil.WithFilename(intermediateKeyFilepath))
require.NoError(t, err)
decrypterKey, err := keyutil.GenerateKey("RSA", "", 2048)
require.NoError(t, err)
decrypter, ok := decrypterKey.(crypto.Decrypter)
require.True(t, ok)
decrypterCertifiate, err := m.Sign(&x509.Certificate{
Subject: pkix.Name{CommonName: "decrypter"},
PublicKey: decrypter.Public(),
SerialNumber: big.NewInt(1),
NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().Add(1 * time.Hour),
DNSNames: []string{"decrypter"},
})
require.NoError(t, err)
b, err := pemutil.Serialize(decrypterCertifiate)
require.NoError(t, err)
decrypterCertificatePEMBytes := pem.EncodeToMemory(b)
b, err = pemutil.Serialize(decrypter, pemutil.WithPassword([]byte("1234")))
require.NoError(t, err)
decrypterKeyPEMBytes := pem.EncodeToMemory(b)
// get a random address to listen on and connect to; currently no nicer way to get one before starting the server
// TODO(hs): find/implement a nicer way to expose the CA URL, similar to how e.g. httptest.Server exposes it?
host, port := reservePort(t)
prov := &provisioner.SCEP{
ID: "scep",
Name: "scep",
Type: "SCEP",
ForceCN: false,
ChallengePassword: "",
EncryptionAlgorithmIdentifier: 2,
MinimumPublicKeyLength: 2048,
Claims: &config.GlobalProvisionerClaims,
DecrypterCertificate: decrypterCertificatePEMBytes,
DecrypterKeyPEM: decrypterKeyPEMBytes,
DecrypterKeyPassword: "1234",
}
err = prov.Init(provisioner.Config{})
require.NoError(t, err)
cfg := &config.Config{
Root: []string{rootFilepath},
IntermediateCert: intermediateCertFilepath,
IntermediateKey: intermediateKeyFilepath,
Address: net.JoinHostPort(host, port), // reuse the address that was just "reserved"
DNSNames: []string{"127.0.0.1", "[::1]", "localhost"},
AuthorityConfig: &config.AuthConfig{
AuthorityID: "stepca-test-scep",
DeploymentType: "standalone-test",
Provisioners: provisioner.List{prov},
},
Logger: json.RawMessage(`{"format": "text"}`),
}
c, err := ca.New(cfg)
require.NoError(t, err)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
err = c.Run()
require.ErrorIs(t, err, http.ErrServerClosed)
}()
// instantiate a client for the CA running at the random address
caClient := newCAClient(t, fmt.Sprintf("https://localhost:%s", port), rootFilepath)
requireHealthyCA(t, caClient)
scepClient := createSCEPClient(t, fmt.Sprintf("https://localhost:%s/scep/scep", port), m.Root)
cert, err := scepClient.requestCertificate(t, "test.localhost", []string{"test.localhost"})
assert.NoError(t, err)
require.NotNil(t, cert)
assert.Equal(t, "test.localhost", cert.Subject.CommonName)
assert.Equal(t, "Step E2E | SCEP Decrypter Intermediate CA", cert.Issuer.CommonName)
// done testing; stop and wait for the server to quit
err = c.Stop()
require.NoError(t, err)
wg.Wait()
}

@ -0,0 +1,116 @@
package sceptest
import (
"context"
"crypto"
"encoding/json"
"fmt"
"net"
"net/http"
"path/filepath"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/minica"
"go.step.sm/crypto/pemutil"
"github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/ca"
"github.com/smallstep/certificates/cas/apiv1"
)
func TestFailsIssuingCertificateUsingRegularSCEPWithUpstreamCAS(t *testing.T) {
signer, err := keyutil.GenerateSigner("RSA", "", 2048)
require.NoError(t, err)
dir := t.TempDir()
m, err := minica.New(minica.WithName("Step E2E | SCEP Regular w/ Upstream CAS"), minica.WithGetSignerFunc(func() (crypto.Signer, error) {
return signer, nil
}))
require.NoError(t, err)
rootFilepath := filepath.Join(dir, "root.crt")
_, err = pemutil.Serialize(m.Root, pemutil.WithFilename(rootFilepath))
require.NoError(t, err)
intermediateCertFilepath := filepath.Join(dir, "intermediate.crt")
_, err = pemutil.Serialize(m.Intermediate, pemutil.WithFilename(intermediateCertFilepath))
require.NoError(t, err)
intermediateKeyFilepath := filepath.Join(dir, "intermediate.key")
_, err = pemutil.Serialize(m.Signer, pemutil.WithFilename(intermediateKeyFilepath))
require.NoError(t, err)
// get a random address to listen on and connect to; currently no nicer way to get one before starting the server
// TODO(hs): find/implement a nicer way to expose the CA URL, similar to how e.g. httptest.Server exposes it?
host, port := reservePort(t)
prov := &provisioner.SCEP{
ID: "scep",
Name: "scep",
Type: "SCEP",
ForceCN: false,
ChallengePassword: "",
EncryptionAlgorithmIdentifier: 2,
MinimumPublicKeyLength: 2048,
Claims: &config.GlobalProvisionerClaims,
}
err = prov.Init(provisioner.Config{})
require.NoError(t, err)
apiv1.Register("test-scep-cas", func(_ context.Context, opts apiv1.Options) (apiv1.CertificateAuthorityService, error) {
return &testCAS{
ca: m,
}, nil
})
cfg := &config.Config{
Address: net.JoinHostPort(host, port), // reuse the address that was just "reserved"
DNSNames: []string{"127.0.0.1", "[::1]", "localhost"},
AuthorityConfig: &config.AuthConfig{
Options: &apiv1.Options{
AuthorityID: "stepca-test-scep",
Type: "test-scep-cas",
CertificateAuthority: "test-cas",
},
AuthorityID: "stepca-test-scep",
DeploymentType: "standalone-test",
Provisioners: provisioner.List{prov},
},
Logger: json.RawMessage(`{"format": "text"}`),
}
c, err := ca.New(cfg)
require.NoError(t, err)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
err = c.Run()
require.ErrorIs(t, err, http.ErrServerClosed)
}()
// instantiate a client for the CA running at the random address
caClient := newCAClient(t, fmt.Sprintf("https://localhost:%s", port), rootFilepath)
requireHealthyCA(t, caClient)
// issuance is expected to fail when an upstream CAS is configured, as the current
// CAS interfaces do not support providing a decrypter.
scepClient := createSCEPClient(t, fmt.Sprintf("https://localhost:%s/scep/scep", port), m.Root)
cert, err := scepClient.requestCertificate(t, "test.localhost", []string{"test.localhost"})
assert.Error(t, err)
assert.Nil(t, cert)
// done testing; stop and wait for the server to quit
err = c.Stop()
require.NoError(t, err)
wg.Wait()
}

@ -0,0 +1,107 @@
package sceptest
import (
"crypto"
"encoding/json"
"fmt"
"net"
"net/http"
"path/filepath"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/minica"
"go.step.sm/crypto/pemutil"
"github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/ca"
)
func TestIssuesCertificateUsingRegularSCEPConfiguration(t *testing.T) {
signer, err := keyutil.GenerateSigner("RSA", "", 2048)
require.NoError(t, err)
dir := t.TempDir()
m, err := minica.New(minica.WithName("Step E2E | SCEP Regular"), minica.WithGetSignerFunc(func() (crypto.Signer, error) {
return signer, nil
}))
require.NoError(t, err)
rootFilepath := filepath.Join(dir, "root.crt")
_, err = pemutil.Serialize(m.Root, pemutil.WithFilename(rootFilepath))
require.NoError(t, err)
intermediateCertFilepath := filepath.Join(dir, "intermediate.crt")
_, err = pemutil.Serialize(m.Intermediate, pemutil.WithFilename(intermediateCertFilepath))
require.NoError(t, err)
intermediateKeyFilepath := filepath.Join(dir, "intermediate.key")
_, err = pemutil.Serialize(m.Signer, pemutil.WithFilename(intermediateKeyFilepath))
require.NoError(t, err)
// get a random address to listen on and connect to; currently no nicer way to get one before starting the server
// TODO(hs): find/implement a nicer way to expose the CA URL, similar to how e.g. httptest.Server exposes it?
host, port := reservePort(t)
prov := &provisioner.SCEP{
ID: "scep",
Name: "scep",
Type: "SCEP",
ForceCN: false,
ChallengePassword: "",
EncryptionAlgorithmIdentifier: 2,
MinimumPublicKeyLength: 2048,
Claims: &config.GlobalProvisionerClaims,
}
err = prov.Init(provisioner.Config{})
require.NoError(t, err)
cfg := &config.Config{
Root: []string{rootFilepath},
IntermediateCert: intermediateCertFilepath,
IntermediateKey: intermediateKeyFilepath,
Address: net.JoinHostPort(host, port), // reuse the address that was just "reserved"
DNSNames: []string{"127.0.0.1", "[::1]", "localhost"},
AuthorityConfig: &config.AuthConfig{
AuthorityID: "stepca-test-scep",
DeploymentType: "standalone-test",
Provisioners: provisioner.List{prov},
},
Logger: json.RawMessage(`{"format": "text"}`),
}
c, err := ca.New(cfg)
require.NoError(t, err)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
err = c.Run()
require.ErrorIs(t, err, http.ErrServerClosed)
}()
// instantiate a client for the CA running at the random address
caClient := newCAClient(t, fmt.Sprintf("https://localhost:%s", port), rootFilepath)
requireHealthyCA(t, caClient)
scepClient := createSCEPClient(t, fmt.Sprintf("https://localhost:%s/scep/scep", port), m.Root)
cert, err := scepClient.requestCertificate(t, "test.localhost", []string{"test.localhost"})
assert.NoError(t, err)
require.NotNil(t, cert)
assert.Equal(t, "test.localhost", cert.Subject.CommonName)
assert.Equal(t, "Step E2E | SCEP Regular Intermediate CA", cert.Issuer.CommonName)
// done testing; stop and wait for the server to quit
err = c.Stop()
require.NoError(t, err)
wg.Wait()
}
Loading…
Cancel
Save