diff --git a/acme/api/account_test.go b/acme/api/account_test.go index 15405f24..a67e1a62 100644 --- a/acme/api/account_test.go +++ b/acme/api/account_test.go @@ -45,6 +45,10 @@ func (*fakeProvisioner) IsChallengeEnabled(ctx context.Context, challenge provis return true } +func (*fakeProvisioner) IsAttestationFormatEnabled(ctx context.Context, format provisioner.ACMEAttestationFormat) bool { + return true +} + func (*fakeProvisioner) AuthorizeRevoke(ctx context.Context, token string) error { return nil } func (*fakeProvisioner) GetID() string { return "" } func (*fakeProvisioner) GetName() string { return "" } diff --git a/acme/challenge.go b/acme/challenge.go index aec30aec..cc860f95 100644 --- a/acme/challenge.go +++ b/acme/challenge.go @@ -26,6 +26,7 @@ import ( "time" "github.com/fxamacker/cbor/v2" + "github.com/smallstep/certificates/authority/provisioner" "go.step.sm/crypto/jose" "go.step.sm/crypto/pemutil" ) @@ -341,6 +342,12 @@ func deviceAttest01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose return WrapErrorISE(err, "error unmarshalling CBOR") } + prov := MustProvisionerFromContext(ctx) + if !prov.IsAttestationFormatEnabled(ctx, provisioner.ACMEAttestationFormat(att.Format)) { + return storeError(ctx, db, ch, true, + NewError(ErrorBadAttestationStatementType, "attestation format %q is not enabled", att.Format)) + } + switch att.Format { case "apple": data, err := doAppleAttestationFormat(ctx, ch, db, &att) diff --git a/acme/common.go b/acme/common.go index 331b21ca..b7260386 100644 --- a/acme/common.go +++ b/acme/common.go @@ -72,6 +72,7 @@ type Provisioner interface { AuthorizeSign(ctx context.Context, token string) ([]provisioner.SignOption, error) AuthorizeRevoke(ctx context.Context, token string) error IsChallengeEnabled(ctx context.Context, challenge provisioner.ACMEChallenge) bool + IsAttestationFormatEnabled(ctx context.Context, format provisioner.ACMEAttestationFormat) bool GetID() string GetName() string DefaultTLSCertDuration() time.Duration @@ -110,7 +111,8 @@ type MockProvisioner struct { MauthorizeOrderIdentifier func(ctx context.Context, identifier provisioner.ACMEIdentifier) error MauthorizeSign func(ctx context.Context, ott string) ([]provisioner.SignOption, error) MauthorizeRevoke func(ctx context.Context, token string) error - MisChallengeEnabled func(Ctx context.Context, challenge provisioner.ACMEChallenge) bool + MisChallengeEnabled func(ctx context.Context, challenge provisioner.ACMEChallenge) bool + MisAttFormatEnabled func(ctx context.Context, format provisioner.ACMEAttestationFormat) bool MdefaultTLSCertDuration func() time.Duration MgetOptions func() *provisioner.Options } @@ -147,7 +149,7 @@ func (m *MockProvisioner) AuthorizeRevoke(ctx context.Context, token string) err return m.Merr } -// AuthorizeChallenge mock +// IsChallengeEnabled mock func (m *MockProvisioner) IsChallengeEnabled(ctx context.Context, challenge provisioner.ACMEChallenge) bool { if m.MisChallengeEnabled != nil { return m.MisChallengeEnabled(ctx, challenge) @@ -155,6 +157,14 @@ func (m *MockProvisioner) IsChallengeEnabled(ctx context.Context, challenge prov return m.Merr == nil } +// IsAttestationFormatEnabled mock +func (m *MockProvisioner) IsAttestationFormatEnabled(ctx context.Context, format provisioner.ACMEAttestationFormat) bool { + if m.MisAttFormatEnabled != nil { + return m.MisAttFormatEnabled(ctx, format) + } + return m.Merr == nil +} + // DefaultTLSCertDuration mock func (m *MockProvisioner) DefaultTLSCertDuration() time.Duration { if m.MdefaultTLSCertDuration != nil {