forked from TrueCloudLab/certificates
Fix ACME order identifier allow/deny check
This commit is contained in:
parent
7c541888ad
commit
3ec9a7310c
3 changed files with 15 additions and 13 deletions
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/go-chi/chi"
|
||||
"github.com/smallstep/certificates/acme"
|
||||
"github.com/smallstep/certificates/api"
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
"go.step.sm/crypto/randutil"
|
||||
)
|
||||
|
||||
|
@ -107,7 +108,8 @@ func (h *Handler) NewOrder(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
for _, identifier := range nor.Identifiers {
|
||||
// TODO: gather all errors, so that we can build subproblems; include the nor.Validate() error here too, like in example?
|
||||
err = prov.AuthorizeOrderIdentifier(ctx, identifier.Value)
|
||||
orderIdentifier := provisioner.ACMEIdentifier{Type: provisioner.ACMEIdentifierType(identifier.Type), Value: identifier.Value}
|
||||
err = prov.AuthorizeOrderIdentifier(ctx, orderIdentifier)
|
||||
if err != nil {
|
||||
api.WriteError(w, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
|
||||
return
|
||||
|
|
|
@ -30,7 +30,7 @@ var clock Clock
|
|||
// Provisioner is an interface that implements a subset of the provisioner.Interface --
|
||||
// only those methods required by the ACME api/authority.
|
||||
type Provisioner interface {
|
||||
AuthorizeOrderIdentifier(ctx context.Context, identifier string) error
|
||||
AuthorizeOrderIdentifier(ctx context.Context, identifier provisioner.ACMEIdentifier) error
|
||||
AuthorizeSign(ctx context.Context, token string) ([]provisioner.SignOption, error)
|
||||
AuthorizeRevoke(ctx context.Context, token string) error
|
||||
GetID() string
|
||||
|
@ -45,7 +45,7 @@ type MockProvisioner struct {
|
|||
Merr error
|
||||
MgetID func() string
|
||||
MgetName func() string
|
||||
MauthorizeOrderIdentifier func(ctx context.Context, identifier string) error
|
||||
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
|
||||
MdefaultTLSCertDuration func() time.Duration
|
||||
|
@ -61,7 +61,7 @@ func (m *MockProvisioner) GetName() string {
|
|||
}
|
||||
|
||||
// AuthorizeOrderIdentifiers mock
|
||||
func (m *MockProvisioner) AuthorizeOrderIdentifier(ctx context.Context, identifier string) error {
|
||||
func (m *MockProvisioner) AuthorizeOrderIdentifier(ctx context.Context, identifier provisioner.ACMEIdentifier) error {
|
||||
if m.MauthorizeOrderIdentifier != nil {
|
||||
return m.MauthorizeOrderIdentifier(ctx, identifier)
|
||||
}
|
||||
|
|
|
@ -90,8 +90,6 @@ func (p *ACME) Init(config Config) (err error) {
|
|||
}
|
||||
|
||||
// Initialize the x509 allow/deny policy engine
|
||||
// TODO(hs): ensure no race conditions happen when reloading settings and requesting certs?
|
||||
// TODO(hs): implement memoization strategy, so that reloading is not required when no changes were made to allow/deny?
|
||||
if p.x509Policy, err = policy.NewX509PolicyEngine(p.Options.GetX509Options()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -115,20 +113,22 @@ type ACMEIdentifier struct {
|
|||
Value string
|
||||
}
|
||||
|
||||
// AuthorizeOrderIdentifiers verifies the provisioner is authorized to issue a
|
||||
// certificate for the Identifiers provided in an Order.
|
||||
func (p *ACME) AuthorizeOrderIdentifier(ctx context.Context, identifier string) error {
|
||||
// AuthorizeOrderIdentifier verifies the provisioner is allowed to issue a
|
||||
// certificate for an ACME Order Identifier.
|
||||
func (p *ACME) AuthorizeOrderIdentifier(ctx context.Context, identifier ACMEIdentifier) error {
|
||||
|
||||
// identifier is allowed if no policy is configured
|
||||
if p.x509Policy == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// assuming only valid identifiers (IP or DNS) are provided
|
||||
var err error
|
||||
if ip := net.ParseIP(identifier); ip != nil {
|
||||
_, err = p.x509Policy.IsIPAllowed(ip)
|
||||
} else {
|
||||
_, err = p.x509Policy.IsDNSAllowed(identifier)
|
||||
switch identifier.Type {
|
||||
case IP:
|
||||
_, err = p.x509Policy.IsIPAllowed(net.ParseIP(identifier.Value))
|
||||
case DNS:
|
||||
_, err = p.x509Policy.IsDNSAllowed(identifier.Value)
|
||||
}
|
||||
|
||||
return err
|
||||
|
|
Loading…
Reference in a new issue