Skip to content

Commit 4e06bdb

Browse files
committed
Add SignWithContext method to authority and mocks
1 parent b2301ea commit 4e06bdb

11 files changed

+69
-31
lines changed

acme/api/revoke_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,10 @@ func (m *mockCA) Sign(*x509.CertificateRequest, provisioner.SignOptions, ...prov
285285
return nil, nil
286286
}
287287

288+
func (m *mockCA) SignWithContext(context.Context, *x509.CertificateRequest, provisioner.SignOptions, ...provisioner.SignOption) ([]*x509.Certificate, error) {
289+
return nil, nil
290+
}
291+
288292
func (m *mockCA) AreSANsAllowed(ctx context.Context, sans []string) error {
289293
if m.MockAreSANsallowed != nil {
290294
return m.MockAreSANsallowed(ctx, sans)

acme/common.go

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ var clock Clock
2222
// CertificateAuthority is the interface implemented by a CA authority.
2323
type CertificateAuthority interface {
2424
Sign(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
25+
SignWithContext(ctx context.Context, cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
2526
AreSANsAllowed(ctx context.Context, sans []string) error
2627
IsRevoked(sn string) (bool, error)
2728
Revoke(context.Context, *authority.RevokeOptions) error

acme/order_test.go

+10
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ func TestOrder_UpdateStatus(t *testing.T) {
272272

273273
type mockSignAuth struct {
274274
sign func(csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
275+
signWithContext func(ctx context.Context, csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
275276
areSANsAllowed func(ctx context.Context, sans []string) error
276277
loadProvisionerByName func(string) (provisioner.Interface, error)
277278
ret1, ret2 interface{}
@@ -287,6 +288,15 @@ func (m *mockSignAuth) Sign(csr *x509.CertificateRequest, signOpts provisioner.S
287288
return []*x509.Certificate{m.ret1.(*x509.Certificate), m.ret2.(*x509.Certificate)}, m.err
288289
}
289290

291+
func (m *mockSignAuth) SignWithContext(ctx context.Context, csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
292+
if m.signWithContext != nil {
293+
return m.signWithContext(ctx, csr, signOpts, extraOpts...)
294+
} else if m.err != nil {
295+
return nil, m.err
296+
}
297+
return []*x509.Certificate{m.ret1.(*x509.Certificate), m.ret2.(*x509.Certificate)}, m.err
298+
}
299+
290300
func (m *mockSignAuth) AreSANsAllowed(ctx context.Context, sans []string) error {
291301
if m.areSANsAllowed != nil {
292302
return m.areSANsAllowed(ctx, sans)

api/api.go

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type Authority interface {
4242
GetTLSOptions() *config.TLSOptions
4343
Root(shasum string) (*x509.Certificate, error)
4444
Sign(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
45+
SignWithContext(ctx context.Context, cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
4546
Renew(peer *x509.Certificate) ([]*x509.Certificate, error)
4647
RenewContext(ctx context.Context, peer *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error)
4748
Rekey(peer *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error)

api/api_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ type mockAuthority struct {
193193
getTLSOptions func() *authority.TLSOptions
194194
root func(shasum string) (*x509.Certificate, error)
195195
sign func(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
196+
signWithContext func(ctx context.Context, cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
196197
renew func(cert *x509.Certificate) ([]*x509.Certificate, error)
197198
rekey func(oldCert *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error)
198199
renewContext func(ctx context.Context, oldCert *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error)
@@ -261,6 +262,13 @@ func (m *mockAuthority) Sign(cr *x509.CertificateRequest, opts provisioner.SignO
261262
return []*x509.Certificate{m.ret1.(*x509.Certificate), m.ret2.(*x509.Certificate)}, m.err
262263
}
263264

265+
func (m *mockAuthority) SignWithContext(ctx context.Context, cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
266+
if m.signWithContext != nil {
267+
return m.signWithContext(ctx, cr, opts, signOpts...)
268+
}
269+
return []*x509.Certificate{m.ret1.(*x509.Certificate), m.ret2.(*x509.Certificate)}, m.err
270+
}
271+
264272
func (m *mockAuthority) Renew(cert *x509.Certificate) ([]*x509.Certificate, error) {
265273
if m.renew != nil {
266274
return m.renew(cert)

authority/provisioner/webhook.go

+9-10
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type WebhookController struct {
3737

3838
// Enrich fetches data from remote servers and adds returned data to the
3939
// templateData
40-
func (wc *WebhookController) Enrich(req *webhook.RequestBody) error {
40+
func (wc *WebhookController) Enrich(ctx context.Context, req *webhook.RequestBody) error {
4141
if wc == nil {
4242
return nil
4343
}
@@ -56,11 +56,11 @@ func (wc *WebhookController) Enrich(req *webhook.RequestBody) error {
5656
if !wc.isCertTypeOK(wh) {
5757
continue
5858
}
59-
// TODO(hs): propagate context from above
60-
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
61-
defer cancel()
6259

63-
resp, err := wh.DoWithContext(ctx, wc.client, req, wc.TemplateData)
60+
whCtx, cancel := context.WithTimeout(ctx, time.Second*10)
61+
defer cancel() //nolint:gocritic // every request canceled with its own timeout
62+
63+
resp, err := wh.DoWithContext(whCtx, wc.client, req, wc.TemplateData)
6464
if err != nil {
6565
return err
6666
}
@@ -73,7 +73,7 @@ func (wc *WebhookController) Enrich(req *webhook.RequestBody) error {
7373
}
7474

7575
// Authorize checks that all remote servers allow the request
76-
func (wc *WebhookController) Authorize(req *webhook.RequestBody) error {
76+
func (wc *WebhookController) Authorize(ctx context.Context, req *webhook.RequestBody) error {
7777
if wc == nil {
7878
return nil
7979
}
@@ -93,11 +93,10 @@ func (wc *WebhookController) Authorize(req *webhook.RequestBody) error {
9393
continue
9494
}
9595

96-
// TODO(hs): propagate context from above
97-
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
98-
defer cancel()
96+
whCtx, cancel := context.WithTimeout(ctx, time.Second*10)
97+
defer cancel() //nolint:gocritic // every request canceled with its own timeout
9998

100-
resp, err := wh.DoWithContext(ctx, wc.client, req, wc.TemplateData)
99+
resp, err := wh.DoWithContext(whCtx, wc.client, req, wc.TemplateData)
101100
if err != nil {
102101
return err
103102
}

authority/provisioner/webhook_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ func TestWebhookController_Enrich(t *testing.T) {
242242
wh.URL = ts.URL
243243
}
244244

245-
err := test.ctl.Enrich(test.req)
245+
err := test.ctl.Enrich(context.Background(), test.req)
246246
if (err != nil) != test.expectErr {
247247
t.Fatalf("Got err %v, want %v", err, test.expectErr)
248248
}
@@ -352,7 +352,7 @@ func TestWebhookController_Authorize(t *testing.T) {
352352
wh.URL = ts.URL
353353
}
354354

355-
err := test.ctl.Authorize(test.req)
355+
err := test.ctl.Authorize(context.Background(), test.req)
356356
if (err != nil) != test.expectErr {
357357
t.Fatalf("Got err %v, want %v", err, test.expectErr)
358358
}

authority/ssh.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ func (a *Authority) GetSSHBastion(ctx context.Context, user, hostname string) (*
146146
}
147147

148148
// SignSSH creates a signed SSH certificate with the given public key and options.
149-
func (a *Authority) SignSSH(_ context.Context, key ssh.PublicKey, opts provisioner.SignSSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error) {
149+
func (a *Authority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisioner.SignSSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error) {
150150
var (
151151
certOptions []sshutil.Option
152152
mods []provisioner.SSHCertModifier
@@ -205,7 +205,7 @@ func (a *Authority) SignSSH(_ context.Context, key ssh.PublicKey, opts provision
205205
}
206206

207207
// Call enriching webhooks
208-
if err := callEnrichingWebhooksSSH(webhookCtl, cr); err != nil {
208+
if err := callEnrichingWebhooksSSH(ctx, webhookCtl, cr); err != nil {
209209
return nil, errs.ApplyOptions(
210210
errs.ForbiddenErr(err, err.Error()),
211211
errs.WithKeyVal("signOptions", signOpts),
@@ -277,7 +277,7 @@ func (a *Authority) SignSSH(_ context.Context, key ssh.PublicKey, opts provision
277277
}
278278

279279
// Send certificate to webhooks for authorization
280-
if err := callAuthorizingWebhooksSSH(webhookCtl, certificate, certTpl); err != nil {
280+
if err := callAuthorizingWebhooksSSH(ctx, webhookCtl, certificate, certTpl); err != nil {
281281
return nil, errs.ApplyOptions(
282282
errs.ForbiddenErr(err, "authority.SignSSH: error signing certificate"),
283283
)
@@ -653,7 +653,7 @@ func (a *Authority) getAddUserCommand(principal string) string {
653653
return strings.ReplaceAll(cmd, "<principal>", principal)
654654
}
655655

656-
func callEnrichingWebhooksSSH(webhookCtl webhookController, cr sshutil.CertificateRequest) error {
656+
func callEnrichingWebhooksSSH(ctx context.Context, webhookCtl webhookController, cr sshutil.CertificateRequest) error {
657657
if webhookCtl == nil {
658658
return nil
659659
}
@@ -663,10 +663,10 @@ func callEnrichingWebhooksSSH(webhookCtl webhookController, cr sshutil.Certifica
663663
if err != nil {
664664
return err
665665
}
666-
return webhookCtl.Enrich(whEnrichReq)
666+
return webhookCtl.Enrich(ctx, whEnrichReq)
667667
}
668668

669-
func callAuthorizingWebhooksSSH(webhookCtl webhookController, cert *sshutil.Certificate, certTpl *ssh.Certificate) error {
669+
func callAuthorizingWebhooksSSH(ctx context.Context, webhookCtl webhookController, cert *sshutil.Certificate, certTpl *ssh.Certificate) error {
670670
if webhookCtl == nil {
671671
return nil
672672
}
@@ -676,5 +676,5 @@ func callAuthorizingWebhooksSSH(webhookCtl webhookController, cert *sshutil.Cert
676676
if err != nil {
677677
return err
678678
}
679-
return webhookCtl.Authorize(whAuthBody)
679+
return webhookCtl.Authorize(ctx, whAuthBody)
680680
}

authority/tls.go

+16-7
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,17 @@ func withDefaultASN1DN(def *config.ASN1DN) provisioner.CertificateModifierFunc {
9191
}
9292
}
9393

94-
// Sign creates a signed certificate from a certificate signing request.
94+
// Sign creates a signed certificate from a certificate signing request. It
95+
// creates a new context.Context, and calls into SignWithContext.
96+
//
97+
// Deprecated: Use authority.SignWithContext with an actual context.Context.
9598
func (a *Authority) Sign(csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
99+
return a.SignWithContext(context.Background(), csr, signOpts, extraOpts...)
100+
}
101+
102+
// SignWithContext creates a signed certificate from a certificate signing request,
103+
// taking the provided context.Context.
104+
func (a *Authority) SignWithContext(ctx context.Context, csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
96105
var (
97106
certOptions []x509util.Option
98107
certValidators []provisioner.CertificateValidator
@@ -163,7 +172,7 @@ func (a *Authority) Sign(csr *x509.CertificateRequest, signOpts provisioner.Sign
163172
}
164173
}
165174

166-
if err := callEnrichingWebhooksX509(webhookCtl, attData, csr); err != nil {
175+
if err := callEnrichingWebhooksX509(ctx, webhookCtl, attData, csr); err != nil {
167176
return nil, errs.ApplyOptions(
168177
errs.ForbiddenErr(err, err.Error()),
169178
errs.WithKeyVal("csr", csr),
@@ -256,7 +265,7 @@ func (a *Authority) Sign(csr *x509.CertificateRequest, signOpts provisioner.Sign
256265
}
257266

258267
// Send certificate to webhooks for authorization
259-
if err := callAuthorizingWebhooksX509(webhookCtl, cert, leaf, attData); err != nil {
268+
if err := callAuthorizingWebhooksX509(ctx, webhookCtl, cert, leaf, attData); err != nil {
260269
return nil, errs.ApplyOptions(
261270
errs.ForbiddenErr(err, "error creating certificate"),
262271
opts...,
@@ -952,7 +961,7 @@ func templatingError(err error) error {
952961
return errors.Wrap(cause, "error applying certificate template")
953962
}
954963

955-
func callEnrichingWebhooksX509(webhookCtl webhookController, attData *provisioner.AttestationData, csr *x509.CertificateRequest) error {
964+
func callEnrichingWebhooksX509(ctx context.Context, webhookCtl webhookController, attData *provisioner.AttestationData, csr *x509.CertificateRequest) error {
956965
if webhookCtl == nil {
957966
return nil
958967
}
@@ -969,10 +978,10 @@ func callEnrichingWebhooksX509(webhookCtl webhookController, attData *provisione
969978
if err != nil {
970979
return err
971980
}
972-
return webhookCtl.Enrich(whEnrichReq)
981+
return webhookCtl.Enrich(ctx, whEnrichReq)
973982
}
974983

975-
func callAuthorizingWebhooksX509(webhookCtl webhookController, cert *x509util.Certificate, leaf *x509.Certificate, attData *provisioner.AttestationData) error {
984+
func callAuthorizingWebhooksX509(ctx context.Context, webhookCtl webhookController, cert *x509util.Certificate, leaf *x509.Certificate, attData *provisioner.AttestationData) error {
976985
if webhookCtl == nil {
977986
return nil
978987
}
@@ -989,5 +998,5 @@ func callAuthorizingWebhooksX509(webhookCtl webhookController, cert *x509util.Ce
989998
if err != nil {
990999
return err
9911000
}
992-
return webhookCtl.Authorize(whAuthBody)
1001+
return webhookCtl.Authorize(ctx, whAuthBody)
9931002
}

authority/webhook.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package authority
22

3-
import "github.com/smallstep/certificates/webhook"
3+
import (
4+
"context"
5+
6+
"github.com/smallstep/certificates/webhook"
7+
)
48

59
type webhookController interface {
6-
Enrich(*webhook.RequestBody) error
7-
Authorize(*webhook.RequestBody) error
10+
Enrich(context.Context, *webhook.RequestBody) error
11+
Authorize(context.Context, *webhook.RequestBody) error
812
}

authority/webhook_test.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package authority
22

33
import (
4+
"context"
5+
46
"github.com/smallstep/certificates/authority/provisioner"
57
"github.com/smallstep/certificates/webhook"
68
)
@@ -14,14 +16,14 @@ type mockWebhookController struct {
1416

1517
var _ webhookController = &mockWebhookController{}
1618

17-
func (wc *mockWebhookController) Enrich(*webhook.RequestBody) error {
19+
func (wc *mockWebhookController) Enrich(context.Context, *webhook.RequestBody) error {
1820
for key, data := range wc.respData {
1921
wc.templateData.SetWebhook(key, data)
2022
}
2123

2224
return wc.enrichErr
2325
}
2426

25-
func (wc *mockWebhookController) Authorize(*webhook.RequestBody) error {
27+
func (wc *mockWebhookController) Authorize(context.Context, *webhook.RequestBody) error {
2628
return wc.authorizeErr
2729
}

0 commit comments

Comments
 (0)