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 #1094
pull/1764/head
Mariano Cano 2 months ago
parent ef1631b00d
commit 10f6a901ec
No known key found for this signature in database

@ -147,10 +147,10 @@ func validateJWS(next nextHTTP) nextHTTP {
sig := jws.Signatures[0] sig := jws.Signatures[0]
uh := sig.Unprotected uh := sig.Unprotected
if len(uh.KeyID) > 0 || if uh.KeyID != "" ||
uh.JSONWebKey != nil || uh.JSONWebKey != nil ||
len(uh.Algorithm) > 0 || uh.Algorithm != "" ||
len(uh.Nonce) > 0 || uh.Nonce != "" ||
len(uh.ExtraHeaders) > 0 { len(uh.ExtraHeaders) > 0 {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "unprotected header must not be used")) render.Error(w, acme.NewError(acme.ErrorMalformedType, "unprotected header must not be used"))
return return
@ -199,7 +199,7 @@ func validateJWS(next nextHTTP) nextHTTP {
return return
} }
if hdr.JSONWebKey != nil && len(hdr.KeyID) > 0 { if hdr.JSONWebKey != nil && hdr.KeyID != "" {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "jwk and kid are mutually exclusive")) render.Error(w, acme.NewError(acme.ErrorMalformedType, "jwk and kid are mutually exclusive"))
return return
} }

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

@ -78,7 +78,7 @@ func Revoke(w http.ResponseWriter, r *http.Request) {
// A token indicates that we are using the api via a provisioner token, // A token indicates that we are using the api via a provisioner token,
// otherwise it is assumed that the certificate is revoking itself over mTLS. // otherwise it is assumed that the certificate is revoking itself over mTLS.
if len(body.OTT) > 0 { if body.OTT != "" {
logOtt(w, body.OTT) logOtt(w, body.OTT)
if _, err := a.Authorize(ctx, body.OTT); err != nil { if _, err := a.Authorize(ctx, body.OTT); err != nil {
render.Error(w, errs.UnauthorizedErr(err)) render.Error(w, errs.UnauthorizedErr(err))

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

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

@ -906,7 +906,7 @@ func TestDB_CreateProvisioner(t *testing.T) {
var _dbp = new(dbProvisioner) var _dbp = new(dbProvisioner)
assert.FatalError(t, json.Unmarshal(nu, _dbp)) assert.FatalError(t, json.Unmarshal(nu, _dbp))
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key)) assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId) assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
assert.Equals(t, _dbp.Type, prov.Type) assert.Equals(t, _dbp.Type, prov.Type)
assert.Equals(t, _dbp.Name, prov.Name) assert.Equals(t, _dbp.Name, prov.Name)
@ -944,7 +944,7 @@ func TestDB_CreateProvisioner(t *testing.T) {
var _dbp = new(dbProvisioner) var _dbp = new(dbProvisioner)
assert.FatalError(t, json.Unmarshal(nu, _dbp)) assert.FatalError(t, json.Unmarshal(nu, _dbp))
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key)) assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId) assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
assert.Equals(t, _dbp.Type, prov.Type) assert.Equals(t, _dbp.Type, prov.Type)
assert.Equals(t, _dbp.Name, prov.Name) assert.Equals(t, _dbp.Name, prov.Name)
@ -1093,7 +1093,7 @@ func TestDB_UpdateProvisioner(t *testing.T) {
var _dbp = new(dbProvisioner) var _dbp = new(dbProvisioner)
assert.FatalError(t, json.Unmarshal(nu, _dbp)) assert.FatalError(t, json.Unmarshal(nu, _dbp))
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key)) assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId) assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
assert.Equals(t, _dbp.Type, prov.Type) assert.Equals(t, _dbp.Type, prov.Type)
assert.Equals(t, _dbp.Name, prov.Name) assert.Equals(t, _dbp.Name, prov.Name)
@ -1188,7 +1188,7 @@ func TestDB_UpdateProvisioner(t *testing.T) {
var _dbp = new(dbProvisioner) var _dbp = new(dbProvisioner)
assert.FatalError(t, json.Unmarshal(nu, _dbp)) assert.FatalError(t, json.Unmarshal(nu, _dbp))
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key)) assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId) assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
assert.Equals(t, _dbp.Type, prov.Type) assert.Equals(t, _dbp.Type, prov.Type)
assert.Equals(t, _dbp.Name, prov.Name) assert.Equals(t, _dbp.Name, prov.Name)

