Add support for deleting ACME EAB keys
This commit is contained in:
parent
a98fe03e80
commit
9d09f5e575
5 changed files with 63 additions and 0 deletions
13
acme/db.go
13
acme/db.go
|
@ -21,6 +21,7 @@ type DB interface {
|
||||||
|
|
||||||
CreateExternalAccountKey(ctx context.Context, provisionerName string, name string) (*ExternalAccountKey, error)
|
CreateExternalAccountKey(ctx context.Context, provisionerName string, name string) (*ExternalAccountKey, error)
|
||||||
GetExternalAccountKey(ctx context.Context, provisionerName string, keyID string) (*ExternalAccountKey, error)
|
GetExternalAccountKey(ctx context.Context, provisionerName string, keyID string) (*ExternalAccountKey, error)
|
||||||
|
DeleteExternalAccountKey(ctx context.Context, keyID string) error
|
||||||
UpdateExternalAccountKey(ctx context.Context, provisionerName string, eak *ExternalAccountKey) error
|
UpdateExternalAccountKey(ctx context.Context, provisionerName string, eak *ExternalAccountKey) error
|
||||||
|
|
||||||
CreateNonce(ctx context.Context) (Nonce, error)
|
CreateNonce(ctx context.Context) (Nonce, error)
|
||||||
|
@ -53,6 +54,7 @@ type MockDB struct {
|
||||||
|
|
||||||
MockCreateExternalAccountKey func(ctx context.Context, provisionerName string, name string) (*ExternalAccountKey, error)
|
MockCreateExternalAccountKey func(ctx context.Context, provisionerName string, name string) (*ExternalAccountKey, error)
|
||||||
MockGetExternalAccountKey func(ctx context.Context, provisionerName string, keyID string) (*ExternalAccountKey, error)
|
MockGetExternalAccountKey func(ctx context.Context, provisionerName string, keyID string) (*ExternalAccountKey, error)
|
||||||
|
MockDeleteExternalAccountKey func(ctx context.Context, keyID string) error
|
||||||
MockUpdateExternalAccountKey func(ctx context.Context, provisionerName string, eak *ExternalAccountKey) error
|
MockUpdateExternalAccountKey func(ctx context.Context, provisionerName string, eak *ExternalAccountKey) error
|
||||||
|
|
||||||
MockCreateNonce func(ctx context.Context) (Nonce, error)
|
MockCreateNonce func(ctx context.Context) (Nonce, error)
|
||||||
|
@ -138,6 +140,17 @@ func (m *MockDB) GetExternalAccountKey(ctx context.Context, provisionerName stri
|
||||||
return m.MockRet1.(*ExternalAccountKey), m.MockError
|
return m.MockRet1.(*ExternalAccountKey), m.MockError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteExternalAccountKey mock
|
||||||
|
func (m *MockDB) DeleteExternalAccountKey(ctx context.Context, keyID string) error {
|
||||||
|
if m.MockDeleteExternalAccountKey != nil {
|
||||||
|
return m.MockDeleteExternalAccountKey(ctx, keyID)
|
||||||
|
} else if m.MockError != nil {
|
||||||
|
return m.MockError
|
||||||
|
}
|
||||||
|
return m.MockError
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateExternalAccountKey mock
|
||||||
func (m *MockDB) UpdateExternalAccountKey(ctx context.Context, provisionerName string, eak *ExternalAccountKey) error {
|
func (m *MockDB) UpdateExternalAccountKey(ctx context.Context, provisionerName string, eak *ExternalAccountKey) error {
|
||||||
if m.MockUpdateExternalAccountKey != nil {
|
if m.MockUpdateExternalAccountKey != nil {
|
||||||
return m.MockUpdateExternalAccountKey(ctx, provisionerName, eak)
|
return m.MockUpdateExternalAccountKey(ctx, provisionerName, eak)
|
||||||
|
|
|
@ -221,6 +221,14 @@ func (db *DB) GetExternalAccountKey(ctx context.Context, provisionerName string,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) DeleteExternalAccountKey(ctx context.Context, keyID string) error {
|
||||||
|
err := db.db.Del(externalAccountKeyTable, []byte(keyID))
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error deleting ACME EAB Key with Key ID: %s", keyID)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (db *DB) UpdateExternalAccountKey(ctx context.Context, provisionerName string, eak *acme.ExternalAccountKey) error {
|
func (db *DB) UpdateExternalAccountKey(ctx context.Context, provisionerName string, eak *acme.ExternalAccountKey) error {
|
||||||
old, err := db.getDBExternalAccountKey(ctx, eak.ID)
|
old, err := db.getDBExternalAccountKey(ctx, eak.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package api
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi"
|
||||||
"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"
|
"go.step.sm/linkedca"
|
||||||
|
@ -60,6 +61,18 @@ func (h *Handler) CreateExternalAccountKey(w http.ResponseWriter, r *http.Reques
|
||||||
api.ProtoJSONStatus(w, response, http.StatusCreated)
|
api.ProtoJSONStatus(w, response, http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteExternalAccountKey deletes an ACME External Account Key.
|
||||||
|
func (h *Handler) DeleteExternalAccountKey(w http.ResponseWriter, r *http.Request) {
|
||||||
|
id := chi.URLParam(r, "id")
|
||||||
|
|
||||||
|
if err := h.acmeDB.DeleteExternalAccountKey(r.Context(), id); err != nil {
|
||||||
|
api.WriteError(w, admin.WrapErrorISE(err, "error deleting ACME EAB Key %s", id))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
api.JSON(w, &DeleteResponse{Status: "ok"})
|
||||||
|
}
|
||||||
|
|
||||||
// GetExternalAccountKeys returns a segment of ACME EAB Keys.
|
// GetExternalAccountKeys returns a segment of ACME EAB Keys.
|
||||||
func (h *Handler) GetExternalAccountKeys(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) GetExternalAccountKeys(w http.ResponseWriter, r *http.Request) {
|
||||||
// cursor, limit, err := api.ParseCursor(r)
|
// cursor, limit, err := api.ParseCursor(r)
|
||||||
|
|
|
@ -46,4 +46,5 @@ func (h *Handler) Route(r api.Router) {
|
||||||
// ACME External Account Binding Keys
|
// ACME External Account Binding Keys
|
||||||
r.MethodFunc("GET", "/acme/eab", authnz(h.GetExternalAccountKeys))
|
r.MethodFunc("GET", "/acme/eab", authnz(h.GetExternalAccountKeys))
|
||||||
r.MethodFunc("POST", "/acme/eab", authnz(h.CreateExternalAccountKey))
|
r.MethodFunc("POST", "/acme/eab", authnz(h.CreateExternalAccountKey))
|
||||||
|
r.MethodFunc("DELETE", "/acme/eab/{id}", authnz(h.DeleteExternalAccountKey))
|
||||||
}
|
}
|
||||||
|
|
|
@ -634,6 +634,34 @@ retry:
|
||||||
return eabKey, nil
|
return eabKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveExternalAccountKey performs the DELETE /admin/acme/eab/{key_id} request to the CA.
|
||||||
|
func (c *AdminClient) RemoveExternalAccountKey(keyID string) error {
|
||||||
|
var retried bool
|
||||||
|
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "acme/eab", keyID)})
|
||||||
|
tok, err := c.generateAdminToken(u.Path)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error generating admin token")
|
||||||
|
}
|
||||||
|
req, err := http.NewRequest("DELETE", u.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "create DELETE %s request failed", u)
|
||||||
|
}
|
||||||
|
req.Header.Add("Authorization", tok)
|
||||||
|
retry:
|
||||||
|
resp, err := c.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "client DELETE %s failed", u)
|
||||||
|
}
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
if !retried && c.retryOnError(resp) {
|
||||||
|
retried = true
|
||||||
|
goto retry
|
||||||
|
}
|
||||||
|
return readAdminError(resp.Body)
|
||||||
|
}
|
||||||
|
return 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) ([]*linkedca.EABKey, error) {
|
func (c *AdminClient) GetExternalAccountKeys(opts ...AdminOption) ([]*linkedca.EABKey, error) {
|
||||||
var (
|
var (
|
||||||
|
|
Loading…
Reference in a new issue