forked from TrueCloudLab/certificates
Use LinkedCA.EABKey type in ACME EAB API
This commit is contained in:
parent
f31ca4f6a4
commit
1dba8698e3
3 changed files with 27 additions and 22 deletions
|
@ -265,7 +265,6 @@ func (h *Handler) validateExternalAccountBinding(ctx context.Context, nar *NewAc
|
||||||
return nil, acme.WrapErrorISE(err, "error parsing externalAccountBinding jws")
|
return nil, acme.WrapErrorISE(err, "error parsing externalAccountBinding jws")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: verify supported algorithms against the incoming alg (and corresponding settings)?
|
|
||||||
// TODO: implement strategy pattern to allow for different ways of verification (i.e. webhook call) based on configuration
|
// TODO: implement strategy pattern to allow for different ways of verification (i.e. webhook call) based on configuration
|
||||||
|
|
||||||
keyID := eabJWS.Signatures[0].Protected.KeyID
|
keyID := eabJWS.Signatures[0].Protected.KeyID
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/smallstep/certificates/api"
|
"github.com/smallstep/certificates/api"
|
||||||
"github.com/smallstep/certificates/authority/admin"
|
"github.com/smallstep/certificates/authority/admin"
|
||||||
|
"go.step.sm/linkedca"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateExternalAccountKeyRequest is the type for POST /admin/acme/eab requests
|
// CreateExternalAccountKeyRequest is the type for POST /admin/acme/eab requests
|
||||||
|
@ -13,29 +14,35 @@ type CreateExternalAccountKeyRequest struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateExternalAccountKeyResponse is the type for POST /admin/acme/eab responses
|
// Validate validates a new-admin request body.
|
||||||
type CreateExternalAccountKeyResponse struct {
|
func (r *CreateExternalAccountKeyRequest) Validate() error {
|
||||||
ProvisionerName string `json:"provisioner"`
|
if r.ProvisionerName == "" {
|
||||||
KeyID string `json:"keyID"`
|
return admin.NewError(admin.ErrorBadRequestType, "provisioner name cannot be empty")
|
||||||
Name string `json:"name"`
|
}
|
||||||
Key []byte `json:"key"`
|
if r.Name == "" {
|
||||||
|
return admin.NewError(admin.ErrorBadRequestType, "name / reference cannot be empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExternalAccountKeysResponse is the type for GET /admin/acme/eab responses
|
// GetExternalAccountKeysResponse is the type for GET /admin/acme/eab responses
|
||||||
type GetExternalAccountKeysResponse struct {
|
type GetExternalAccountKeysResponse struct {
|
||||||
EAKs []*CreateExternalAccountKeyResponse `json:"eaks"`
|
EAKs []*linkedca.EABKey `json:"eaks"`
|
||||||
NextCursor string `json:"nextCursor"`
|
NextCursor string `json:"nextCursor"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateExternalAccountKey creates a new External Account Binding key
|
// CreateExternalAccountKey creates a new External Account Binding key
|
||||||
func (h *Handler) CreateExternalAccountKey(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) CreateExternalAccountKey(w http.ResponseWriter, r *http.Request) {
|
||||||
var body CreateExternalAccountKeyRequest
|
var body CreateExternalAccountKeyRequest
|
||||||
if err := api.ReadJSON(r.Body, &body); err != nil { // TODO: rewrite into protobuf json (likely)
|
if err := api.ReadJSON(r.Body, &body); err != nil { // TODO: rewrite into protobuf json (likely)
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, admin.WrapError(admin.ErrorBadRequestType, err, "error reading request body"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Validate input
|
if err := body.Validate(); err != nil {
|
||||||
|
api.WriteError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
eak, err := h.acmeDB.CreateExternalAccountKey(r.Context(), body.ProvisionerName, body.Name)
|
eak, err := h.acmeDB.CreateExternalAccountKey(r.Context(), body.ProvisionerName, body.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -43,14 +50,14 @@ func (h *Handler) CreateExternalAccountKey(w http.ResponseWriter, r *http.Reques
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
eakResponse := CreateExternalAccountKeyResponse{
|
response := &linkedca.EABKey{
|
||||||
|
EabKid: eak.ID,
|
||||||
|
EabHmacKey: eak.KeyBytes,
|
||||||
ProvisionerName: eak.ProvisionerName,
|
ProvisionerName: eak.ProvisionerName,
|
||||||
KeyID: eak.ID,
|
|
||||||
Name: eak.Name,
|
Name: eak.Name,
|
||||||
Key: eak.KeyBytes,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
api.JSONStatus(w, eakResponse, http.StatusCreated) // TODO: rewrite into protobuf json (likely)
|
api.ProtoJSONStatus(w, response, http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExternalAccountKeys returns a segment of ACME EAB Keys.
|
// GetExternalAccountKeys returns a segment of ACME EAB Keys.
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/api"
|
|
||||||
"github.com/smallstep/certificates/authority/admin"
|
"github.com/smallstep/certificates/authority/admin"
|
||||||
adminAPI "github.com/smallstep/certificates/authority/admin/api"
|
adminAPI "github.com/smallstep/certificates/authority/admin/api"
|
||||||
"github.com/smallstep/certificates/authority/provisioner"
|
"github.com/smallstep/certificates/authority/provisioner"
|
||||||
|
@ -600,7 +599,7 @@ retry:
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateExternalAccountKey performs the POST /admin/acme/eab request to the CA.
|
// CreateExternalAccountKey performs the POST /admin/acme/eab request to the CA.
|
||||||
func (c *AdminClient) CreateExternalAccountKey(eakRequest *adminAPI.CreateExternalAccountKeyRequest) (*adminAPI.CreateExternalAccountKeyResponse, error) {
|
func (c *AdminClient) CreateExternalAccountKey(eakRequest *adminAPI.CreateExternalAccountKeyRequest) (*linkedca.EABKey, error) {
|
||||||
var retried bool
|
var retried bool
|
||||||
body, err := json.Marshal(eakRequest)
|
body, err := json.Marshal(eakRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -628,18 +627,18 @@ retry:
|
||||||
}
|
}
|
||||||
return nil, readAdminError(resp.Body)
|
return nil, readAdminError(resp.Body)
|
||||||
}
|
}
|
||||||
var eakResp = new(adminAPI.CreateExternalAccountKeyResponse)
|
var eabKey = new(linkedca.EABKey)
|
||||||
if err := api.ReadJSON(resp.Body, &eakResp); err != nil {
|
if err := readProtoJSON(resp.Body, eabKey); err != nil {
|
||||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||||
}
|
}
|
||||||
return eakResp, nil
|
return eabKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExternalAccountKeys returns all ACME EAB Keys from the GET /admin/acme/eab request to the CA.
|
// GetExternalAccountKeys returns all ACME EAB Keys from the GET /admin/acme/eab request to the CA.
|
||||||
func (c *AdminClient) GetExternalAccountKeys(opts ...AdminOption) ([]*adminAPI.CreateExternalAccountKeyResponse, error) {
|
func (c *AdminClient) GetExternalAccountKeys(opts ...AdminOption) ([]*linkedca.EABKey, error) {
|
||||||
var (
|
var (
|
||||||
cursor = ""
|
cursor = ""
|
||||||
eaks = []*adminAPI.CreateExternalAccountKeyResponse{}
|
eaks = []*linkedca.EABKey{}
|
||||||
)
|
)
|
||||||
for {
|
for {
|
||||||
resp, err := c.GetExternalAccountKeysPaginate(WithAdminCursor(cursor), WithAdminLimit(100))
|
resp, err := c.GetExternalAccountKeysPaginate(WithAdminCursor(cursor), WithAdminLimit(100))
|
||||||
|
|
Loading…
Reference in a new issue