Skip to content

Commit 9d09f5e

Browse files
committed
Add support for deleting ACME EAB keys
1 parent a98fe03 commit 9d09f5e

File tree

5 files changed

+63
-0
lines changed

5 files changed

+63
-0
lines changed

Diff for: acme/db.go

+13
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type DB interface {
2121

2222
CreateExternalAccountKey(ctx context.Context, provisionerName string, name string) (*ExternalAccountKey, error)
2323
GetExternalAccountKey(ctx context.Context, provisionerName string, keyID string) (*ExternalAccountKey, error)
24+
DeleteExternalAccountKey(ctx context.Context, keyID string) error
2425
UpdateExternalAccountKey(ctx context.Context, provisionerName string, eak *ExternalAccountKey) error
2526

2627
CreateNonce(ctx context.Context) (Nonce, error)
@@ -53,6 +54,7 @@ type MockDB struct {
5354

5455
MockCreateExternalAccountKey func(ctx context.Context, provisionerName string, name string) (*ExternalAccountKey, error)
5556
MockGetExternalAccountKey func(ctx context.Context, provisionerName string, keyID string) (*ExternalAccountKey, error)
57+
MockDeleteExternalAccountKey func(ctx context.Context, keyID string) error
5658
MockUpdateExternalAccountKey func(ctx context.Context, provisionerName string, eak *ExternalAccountKey) error
5759

5860
MockCreateNonce func(ctx context.Context) (Nonce, error)
@@ -138,6 +140,17 @@ func (m *MockDB) GetExternalAccountKey(ctx context.Context, provisionerName stri
138140
return m.MockRet1.(*ExternalAccountKey), m.MockError
139141
}
140142

143+
// DeleteExternalAccountKey mock
144+
func (m *MockDB) DeleteExternalAccountKey(ctx context.Context, keyID string) error {
145+
if m.MockDeleteExternalAccountKey != nil {
146+
return m.MockDeleteExternalAccountKey(ctx, keyID)
147+
} else if m.MockError != nil {
148+
return m.MockError
149+
}
150+
return m.MockError
151+
}
152+
153+
// UpdateExternalAccountKey mock
141154
func (m *MockDB) UpdateExternalAccountKey(ctx context.Context, provisionerName string, eak *ExternalAccountKey) error {
142155
if m.MockUpdateExternalAccountKey != nil {
143156
return m.MockUpdateExternalAccountKey(ctx, provisionerName, eak)

Diff for: acme/db/nosql/account.go

+8
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,14 @@ func (db *DB) GetExternalAccountKey(ctx context.Context, provisionerName string,
221221
}, nil
222222
}
223223

224+
func (db *DB) DeleteExternalAccountKey(ctx context.Context, keyID string) error {
225+
err := db.db.Del(externalAccountKeyTable, []byte(keyID))
226+
if err != nil {
227+
return errors.Wrapf(err, "error deleting ACME EAB Key with Key ID: %s", keyID)
228+
}
229+
return nil
230+
}
231+
224232
func (db *DB) UpdateExternalAccountKey(ctx context.Context, provisionerName string, eak *acme.ExternalAccountKey) error {
225233
old, err := db.getDBExternalAccountKey(ctx, eak.ID)
226234
if err != nil {

Diff for: authority/admin/api/acme.go

+13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package api
33
import (
44
"net/http"
55

6+
"github.com/go-chi/chi"
67
"github.com/smallstep/certificates/api"
78
"github.com/smallstep/certificates/authority/admin"
89
"go.step.sm/linkedca"
@@ -60,6 +61,18 @@ func (h *Handler) CreateExternalAccountKey(w http.ResponseWriter, r *http.Reques
6061
api.ProtoJSONStatus(w, response, http.StatusCreated)
6162
}
6263

64+
// DeleteExternalAccountKey deletes an ACME External Account Key.
65+
func (h *Handler) DeleteExternalAccountKey(w http.ResponseWriter, r *http.Request) {
66+
id := chi.URLParam(r, "id")
67+
68+
if err := h.acmeDB.DeleteExternalAccountKey(r.Context(), id); err != nil {
69+
api.WriteError(w, admin.WrapErrorISE(err, "error deleting ACME EAB Key %s", id))
70+
return
71+
}
72+
73+
api.JSON(w, &DeleteResponse{Status: "ok"})
74+
}
75+
6376
// GetExternalAccountKeys returns a segment of ACME EAB Keys.
6477
func (h *Handler) GetExternalAccountKeys(w http.ResponseWriter, r *http.Request) {
6578
// cursor, limit, err := api.ParseCursor(r)

Diff for: authority/admin/api/handler.go

+1
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ func (h *Handler) Route(r api.Router) {
4646
// ACME External Account Binding Keys
4747
r.MethodFunc("GET", "/acme/eab", authnz(h.GetExternalAccountKeys))
4848
r.MethodFunc("POST", "/acme/eab", authnz(h.CreateExternalAccountKey))
49+
r.MethodFunc("DELETE", "/acme/eab/{id}", authnz(h.DeleteExternalAccountKey))
4950
}

Diff for: ca/adminClient.go

+28
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,34 @@ retry:
634634
return eabKey, nil
635635
}
636636

637+
// RemoveExternalAccountKey performs the DELETE /admin/acme/eab/{key_id} request to the CA.
638+
func (c *AdminClient) RemoveExternalAccountKey(keyID string) error {
639+
var retried bool
640+
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "acme/eab", keyID)})
641+
tok, err := c.generateAdminToken(u.Path)
642+
if err != nil {
643+
return errors.Wrapf(err, "error generating admin token")
644+
}
645+
req, err := http.NewRequest("DELETE", u.String(), nil)
646+
if err != nil {
647+
return errors.Wrapf(err, "create DELETE %s request failed", u)
648+
}
649+
req.Header.Add("Authorization", tok)
650+
retry:
651+
resp, err := c.client.Do(req)
652+
if err != nil {
653+
return errors.Wrapf(err, "client DELETE %s failed", u)
654+
}
655+
if resp.StatusCode >= 400 {
656+
if !retried && c.retryOnError(resp) {
657+
retried = true
658+
goto retry
659+
}
660+
return readAdminError(resp.Body)
661+
}
662+
return nil
663+
}
664+
637665
// GetExternalAccountKeys returns all ACME EAB Keys from the GET /admin/acme/eab request to the CA.
638666
func (c *AdminClient) GetExternalAccountKeys(opts ...AdminOption) ([]*linkedca.EABKey, error) {
639667
var (

0 commit comments

Comments
 (0)