vault/builtin/logical/pki/acme_eab_policy.go
Steven Clark 0b9f4048af
Add External Account Binding support to ACME (#20523)
* Add Vault APIS to create, list, delete ACME EAB keys

 - Add Vault authenticated APIs to create, list and delete ACME
   EAB keys.
 - Add supporting tests for all new apis

* Add require_eab to acme configuration

* Add EAB support to ACME

* Add EAB support to ACME

* PR feedback 1

 - Address missing err return within DeleteEab
 - Move verifyEabPayload to acme_jws.go no code changes in this PR
 - Update error message returned for error on account storage with EAB.

* PR feedback 2

 - Verify JWK signature payload after signature verification

* Introduce an ACME eab_policy in configuration

 - Instead of a boolean on/off for require_eab, introduce named policies for ACME behaviour enforcing eab.
 - The default policy of always-required, will force new accounts to have an EAB, and all operations in the future, will make sure the account has an EAB associated with it.
 - Two other policies, not-required will allow any anonymous users to use ACME within PKI and 'new-account-required' will enforce new accounts going forward to require an EAB, but existing accounts will still be allowed to use ACME if they don't have an EAB associated with the account.
 - Having 'always-required' as a policy, will override the environment variable to disable public acme as well.

* Add missing go-docs to new tests.

* Add valid eab_policy values in error message.
2023-05-15 13:15:20 -04:00

70 lines
2.1 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package pki
import (
"fmt"
"strings"
)
type EabPolicyName string
const (
eabPolicyNotRequired EabPolicyName = "not-required"
eabPolicyNewAccountRequired EabPolicyName = "new-account-required"
eabPolicyAlwaysRequired EabPolicyName = "always-required"
)
func getEabPolicyByString(name string) (EabPolicy, error) {
lcName := strings.TrimSpace(strings.ToLower(name))
switch lcName {
case string(eabPolicyNotRequired):
return getEabPolicyByName(eabPolicyNotRequired), nil
case string(eabPolicyNewAccountRequired):
return getEabPolicyByName(eabPolicyNewAccountRequired), nil
case string(eabPolicyAlwaysRequired):
return getEabPolicyByName(eabPolicyAlwaysRequired), nil
default:
return getEabPolicyByName(eabPolicyAlwaysRequired), fmt.Errorf("unknown eab policy name: %s", name)
}
}
func getEabPolicyByName(name EabPolicyName) EabPolicy {
return EabPolicy{Name: name}
}
type EabPolicy struct {
Name EabPolicyName
}
// EnforceForNewAccount for new account creations, should we require an EAB.
func (ep EabPolicy) EnforceForNewAccount(eabData *eabType) error {
if (ep.Name == eabPolicyAlwaysRequired || ep.Name == eabPolicyNewAccountRequired) && eabData == nil {
return ErrExternalAccountRequired
}
return nil
}
// EnforceForExistingAccount for all operations within ACME, does the account being used require an EAB attached to it.
func (ep EabPolicy) EnforceForExistingAccount(account *acmeAccount) error {
if ep.Name == eabPolicyAlwaysRequired && account.Eab == nil {
return ErrExternalAccountRequired
}
return nil
}
// IsExternalAccountRequired for new accounts incoming does is an EAB required
func (ep EabPolicy) IsExternalAccountRequired() bool {
return ep.Name == eabPolicyAlwaysRequired || ep.Name == eabPolicyNewAccountRequired
}
// OverrideEnvDisablingPublicAcme determines if ACME is enabled but the OS environment variable
// has said to disable public acme support, if we can override that environment variable to
// turn on ACME support
func (ep EabPolicy) OverrideEnvDisablingPublicAcme() bool {
return ep.Name == eabPolicyAlwaysRequired
}