2023-04-14 18:12:31 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2023-03-29 16:29:19 +00:00
|
|
|
package pki
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/hashicorp/vault/sdk/framework"
|
|
|
|
"github.com/hashicorp/vault/sdk/logical"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2023-05-17 13:59:30 +00:00
|
|
|
pathAcmeHelpSync = `An endpoint implementing the standard ACME protocol`
|
|
|
|
pathAcmeHelpDesc = `This API endpoint implementing a subset of the ACME protocol
|
|
|
|
defined in RFC 8555, with its own authentication and argument syntax that
|
|
|
|
does not follow conventional Vault operations. An ACME client tool or library
|
|
|
|
should be used to interact with these endpoints.`
|
2023-03-29 16:29:19 +00:00
|
|
|
)
|
|
|
|
|
2023-04-14 18:48:33 +00:00
|
|
|
func pathAcmeDirectory(b *backend) []*framework.Path {
|
|
|
|
return buildAcmeFrameworkPaths(b, patternAcmeDirectory, "/directory")
|
2023-03-29 16:29:19 +00:00
|
|
|
}
|
|
|
|
|
2023-03-29 19:06:09 +00:00
|
|
|
func patternAcmeDirectory(b *backend, pattern string) *framework.Path {
|
2023-03-29 16:29:19 +00:00
|
|
|
fields := map[string]*framework.FieldSchema{}
|
2023-03-29 19:06:09 +00:00
|
|
|
addFieldsForACMEPath(fields, pattern)
|
|
|
|
|
2023-03-29 16:29:19 +00:00
|
|
|
return &framework.Path{
|
|
|
|
Pattern: pattern,
|
|
|
|
Fields: fields,
|
|
|
|
Operations: map[logical.Operation]framework.OperationHandler{
|
|
|
|
logical.ReadOperation: &framework.PathOperation{
|
|
|
|
Callback: b.acmeWrapper(b.acmeDirectoryHandler),
|
|
|
|
ForwardPerformanceSecondary: false,
|
|
|
|
ForwardPerformanceStandby: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
2023-05-17 13:59:30 +00:00
|
|
|
HelpSynopsis: pathAcmeHelpSync,
|
|
|
|
HelpDescription: pathAcmeHelpDesc,
|
2023-03-29 16:29:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-03 20:08:25 +00:00
|
|
|
func (b *backend) acmeDirectoryHandler(acmeCtx *acmeContext, r *logical.Request, _ *framework.FieldData) (*logical.Response, error) {
|
2023-03-29 16:29:19 +00:00
|
|
|
rawBody, err := json.Marshal(map[string]interface{}{
|
2023-04-03 13:38:20 +00:00
|
|
|
"newNonce": acmeCtx.baseUrl.JoinPath("new-nonce").String(),
|
|
|
|
"newAccount": acmeCtx.baseUrl.JoinPath("new-account").String(),
|
|
|
|
"newOrder": acmeCtx.baseUrl.JoinPath("new-order").String(),
|
|
|
|
"revokeCert": acmeCtx.baseUrl.JoinPath("revoke-cert").String(),
|
|
|
|
"keyChange": acmeCtx.baseUrl.JoinPath("key-change").String(),
|
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 17:15:20 +00:00
|
|
|
// This is purposefully missing newAuthz as we don't support pre-authorization
|
2023-03-29 16:29:19 +00:00
|
|
|
"meta": map[string]interface{}{
|
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 17:15:20 +00:00
|
|
|
"externalAccountRequired": acmeCtx.eabPolicy.IsExternalAccountRequired(),
|
2023-03-29 16:29:19 +00:00
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed encoding response: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &logical.Response{
|
|
|
|
Data: map[string]interface{}{
|
|
|
|
logical.HTTPContentType: "application/json",
|
|
|
|
logical.HTTPStatusCode: http.StatusOK,
|
|
|
|
logical.HTTPRawBody: rawBody,
|
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}
|