@ -203,7 +203,7 @@ func matchURIConstraint(uri *url.URL, constraint string) (bool, error) {
// domainToReverseLabels converts a textual domain name like foo.example.com to // domainToReverseLabels converts a textual domain name like foo.example.com to
// the list of labels in reverse order, e.g. ["com", "example", "foo"]. // the list of labels in reverse order, e.g. ["com", "example", "foo"].
func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) { func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) {
for len(domain) > 0 { for domain != "" {
if i := strings.LastIndexByte(domain, '.'); i == -1 { if i := strings.LastIndexByte(domain, '.'); i == -1 {
reverseLabels = append(reverseLabels, domain) reverseLabels = append(reverseLabels, domain)
domain = "" domain = ""
@ -316,7 +316,7 @@ func parseRFC2821Mailbox(in string) (mailbox rfc2821Mailbox, ok bool) {
} else { } else {
// Atom ("." Atom)* // Atom ("." Atom)*
NextChar: NextChar:
for len(in) > 0 { for in != "" {
// atext from RFC 2822, Section 3.2.4 // atext from RFC 2822, Section 3.2.4
c := in[0] c := in[0]

@ -125,7 +125,7 @@ func (c *Collection) LoadByToken(token *jose.JSONWebToken, claims *jose.Claims)
} }
// Try with azp (OIDC) // Try with azp (OIDC)
if len(payload.AuthorizedParty) > 0 { if payload.AuthorizedParty != "" {
if p, ok := c.LoadByTokenID(payload.AuthorizedParty); ok { if p, ok := c.LoadByTokenID(payload.AuthorizedParty); ok {
return p, ok return p, ok
} }

@ -87,7 +87,7 @@ func (p *JWK) GetType() Type {
// GetEncryptedKey returns the base provisioner encrypted key if it's defined. // GetEncryptedKey returns the base provisioner encrypted key if it's defined.
func (p *JWK) GetEncryptedKey() (string, string, bool) { func (p *JWK) GetEncryptedKey() (string, string, bool) {
return p.Key.KeyID, p.EncryptedKey, len(p.EncryptedKey) > 0 return p.Key.KeyID, p.EncryptedKey, p.EncryptedKey != ""
} }
// Init initializes and validates the fields of a JWK type. // Init initializes and validates the fields of a JWK type.

@ -105,7 +105,7 @@ func getKeysFromJWKsURI(uri string) (jose.JSONWebKeySet, time.Duration, error) {
func getCacheAge(cacheControl string) time.Duration { func getCacheAge(cacheControl string) time.Duration {
age := defaultCacheAge age := defaultCacheAge
if len(cacheControl) > 0 { if cacheControl != "" {
match := maxAgeRegex.FindAllStringSubmatch(cacheControl, -1) match := maxAgeRegex.FindAllStringSubmatch(cacheControl, -1)
if len(match) > 0 { if len(match) > 0 {
if len(match[0]) == 2 { if len(match[0]) == 2 {

@ -304,7 +304,7 @@ func (s *SCEP) Init(config Config) (err error) {
} }
} }
if decryptionKeyURI := s.DecrypterKeyURI; len(decryptionKeyURI) > 0 { if decryptionKeyURI := s.DecrypterKeyURI; decryptionKeyURI != "" {
u, err := uri.Parse(s.DecrypterKeyURI) u, err := uri.Parse(s.DecrypterKeyURI)
if err != nil { if err != nil {
return fmt.Errorf("failed parsing decrypter key: %w", err) return fmt.Errorf("failed parsing decrypter key: %w", err)

@ -813,7 +813,7 @@ func TestX5C_AuthorizeSSHSign(t *testing.T) {
} }
tot++ tot++
} }
if len(tc.claims.Step.SSH.CertType) > 0 { if tc.claims.Step.SSH.CertType != "" {
assert.Equals(t, tot, 12) assert.Equals(t, tot, 12)
} else { } else {
assert.Equals(t, tot, 10) assert.Equals(t, tot, 10)

@ -608,19 +608,19 @@ func provisionerWebhookToLinkedca(pwh *provisioner.Webhook) *linkedca.Webhook {
} }
func durationsToCertificates(d *linkedca.Durations) (min, max, def *provisioner.Duration, err error) { func durationsToCertificates(d *linkedca.Durations) (min, max, def *provisioner.Duration, err error) {
if len(d.Min) > 0 { if d.Min != "" {
min, err = provisioner.NewDuration(d.Min) min, err = provisioner.NewDuration(d.Min)
if err != nil { if err != nil {
return nil, nil, nil, admin.WrapErrorISE(err, "error parsing minimum duration '%s'", d.Min) return nil, nil, nil, admin.WrapErrorISE(err, "error parsing minimum duration '%s'", d.Min)
} }
} }
if len(d.Max) > 0 { if d.Max != "" {
max, err = provisioner.NewDuration(d.Max) max, err = provisioner.NewDuration(d.Max)
if err != nil { if err != nil {
return nil, nil, nil, admin.WrapErrorISE(err, "error parsing maximum duration '%s'", d.Max) return nil, nil, nil, admin.WrapErrorISE(err, "error parsing maximum duration '%s'", d.Max)
} }
} }
if len(d.Default) > 0 { if d.Default != "" {
def, err = provisioner.NewDuration(d.Default) def, err = provisioner.NewDuration(d.Default)
if err != nil { if err != nil {
return nil, nil, nil, admin.WrapErrorISE(err, "error parsing default duration '%s'", d.Default) return nil, nil, nil, admin.WrapErrorISE(err, "error parsing default duration '%s'", d.Default)

@ -45,7 +45,7 @@ func (a *Authority) GetRoots() ([]*x509.Certificate, error) {
// GetFederation returns all the root certificates in the federation. // GetFederation returns all the root certificates in the federation.
// This method implements the Authority interface. // This method implements the Authority interface.
func (a *Authority) GetFederation() (federation []*x509.Certificate, err error) { func (a *Authority) GetFederation() (federation []*x509.Certificate, err error) {
a.certificates.Range(func(k, v interface{}) bool { a.certificates.Range(func(_, v interface{}) bool {
crt, ok := v.(*x509.Certificate) crt, ok := v.(*x509.Certificate)
if !ok { if !ok {
federation = nil federation = nil

@ -59,7 +59,7 @@ var (
) )
func withDefaultASN1DN(def *config.ASN1DN) provisioner.CertificateModifierFunc { func withDefaultASN1DN(def *config.ASN1DN) provisioner.CertificateModifierFunc {
return func(crt *x509.Certificate, opts provisioner.SignOptions) error { return func(crt *x509.Certificate, _ provisioner.SignOptions) error {
if def == nil { if def == nil {
return errors.New("default ASN1DN template cannot be nil") return errors.New("default ASN1DN template cannot be nil")
} }
@ -913,10 +913,16 @@ func (a *Authority) GetTLSCertificate() (*tls.Certificate, error) {
return fatal(err) return fatal(err)
} }
// For StepCAS RA let the lifetime to the provisioner used by the CA.
var lifetime time.Duration
if casapi.TypeOf(a.x509CAService) != casapi.StepCAS {
lifetime = 24 * time.Hour
}
resp, err := a.x509CAService.CreateCertificate(&casapi.CreateCertificateRequest{ resp, err := a.x509CAService.CreateCertificate(&casapi.CreateCertificateRequest{
Template: certTpl, Template: certTpl,
CSR: cr, CSR: cr,
Lifetime: 24 * time.Hour, Lifetime: lifetime,
Backdate: 1 * time.Minute, Backdate: 1 * time.Minute,
IsCAServerCert: true, IsCAServerCert: true,
}) })

@ -204,7 +204,7 @@ func (o *adminOptions) apply(opts []AdminOption) (err error) {
func (o *adminOptions) rawQuery() string { func (o *adminOptions) rawQuery() string {
v := url.Values{} v := url.Values{}
if len(o.cursor) > 0 { if o.cursor != "" {
v.Set("cursor", o.cursor) v.Set("cursor", o.cursor)
} }
if o.limit > 0 { if o.limit > 0 {

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

@ -69,7 +69,7 @@ func init() {
GetClientCertificate: id.GetClientCertificateFunc(), GetClientCertificate: id.GetClientCertificateFunc(),
}, },
} }
return func(ctx context.Context, network, address string) (net.Conn, error) { return func(ctx context.Context, _, _ string) (net.Conn, error) {
return d.DialContext(ctx, "tcp", net.JoinHostPort(host, port)) return d.DialContext(ctx, "tcp", net.JoinHostPort(host, port))
} }
} }

@ -67,6 +67,14 @@ func (t Type) String() string {
return strings.ToLower(string(t)) return strings.ToLower(string(t))
} }
// TypeOf returns the type of the given CertificateAuthorityService.
func TypeOf(c CertificateAuthorityService) Type {
if ct, ok := c.(interface{ Type() Type }); ok {
return ct.Type()
}
return ExternalCAS
}
// NotImplementedError is the type of error returned if an operation is not implemented. // NotImplementedError is the type of error returned if an operation is not implemented.
type NotImplementedError struct { type NotImplementedError struct {
Message string Message string

@ -4,6 +4,24 @@ import (
"testing" "testing"
) )
type simpleCAS struct{}
func (*simpleCAS) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) {
return nil, NotImplementedError{}
}
func (*simpleCAS) RenewCertificate(req *RenewCertificateRequest) (*RenewCertificateResponse, error) {
return nil, NotImplementedError{}
}
func (*simpleCAS) RevokeCertificate(req *RevokeCertificateRequest) (*RevokeCertificateResponse, error) {
return nil, NotImplementedError{}
}
type fakeCAS struct {
simpleCAS
}
func (*fakeCAS) Type() Type { return SoftCAS }
func TestType_String(t *testing.T) { func TestType_String(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
@ -25,6 +43,27 @@ func TestType_String(t *testing.T) {
} }
} }
func TestTypeOf(t *testing.T) {
type args struct {
c CertificateAuthorityService
}
tests := []struct {
name string
args args
want Type
}{
{"ok", args{&simpleCAS{}}, ExternalCAS},
{"ok with type", args{&fakeCAS{}}, SoftCAS},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := TypeOf(tt.args.c); got != tt.want {
t.Errorf("TypeOf() = %v, want %v", got, tt.want)
}
})
}
}
func TestNotImplementedError_Error(t *testing.T) { func TestNotImplementedError_Error(t *testing.T) {
type fields struct { type fields struct {
Message string Message string

@ -154,6 +154,11 @@ func New(ctx context.Context, opts apiv1.Options) (*CloudCAS, error) {
}, nil }, nil
} }
// Type returns the type of this CertificateAuthorityService.
func (c *CloudCAS) Type() apiv1.Type {
return apiv1.CloudCAS
}
// GetCertificateAuthority returns the root certificate for the given // GetCertificateAuthority returns the root certificate for the given
// certificate authority. It implements apiv1.CertificateAuthorityGetter // certificate authority. It implements apiv1.CertificateAuthorityGetter
// interface. // interface.

@ -443,6 +443,23 @@ func TestNew_real(t *testing.T) {
} }
} }
func TestCloudCAS_Type(t *testing.T) {
tests := []struct {
name string
want apiv1.Type
}{
{"ok", apiv1.CloudCAS},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &CloudCAS{}
if got := c.Type(); got != tt.want {
t.Errorf("CloudCAS.Type() = %v, want %v", got, tt.want)
}
})
}
}
func TestCloudCAS_GetCertificateAuthority(t *testing.T) { func TestCloudCAS_GetCertificateAuthority(t *testing.T) {
root := mustParseCertificate(t, testRootCertificate) root := mustParseCertificate(t, testRootCertificate)
type fields struct { type fields struct {

@ -53,6 +53,11 @@ func New(_ context.Context, opts apiv1.Options) (*SoftCAS, error) {
}, nil }, nil
} }
// Type returns the type of this CertificateAuthorityService.
func (c *SoftCAS) Type() apiv1.Type {
return apiv1.SoftCAS
}
// CreateCertificate signs a new certificate using Golang or KMS crypto. // CreateCertificate signs a new certificate using Golang or KMS crypto.
func (c *SoftCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1.CreateCertificateResponse, error) { func (c *SoftCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1.CreateCertificateResponse, error) {
switch { switch {

@ -252,6 +252,23 @@ func TestNew_register(t *testing.T) {
} }
} }
func TestSoftCAS_Type(t *testing.T) {
tests := []struct {
name string
want apiv1.Type
}{
{"ok", apiv1.SoftCAS},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &SoftCAS{}
if got := c.Type(); got != tt.want {
t.Errorf("SoftCAS.Type() = %v, want %v", got, tt.want)
}
})
}
}
func TestSoftCAS_CreateCertificate(t *testing.T) { func TestSoftCAS_CreateCertificate(t *testing.T) {
mockNow(t) mockNow(t)
// Set rand.Reader to EOF // Set rand.Reader to EOF

@ -65,6 +65,11 @@ func New(ctx context.Context, opts apiv1.Options) (*StepCAS, error) {
}, nil }, nil
} }
// Type returns the type of this CertificateAuthorityService.
func (s *StepCAS) Type() apiv1.Type {
return apiv1.StepCAS
}
// CreateCertificate uses the step-ca sign request with the configured // CreateCertificate uses the step-ca sign request with the configured
// provisioner to get a new certificate from the certificate authority. // provisioner to get a new certificate from the certificate authority.
func (s *StepCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1.CreateCertificateResponse, error) { func (s *StepCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1.CreateCertificateResponse, error) {
@ -73,8 +78,8 @@ func (s *StepCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1
return nil, errors.New("createCertificateRequest `csr` cannot be nil") return nil, errors.New("createCertificateRequest `csr` cannot be nil")
case req.Template == nil: case req.Template == nil:
return nil, errors.New("createCertificateRequest `template` cannot be nil") return nil, errors.New("createCertificateRequest `template` cannot be nil")
case req.Lifetime == 0: case req.Lifetime < 0:
return nil, errors.New("createCertificateRequest `lifetime` cannot be 0") return nil, errors.New("createCertificateRequest `lifetime` cannot less than 0")
} }
info := &raInfo{ info := &raInfo{

@ -624,6 +624,23 @@ func TestNew(t *testing.T) {
} }
} }
func TestStepCAS_Type(t *testing.T) {
tests := []struct {
name string
want apiv1.Type
}{
{"ok", apiv1.StepCAS},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &StepCAS{}
if got := c.Type(); got != tt.want {
t.Errorf("StepCAS.Type() = %v, want %v", got, tt.want)
}
})
}
}
func TestStepCAS_CreateCertificate(t *testing.T) { func TestStepCAS_CreateCertificate(t *testing.T) {
caURL, client := testCAHelper(t) caURL, client := testCAHelper(t)
x5c := testX5CIssuer(t, caURL, "") x5c := testX5CIssuer(t, caURL, "")

@ -110,6 +110,11 @@ func New(ctx context.Context, opts apiv1.Options) (*VaultCAS, error) {
}, nil }, nil
} }
// Type returns the type of this CertificateAuthorityService.
func (v *VaultCAS) Type() apiv1.Type {
return apiv1.VaultCAS
}
// CreateCertificate signs a new certificate using Hashicorp Vault. // CreateCertificate signs a new certificate using Hashicorp Vault.
func (v *VaultCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1.CreateCertificateResponse, error) { func (v *VaultCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1.CreateCertificateResponse, error) {
switch { switch {

@ -193,6 +193,23 @@ func TestNew_register(t *testing.T) {
} }
} }
func TestVaultCAS_Type(t *testing.T) {
tests := []struct {
name string
want apiv1.Type
}{
{"ok", apiv1.VaultCAS},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &VaultCAS{}
if got := c.Type(); got != tt.want {
t.Errorf("VaultCAS.Type() = %v, want %v", got, tt.want)
}
})
}
}
func TestVaultCAS_CreateCertificate(t *testing.T) { func TestVaultCAS_CreateCertificate(t *testing.T) {
_, client := testCAHelper(t) _, client := testCAHelper(t)

@ -239,7 +239,7 @@ To get a linked authority token:
// replace resolver if requested // replace resolver if requested
if resolver != "" { if resolver != "" {
net.DefaultResolver.PreferGo = true net.DefaultResolver.PreferGo = true
net.DefaultResolver.Dial = func(ctx context.Context, network, address string) (net.Conn, error) { net.DefaultResolver.Dial = func(_ context.Context, network, _ string) (net.Conn, error) {
return net.Dial(network, resolver) return net.Dial(network, resolver)
} }
} }

@ -116,7 +116,7 @@ func New(c *Config) (AuthDB, error) {
opts := []nosql.Option{nosql.WithDatabase(c.Database), opts := []nosql.Option{nosql.WithDatabase(c.Database),
nosql.WithValueDir(c.ValueDir)} nosql.WithValueDir(c.ValueDir)}
if len(c.BadgerFileLoadingMode) > 0 { if c.BadgerFileLoadingMode != "" {
opts = append(opts, nosql.WithBadgerFileLoadingMode(c.BadgerFileLoadingMode)) opts = append(opts, nosql.WithBadgerFileLoadingMode(c.BadgerFileLoadingMode))
} }

@ -80,7 +80,7 @@ func (e *Error) StatusCode() int {
// Message returns a user friendly error, if one is set. // Message returns a user friendly error, if one is set.
func (e *Error) Message() string { func (e *Error) Message() string {
if len(e.Msg) > 0 { if e.Msg != "" {
return e.Msg return e.Msg
} }
return e.Err.Error() return e.Err.Error()
@ -123,7 +123,7 @@ func Wrapf(status int, e error, format string, args ...interface{}) error {
// MarshalJSON implements json.Marshaller interface for the Error struct. // MarshalJSON implements json.Marshaller interface for the Error struct.
func (e *Error) MarshalJSON() ([]byte, error) { func (e *Error) MarshalJSON() ([]byte, error) {
var msg string var msg string
if len(e.Msg) > 0 { if e.Msg != "" {
msg = e.Msg msg = e.Msg
} else { } else {
msg = http.StatusText(e.Status) msg = http.StatusText(e.Status)

@ -288,7 +288,7 @@ func checkNameConstraints(
// domainToReverseLabels converts a textual domain name like foo.example.com to // domainToReverseLabels converts a textual domain name like foo.example.com to
// the list of labels in reverse order, e.g. ["com", "example", "foo"]. // the list of labels in reverse order, e.g. ["com", "example", "foo"].
func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) { func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) {
for len(domain) > 0 { for domain != "" {
if i := strings.LastIndexByte(domain, '.'); i == -1 { if i := strings.LastIndexByte(domain, '.'); i == -1 {
reverseLabels = append(reverseLabels, domain) reverseLabels = append(reverseLabels, domain)
domain = "" domain = ""
@ -401,7 +401,7 @@ func parseRFC2821Mailbox(in string) (mailbox rfc2821Mailbox, ok bool) {
} else { } else {
// Atom ("." Atom)* // Atom ("." Atom)*
NextChar: NextChar:
for len(in) > 0 { for in != "" {
// atext from RFC 2822, Section 3.2.4 // atext from RFC 2822, Section 3.2.4
c := in[0] c := in[0]

Loading…
Cancel
Save