Skip to content

Commit 10f6a90

Browse files
committed
Let the CA determine the RA lifetime
When the RA mode with StepCAS is used, let the CA decide which lifetime the RA should get instead of requiring always 24h. This commit also fixes linter warnings. Related to smallstep#1094
1 parent ef1631b commit 10f6a90

32 files changed

+179
-38
lines changed

acme/api/middleware.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,10 @@ func validateJWS(next nextHTTP) nextHTTP {
147147

148148
sig := jws.Signatures[0]
149149
uh := sig.Unprotected
150-
if len(uh.KeyID) > 0 ||
150+
if uh.KeyID != "" ||
151151
uh.JSONWebKey != nil ||
152-
len(uh.Algorithm) > 0 ||
153-
len(uh.Nonce) > 0 ||
152+
uh.Algorithm != "" ||
153+
uh.Nonce != "" ||
154154
len(uh.ExtraHeaders) > 0 {
155155
render.Error(w, acme.NewError(acme.ErrorMalformedType, "unprotected header must not be used"))
156156
return
@@ -199,7 +199,7 @@ func validateJWS(next nextHTTP) nextHTTP {
199199
return
200200
}
201201

202-
if hdr.JSONWebKey != nil && len(hdr.KeyID) > 0 {
202+
if hdr.JSONWebKey != nil && hdr.KeyID != "" {
203203
render.Error(w, acme.NewError(acme.ErrorMalformedType, "jwk and kid are mutually exclusive"))
204204
return
205205
}

api/api.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ func LogSSHCertificate(w http.ResponseWriter, cert *ssh.Certificate) {
565565
func ParseCursor(r *http.Request) (cursor string, limit int, err error) {
566566
q := r.URL.Query()
567567
cursor = q.Get("cursor")
568-
if v := q.Get("limit"); len(v) > 0 {
568+
if v := q.Get("limit"); v != "" {
569569
limit, err = strconv.Atoi(v)
570570
if err != nil {
571571
return "", 0, errs.BadRequestErr(err, "limit '%s' is not an integer", v)

api/revoke.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func Revoke(w http.ResponseWriter, r *http.Request) {
7878

7979
// A token indicates that we are using the api via a provisioner token,
8080
// otherwise it is assumed that the certificate is revoking itself over mTLS.
81-
if len(body.OTT) > 0 {
81+
if body.OTT != "" {
8282
logOtt(w, body.OTT)
8383
if _, err := a.Authorize(ctx, body.OTT); err != nil {
8484
render.Error(w, errs.UnauthorizedErr(err))

authority/admin/api/provisioner.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func GetProvisioner(w http.ResponseWriter, r *http.Request) {
3838
auth := mustAuthority(ctx)
3939
db := admin.MustFromContext(ctx)
4040

41-
if len(id) > 0 {
41+
if id != "" {
4242
if p, err = auth.LoadProvisionerByID(id); err != nil {
4343
render.Error(w, admin.WrapErrorISE(err, "error loading provisioner %s", id))
4444
return
@@ -116,7 +116,7 @@ func DeleteProvisioner(w http.ResponseWriter, r *http.Request) {
116116
name := chi.URLParam(r, "name")
117117
auth := mustAuthority(r.Context())
118118

119-
if len(id) > 0 {
119+
if id != "" {
120120
if p, err = auth.LoadProvisionerByID(id); err != nil {
121121
render.Error(w, admin.WrapErrorISE(err, "error loading provisioner %s", id))
122122
return

authority/admin/db/nosql/admin_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,7 @@ func TestDB_CreateAdmin(t *testing.T) {
857857
var _dba = new(dbAdmin)
858858
assert.FatalError(t, json.Unmarshal(nu, _dba))
859859

860-
assert.True(t, len(_dba.ID) > 0 && _dba.ID == string(key))
860+
assert.True(t, _dba.ID != "" && _dba.ID == string(key))
861861
assert.Equals(t, _dba.AuthorityID, adm.AuthorityId)
862862
assert.Equals(t, _dba.ProvisionerID, adm.ProvisionerId)
863863
assert.Equals(t, _dba.Subject, adm.Subject)
@@ -890,7 +890,7 @@ func TestDB_CreateAdmin(t *testing.T) {
890890
var _dba = new(dbAdmin)
891891
assert.FatalError(t, json.Unmarshal(nu, _dba))
892892

893-
assert.True(t, len(_dba.ID) > 0 && _dba.ID == string(key))
893+
assert.True(t, _dba.ID != "" && _dba.ID == string(key))
894894
assert.Equals(t, _dba.AuthorityID, adm.AuthorityId)
895895
assert.Equals(t, _dba.ProvisionerID, adm.ProvisionerId)
896896
assert.Equals(t, _dba.Subject, adm.Subject)

authority/admin/db/nosql/provisioner_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,7 @@ func TestDB_CreateProvisioner(t *testing.T) {
906906
var _dbp = new(dbProvisioner)
907907
assert.FatalError(t, json.Unmarshal(nu, _dbp))
908908

909-
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key))
909+
assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
910910
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
911911
assert.Equals(t, _dbp.Type, prov.Type)
912912
assert.Equals(t, _dbp.Name, prov.Name)
@@ -944,7 +944,7 @@ func TestDB_CreateProvisioner(t *testing.T) {
944944
var _dbp = new(dbProvisioner)
945945
assert.FatalError(t, json.Unmarshal(nu, _dbp))
946946

947-
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key))
947+
assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
948948
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
949949
assert.Equals(t, _dbp.Type, prov.Type)
950950
assert.Equals(t, _dbp.Name, prov.Name)
@@ -1093,7 +1093,7 @@ func TestDB_UpdateProvisioner(t *testing.T) {
10931093
var _dbp = new(dbProvisioner)
10941094
assert.FatalError(t, json.Unmarshal(nu, _dbp))
10951095

1096-
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key))
1096+
assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
10971097
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
10981098
assert.Equals(t, _dbp.Type, prov.Type)
10991099
assert.Equals(t, _dbp.Name, prov.Name)
@@ -1188,7 +1188,7 @@ func TestDB_UpdateProvisioner(t *testing.T) {
11881188
var _dbp = new(dbProvisioner)
11891189
assert.FatalError(t, json.Unmarshal(nu, _dbp))
11901190

1191-
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key))
1191+
assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
11921192
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
11931193
assert.Equals(t, _dbp.Type, prov.Type)
11941194
assert.Equals(t, _dbp.Name, prov.Name)

authority/internal/constraints/verify.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ func matchURIConstraint(uri *url.URL, constraint string) (bool, error) {
203203
// domainToReverseLabels converts a textual domain name like foo.example.com to
204204
// the list of labels in reverse order, e.g. ["com", "example", "foo"].
205205
func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) {
206-
for len(domain) > 0 {
206+
for domain != "" {
207207
if i := strings.LastIndexByte(domain, '.'); i == -1 {
208208
reverseLabels = append(reverseLabels, domain)
209209
domain = ""
@@ -316,7 +316,7 @@ func parseRFC2821Mailbox(in string) (mailbox rfc2821Mailbox, ok bool) {
316316
} else {
317317
// Atom ("." Atom)*
318318
NextChar:
319-
for len(in) > 0 {
319+
for in != "" {
320320
// atext from RFC 2822, Section 3.2.4
321321
c := in[0]
322322

authority/provisioner/collection.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func (c *Collection) LoadByToken(token *jose.JSONWebToken, claims *jose.Claims)
125125
}
126126

127127
// Try with azp (OIDC)
128-
if len(payload.AuthorizedParty) > 0 {
128+
if payload.AuthorizedParty != "" {
129129
if p, ok := c.LoadByTokenID(payload.AuthorizedParty); ok {
130130
return p, ok
131131
}

authority/provisioner/jwk.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func (p *JWK) GetType() Type {
8787

8888
// GetEncryptedKey returns the base provisioner encrypted key if it's defined.
8989
func (p *JWK) GetEncryptedKey() (string, string, bool) {
90-
return p.Key.KeyID, p.EncryptedKey, len(p.EncryptedKey) > 0
90+
return p.Key.KeyID, p.EncryptedKey, p.EncryptedKey != ""
9191
}
9292

9393
// Init initializes and validates the fields of a JWK type.

authority/provisioner/keystore.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func getKeysFromJWKsURI(uri string) (jose.JSONWebKeySet, time.Duration, error) {
105105

106106
func getCacheAge(cacheControl string) time.Duration {
107107
age := defaultCacheAge
108-
if len(cacheControl) > 0 {
108+
if cacheControl != "" {
109109
match := maxAgeRegex.FindAllStringSubmatch(cacheControl, -1)
110110
if len(match) > 0 {
111111
if len(match[0]) == 2 {

authority/provisioner/scep.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ func (s *SCEP) Init(config Config) (err error) {
304304
}
305305
}
306306

307-
if decryptionKeyURI := s.DecrypterKeyURI; len(decryptionKeyURI) > 0 {
307+
if decryptionKeyURI := s.DecrypterKeyURI; decryptionKeyURI != "" {
308308
u, err := uri.Parse(s.DecrypterKeyURI)
309309
if err != nil {
310310
return fmt.Errorf("failed parsing decrypter key: %w", err)

authority/provisioner/x5c_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ func TestX5C_AuthorizeSSHSign(t *testing.T) {
813813
}
814814
tot++
815815
}
816-
if len(tc.claims.Step.SSH.CertType) > 0 {
816+
if tc.claims.Step.SSH.CertType != "" {
817817
assert.Equals(t, tot, 12)
818818
} else {
819819
assert.Equals(t, tot, 10)

authority/provisioners.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -608,19 +608,19 @@ func provisionerWebhookToLinkedca(pwh *provisioner.Webhook) *linkedca.Webhook {
608608
}
609609

610610
func durationsToCertificates(d *linkedca.Durations) (min, max, def *provisioner.Duration, err error) {
611-
if len(d.Min) > 0 {
611+
if d.Min != "" {
612612
min, err = provisioner.NewDuration(d.Min)
613613
if err != nil {
614614
return nil, nil, nil, admin.WrapErrorISE(err, "error parsing minimum duration '%s'", d.Min)
615615
}
616616
}
617-
if len(d.Max) > 0 {
617+
if d.Max != "" {
618618
max, err = provisioner.NewDuration(d.Max)
619619
if err != nil {
620620
return nil, nil, nil, admin.WrapErrorISE(err, "error parsing maximum duration '%s'", d.Max)
621621
}
622622
}
623-
if len(d.Default) > 0 {
623+
if d.Default != "" {
624624
def, err = provisioner.NewDuration(d.Default)
625625
if err != nil {
626626
return nil, nil, nil, admin.WrapErrorISE(err, "error parsing default duration '%s'", d.Default)

authority/root.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func (a *Authority) GetRoots() ([]*x509.Certificate, error) {
4545
// GetFederation returns all the root certificates in the federation.
4646
// This method implements the Authority interface.
4747
func (a *Authority) GetFederation() (federation []*x509.Certificate, err error) {
48-
a.certificates.Range(func(k, v interface{}) bool {
48+
a.certificates.Range(func(_, v interface{}) bool {
4949
crt, ok := v.(*x509.Certificate)
5050
if !ok {
5151
federation = nil

authority/tls.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ var (
5959
)
6060

6161
func withDefaultASN1DN(def *config.ASN1DN) provisioner.CertificateModifierFunc {
62-
return func(crt *x509.Certificate, opts provisioner.SignOptions) error {
62+
return func(crt *x509.Certificate, _ provisioner.SignOptions) error {
6363
if def == nil {
6464
return errors.New("default ASN1DN template cannot be nil")
6565
}
@@ -913,10 +913,16 @@ func (a *Authority) GetTLSCertificate() (*tls.Certificate, error) {
913913
return fatal(err)
914914
}
915915

916+
// For StepCAS RA let the lifetime to the provisioner used by the CA.
917+
var lifetime time.Duration
918+
if casapi.TypeOf(a.x509CAService) != casapi.StepCAS {
919+
lifetime = 24 * time.Hour
920+
}
921+
916922
resp, err := a.x509CAService.CreateCertificate(&casapi.CreateCertificateRequest{
917923
Template: certTpl,
918924
CSR: cr,
919-
Lifetime: 24 * time.Hour,
925+
Lifetime: lifetime,
920926
Backdate: 1 * time.Minute,
921927
IsCAServerCert: true,
922928
})

ca/adminClient.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func (o *adminOptions) apply(opts []AdminOption) (err error) {
204204

205205
func (o *adminOptions) rawQuery() string {
206206
v := url.Values{}
207-
if len(o.cursor) > 0 {
207+
if o.cursor != "" {
208208
v.Set("cursor", o.cursor)
209209
}
210210
if o.limit > 0 {

ca/ca.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ func (ca *CA) shouldServeSCEPEndpoints() bool {
678678
//nolint:unused // useful for debugging
679679
func dumpRoutes(mux chi.Routes) {
680680
// helpful routine for logging all routes
681-
walkFunc := func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error {
681+
walkFunc := func(method string, route string, _ http.Handler, _ ...func(http.Handler) http.Handler) error {
682682
fmt.Printf("%s %s\n", method, route)
683683
return nil
684684
}

ca/tls.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func init() {
6969
GetClientCertificate: id.GetClientCertificateFunc(),
7070
},
7171
}
72-
return func(ctx context.Context, network, address string) (net.Conn, error) {
72+
return func(ctx context.Context, _, _ string) (net.Conn, error) {
7373
return d.DialContext(ctx, "tcp", net.JoinHostPort(host, port))
7474
}
7575
}

cas/apiv1/services.go

+8
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ func (t Type) String() string {
6767
return strings.ToLower(string(t))
6868
}
6969

70+
// TypeOf returns the type of the given CertificateAuthorityService.
71+
func TypeOf(c CertificateAuthorityService) Type {
72+
if ct, ok := c.(interface{ Type() Type }); ok {
73+
return ct.Type()
74+
}
75+
return ExternalCAS
76+
}
77+
7078
// NotImplementedError is the type of error returned if an operation is not implemented.
7179
type NotImplementedError struct {
7280
Message string

cas/apiv1/services_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,24 @@ import (
44
"testing"
55
)
66

7+
type simpleCAS struct{}
8+
9+
func (*simpleCAS) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) {
10+
return nil, NotImplementedError{}
11+
}
12+
func (*simpleCAS) RenewCertificate(req *RenewCertificateRequest) (*RenewCertificateResponse, error) {
13+
return nil, NotImplementedError{}
14+
}
15+
func (*simpleCAS) RevokeCertificate(req *RevokeCertificateRequest) (*RevokeCertificateResponse, error) {
16+
return nil, NotImplementedError{}
17+
}
18+
19+
type fakeCAS struct {
20+
simpleCAS
21+
}
22+
23+
func (*fakeCAS) Type() Type { return SoftCAS }
24+
725
func TestType_String(t *testing.T) {
826
tests := []struct {
927
name string
@@ -25,6 +43,27 @@ func TestType_String(t *testing.T) {
2543
}
2644
}
2745

46+
func TestTypeOf(t *testing.T) {
47+
type args struct {
48+
c CertificateAuthorityService
49+
}
50+
tests := []struct {
51+
name string
52+
args args
53+
want Type
54+
}{
55+
{"ok", args{&simpleCAS{}}, ExternalCAS},
56+
{"ok with type", args{&fakeCAS{}}, SoftCAS},
57+
}
58+
for _, tt := range tests {
59+
t.Run(tt.name, func(t *testing.T) {
60+
if got := TypeOf(tt.args.c); got != tt.want {
61+
t.Errorf("TypeOf() = %v, want %v", got, tt.want)
62+
}
63+
})
64+
}
65+
}
66+
2867
func TestNotImplementedError_Error(t *testing.T) {
2968
type fields struct {
3069
Message string

cas/cloudcas/cloudcas.go

+5
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,11 @@ func New(ctx context.Context, opts apiv1.Options) (*CloudCAS, error) {
154154
}, nil
155155
}
156156

157+
// Type returns the type of this CertificateAuthorityService.
158+
func (c *CloudCAS) Type() apiv1.Type {
159+
return apiv1.CloudCAS
160+
}
161+
157162
// GetCertificateAuthority returns the root certificate for the given
158163
// certificate authority. It implements apiv1.CertificateAuthorityGetter
159164
// interface.

cas/cloudcas/cloudcas_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,23 @@ func TestNew_real(t *testing.T) {
443443
}
444444
}
445445

446+
func TestCloudCAS_Type(t *testing.T) {
447+
tests := []struct {
448+
name string
449+
want apiv1.Type
450+
}{
451+
{"ok", apiv1.CloudCAS},
452+
}
453+
for _, tt := range tests {
454+
t.Run(tt.name, func(t *testing.T) {
455+
c := &CloudCAS{}
456+
if got := c.Type(); got != tt.want {
457+
t.Errorf("CloudCAS.Type() = %v, want %v", got, tt.want)
458+
}
459+
})
460+
}
461+
}
462+
446463
func TestCloudCAS_GetCertificateAuthority(t *testing.T) {
447464
root := mustParseCertificate(t, testRootCertificate)
448465
type fields struct {

cas/softcas/softcas.go

+5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ func New(_ context.Context, opts apiv1.Options) (*SoftCAS, error) {
5353
}, nil
5454
}
5555

56+
// Type returns the type of this CertificateAuthorityService.
57+
func (c *SoftCAS) Type() apiv1.Type {
58+
return apiv1.SoftCAS
59+
}
60+
5661
// CreateCertificate signs a new certificate using Golang or KMS crypto.
5762
func (c *SoftCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1.CreateCertificateResponse, error) {
5863
switch {

0 commit comments

Comments
 (0)