forked from TrueCloudLab/certificates
Rename provisioner options structs:
* provisioner.ProvisionerOptions => provisioner.Options * provisioner.Options => provisioner.SignOptions * provisioner.SSHOptions => provisioner.SingSSHOptions
This commit is contained in:
parent
e0dd1bd132
commit
6c64fb3ed2
37 changed files with 405 additions and 406 deletions
|
@ -18,7 +18,7 @@ type Provisioner interface {
|
|||
AuthorizeSign(ctx context.Context, token string) ([]provisioner.SignOption, error)
|
||||
GetName() string
|
||||
DefaultTLSCertDuration() time.Duration
|
||||
GetOptions() *provisioner.ProvisionerOptions
|
||||
GetOptions() *provisioner.Options
|
||||
}
|
||||
|
||||
// MockProvisioner for testing
|
||||
|
@ -28,7 +28,7 @@ type MockProvisioner struct {
|
|||
MgetName func() string
|
||||
MauthorizeSign func(ctx context.Context, ott string) ([]provisioner.SignOption, error)
|
||||
MdefaultTLSCertDuration func() time.Duration
|
||||
MgetOptions func() *provisioner.ProvisionerOptions
|
||||
MgetOptions func() *provisioner.Options
|
||||
}
|
||||
|
||||
// GetName mock
|
||||
|
@ -55,11 +55,11 @@ func (m *MockProvisioner) DefaultTLSCertDuration() time.Duration {
|
|||
return m.Mret1.(time.Duration)
|
||||
}
|
||||
|
||||
func (m *MockProvisioner) GetOptions() *provisioner.ProvisionerOptions {
|
||||
func (m *MockProvisioner) GetOptions() *provisioner.Options {
|
||||
if m.MgetOptions != nil {
|
||||
return m.MgetOptions()
|
||||
}
|
||||
return m.Mret1.(*provisioner.ProvisionerOptions)
|
||||
return m.Mret1.(*provisioner.Options)
|
||||
}
|
||||
|
||||
// ContextKey is the key type for storing and searching for ACME request
|
||||
|
@ -134,7 +134,7 @@ func ProvisionerFromContext(ctx context.Context) (Provisioner, error) {
|
|||
|
||||
// SignAuthority is the interface implemented by a CA authority.
|
||||
type SignAuthority interface {
|
||||
Sign(cr *x509.CertificateRequest, opts provisioner.Options, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
|
||||
Sign(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
|
||||
LoadProvisionerByID(string) (provisioner.Interface, error)
|
||||
}
|
||||
|
||||
|
|
|
@ -338,7 +338,7 @@ func (o *order) finalize(db nosql.DB, csr *x509.CertificateRequest, auth SignAut
|
|||
signOps = append(signOps, templateOptions)
|
||||
|
||||
// Create and store a new certificate.
|
||||
certChain, err := auth.Sign(csr, provisioner.Options{
|
||||
certChain, err := auth.Sign(csr, provisioner.SignOptions{
|
||||
NotBefore: provisioner.NewTimeDuration(o.NotBefore),
|
||||
NotAfter: provisioner.NewTimeDuration(o.NotAfter),
|
||||
}, signOps...)
|
||||
|
|
|
@ -895,13 +895,13 @@ func TestOrderUpdateStatus(t *testing.T) {
|
|||
}
|
||||
|
||||
type mockSignAuth struct {
|
||||
sign func(csr *x509.CertificateRequest, signOpts provisioner.Options, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
|
||||
sign func(csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
|
||||
loadProvisionerByID func(string) (provisioner.Interface, error)
|
||||
ret1, ret2 interface{}
|
||||
err error
|
||||
}
|
||||
|
||||
func (m *mockSignAuth) Sign(csr *x509.CertificateRequest, signOpts provisioner.Options, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
func (m *mockSignAuth) Sign(csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
if m.sign != nil {
|
||||
return m.sign(csr, signOpts, extraOpts...)
|
||||
} else if m.err != nil {
|
||||
|
@ -1262,7 +1262,7 @@ func TestOrderFinalize(t *testing.T) {
|
|||
res: clone,
|
||||
csr: csr,
|
||||
sa: &mockSignAuth{
|
||||
sign: func(csr *x509.CertificateRequest, pops provisioner.Options, signOps ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
sign: func(csr *x509.CertificateRequest, pops provisioner.SignOptions, signOps ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
assert.Equals(t, len(signOps), 6)
|
||||
return []*x509.Certificate{crt, inter}, nil
|
||||
},
|
||||
|
@ -1311,7 +1311,7 @@ func TestOrderFinalize(t *testing.T) {
|
|||
res: &clone,
|
||||
csr: csr,
|
||||
sa: &mockSignAuth{
|
||||
sign: func(csr *x509.CertificateRequest, pops provisioner.Options, signOps ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
sign: func(csr *x509.CertificateRequest, pops provisioner.SignOptions, signOps ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
assert.Equals(t, len(signOps), 6)
|
||||
return []*x509.Certificate{crt, inter}, nil
|
||||
},
|
||||
|
@ -1358,7 +1358,7 @@ func TestOrderFinalize(t *testing.T) {
|
|||
res: &clone,
|
||||
csr: csr,
|
||||
sa: &mockSignAuth{
|
||||
sign: func(csr *x509.CertificateRequest, pops provisioner.Options, signOps ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
sign: func(csr *x509.CertificateRequest, pops provisioner.SignOptions, signOps ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
assert.Equals(t, len(signOps), 6)
|
||||
return []*x509.Certificate{crt, inter}, nil
|
||||
},
|
||||
|
|
|
@ -34,7 +34,7 @@ type Authority interface {
|
|||
AuthorizeSign(ott string) ([]provisioner.SignOption, error)
|
||||
GetTLSOptions() *tlsutil.TLSOptions
|
||||
Root(shasum string) (*x509.Certificate, error)
|
||||
Sign(cr *x509.CertificateRequest, opts provisioner.Options, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
|
||||
Sign(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
|
||||
Renew(peer *x509.Certificate) ([]*x509.Certificate, error)
|
||||
Rekey(peer *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error)
|
||||
LoadProvisionerByCertificate(*x509.Certificate) (provisioner.Interface, error)
|
||||
|
|
|
@ -550,7 +550,7 @@ type mockAuthority struct {
|
|||
authorizeSign func(ott string) ([]provisioner.SignOption, error)
|
||||
getTLSOptions func() *tlsutil.TLSOptions
|
||||
root func(shasum string) (*x509.Certificate, error)
|
||||
sign func(cr *x509.CertificateRequest, opts provisioner.Options, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
|
||||
sign func(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
|
||||
renew func(cert *x509.Certificate) ([]*x509.Certificate, error)
|
||||
rekey func(oldCert *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error)
|
||||
loadProvisionerByCertificate func(cert *x509.Certificate) (provisioner.Interface, error)
|
||||
|
@ -560,7 +560,7 @@ type mockAuthority struct {
|
|||
getEncryptedKey func(kid string) (string, error)
|
||||
getRoots func() ([]*x509.Certificate, error)
|
||||
getFederation func() ([]*x509.Certificate, error)
|
||||
signSSH func(ctx context.Context, key ssh.PublicKey, opts provisioner.SSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error)
|
||||
signSSH func(ctx context.Context, key ssh.PublicKey, opts provisioner.SignSSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error)
|
||||
signSSHAddUser func(ctx context.Context, key ssh.PublicKey, cert *ssh.Certificate) (*ssh.Certificate, error)
|
||||
renewSSH func(ctx context.Context, cert *ssh.Certificate) (*ssh.Certificate, error)
|
||||
rekeySSH func(ctx context.Context, cert *ssh.Certificate, key ssh.PublicKey, signOpts ...provisioner.SignOption) (*ssh.Certificate, error)
|
||||
|
@ -599,7 +599,7 @@ func (m *mockAuthority) Root(shasum string) (*x509.Certificate, error) {
|
|||
return m.ret1.(*x509.Certificate), m.err
|
||||
}
|
||||
|
||||
func (m *mockAuthority) Sign(cr *x509.CertificateRequest, opts provisioner.Options, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
func (m *mockAuthority) Sign(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
if m.sign != nil {
|
||||
return m.sign(cr, opts, signOpts...)
|
||||
}
|
||||
|
@ -669,7 +669,7 @@ func (m *mockAuthority) GetFederation() ([]*x509.Certificate, error) {
|
|||
return m.ret1.([]*x509.Certificate), m.err
|
||||
}
|
||||
|
||||
func (m *mockAuthority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisioner.SSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error) {
|
||||
func (m *mockAuthority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisioner.SignSSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error) {
|
||||
if m.signSSH != nil {
|
||||
return m.signSSH(ctx, key, opts, signOpts...)
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ func (h *caHandler) Sign(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
opts := provisioner.Options{
|
||||
opts := provisioner.SignOptions{
|
||||
NotBefore: body.NotBefore,
|
||||
NotAfter: body.NotAfter,
|
||||
TemplateData: body.TemplateData,
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
|
||||
// SSHAuthority is the interface implemented by a SSH CA authority.
|
||||
type SSHAuthority interface {
|
||||
SignSSH(ctx context.Context, key ssh.PublicKey, opts provisioner.SSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error)
|
||||
SignSSH(ctx context.Context, key ssh.PublicKey, opts provisioner.SignSSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error)
|
||||
RenewSSH(ctx context.Context, cert *ssh.Certificate) (*ssh.Certificate, error)
|
||||
RekeySSH(ctx context.Context, cert *ssh.Certificate, key ssh.PublicKey, signOpts ...provisioner.SignOption) (*ssh.Certificate, error)
|
||||
SignSSHAddUser(ctx context.Context, key ssh.PublicKey, cert *ssh.Certificate) (*ssh.Certificate, error)
|
||||
|
@ -274,7 +274,7 @@ func (h *caHandler) SSHSign(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
opts := provisioner.SSHOptions{
|
||||
opts := provisioner.SignSSHOptions{
|
||||
CertType: body.CertType,
|
||||
KeyID: body.KeyID,
|
||||
Principals: body.Principals,
|
||||
|
@ -322,7 +322,7 @@ func (h *caHandler) SSHSign(w http.ResponseWriter, r *http.Request) {
|
|||
NotAfter: time.Unix(int64(cert.ValidBefore), 0),
|
||||
})
|
||||
|
||||
certChain, err := h.Authority.Sign(cr, provisioner.Options{}, signOpts...)
|
||||
certChain, err := h.Authority.Sign(cr, provisioner.SignOptions{}, signOpts...)
|
||||
if err != nil {
|
||||
WriteError(w, errs.ForbiddenErr(err))
|
||||
return
|
||||
|
|
|
@ -319,13 +319,13 @@ func Test_caHandler_SSHSign(t *testing.T) {
|
|||
authorizeSign: func(ott string) ([]provisioner.SignOption, error) {
|
||||
return []provisioner.SignOption{}, tt.authErr
|
||||
},
|
||||
signSSH: func(ctx context.Context, key ssh.PublicKey, opts provisioner.SSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error) {
|
||||
signSSH: func(ctx context.Context, key ssh.PublicKey, opts provisioner.SignSSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error) {
|
||||
return tt.signCert, tt.signErr
|
||||
},
|
||||
signSSHAddUser: func(ctx context.Context, key ssh.PublicKey, cert *ssh.Certificate) (*ssh.Certificate, error) {
|
||||
return tt.addUserCert, tt.addUserErr
|
||||
},
|
||||
sign: func(cr *x509.CertificateRequest, opts provisioner.Options, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
sign: func(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
return tt.tlsSignCerts, tt.tlsSignErr
|
||||
},
|
||||
}).(*caHandler)
|
||||
|
|
|
@ -283,7 +283,7 @@ func TestNewEmbedded_Sign(t *testing.T) {
|
|||
csr, err := x509.ParseCertificateRequest(cr)
|
||||
assert.FatalError(t, err)
|
||||
|
||||
cert, err := a.Sign(csr, provisioner.Options{})
|
||||
cert, err := a.Sign(csr, provisioner.SignOptions{})
|
||||
assert.FatalError(t, err)
|
||||
assert.Equals(t, []string{"foo.bar.zar"}, cert[0].DNSNames)
|
||||
assert.Equals(t, crt, cert[1])
|
||||
|
|
|
@ -830,17 +830,17 @@ func TestAuthority_authorizeRenew(t *testing.T) {
|
|||
}
|
||||
|
||||
func generateSimpleSSHUserToken(iss, aud string, jwk *jose.JSONWebKey) (string, error) {
|
||||
return generateSSHToken("subject@localhost", iss, aud, time.Now(), &provisioner.SSHOptions{
|
||||
return generateSSHToken("subject@localhost", iss, aud, time.Now(), &provisioner.SignSSHOptions{
|
||||
CertType: "user",
|
||||
Principals: []string{"name"},
|
||||
}, jwk)
|
||||
}
|
||||
|
||||
type stepPayload struct {
|
||||
SSH *provisioner.SSHOptions `json:"ssh,omitempty"`
|
||||
SSH *provisioner.SignSSHOptions `json:"ssh,omitempty"`
|
||||
}
|
||||
|
||||
func generateSSHToken(sub, iss, aud string, iat time.Time, sshOpts *provisioner.SSHOptions, jwk *jose.JSONWebKey) (string, error) {
|
||||
func generateSSHToken(sub, iss, aud string, iat time.Time, sshOpts *provisioner.SignSSHOptions, jwk *jose.JSONWebKey) (string, error) {
|
||||
sig, err := jose.NewSigner(
|
||||
jose.SigningKey{Algorithm: jose.ES256, Key: jwk.Key},
|
||||
new(jose.SignerOptions).WithType("JWT").WithHeader("kid", jwk.KeyID),
|
||||
|
|
|
@ -13,11 +13,11 @@ import (
|
|||
// provisioning flow.
|
||||
type ACME struct {
|
||||
*base
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
ForceCN bool `json:"forceCN,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *ProvisionerOptions `json:"options,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
ForceCN bool `json:"forceCN,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *Options `json:"options,omitempty"`
|
||||
claimer *Claimer
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ func (p *ACME) GetEncryptedKey() (string, string, bool) {
|
|||
}
|
||||
|
||||
// GetOptions returns the configured provisioner options.
|
||||
func (p *ACME) GetOptions() *ProvisionerOptions {
|
||||
func (p *ACME) GetOptions() *Options {
|
||||
return p.Options
|
||||
}
|
||||
|
||||
|
|
|
@ -126,14 +126,14 @@ type awsInstanceIdentityDocument struct {
|
|||
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
|
||||
type AWS struct {
|
||||
*base
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Accounts []string `json:"accounts"`
|
||||
DisableCustomSANs bool `json:"disableCustomSANs"`
|
||||
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
||||
InstanceAge Duration `json:"instanceAge,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *ProvisionerOptions `json:"options,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Accounts []string `json:"accounts"`
|
||||
DisableCustomSANs bool `json:"disableCustomSANs"`
|
||||
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
||||
InstanceAge Duration `json:"instanceAge,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *Options `json:"options,omitempty"`
|
||||
claimer *Claimer
|
||||
config *awsConfig
|
||||
audiences Audiences
|
||||
|
@ -483,7 +483,7 @@ func (p *AWS) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
|
|||
}
|
||||
|
||||
// Default to cert type to host
|
||||
defaults := SSHOptions{
|
||||
defaults := SignSSHOptions{
|
||||
CertType: SSHHostCert,
|
||||
Principals: principals,
|
||||
}
|
||||
|
|
|
@ -647,51 +647,51 @@ func TestAWS_AuthorizeSSHSign(t *testing.T) {
|
|||
assert.FatalError(t, err)
|
||||
|
||||
hostDuration := p1.claimer.DefaultHostSSHCertDuration()
|
||||
expectedHostOptions := &SSHOptions{
|
||||
expectedHostOptions := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"127.0.0.1", "ip-127-0-0-1.us-west-1.compute.internal"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
expectedHostOptionsIP := &SSHOptions{
|
||||
expectedHostOptionsIP := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"127.0.0.1"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
expectedHostOptionsHostname := &SSHOptions{
|
||||
expectedHostOptionsHostname := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"ip-127-0-0-1.us-west-1.compute.internal"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
expectedCustomOptions := &SSHOptions{
|
||||
expectedCustomOptions := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"foo.local"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
|
||||
type args struct {
|
||||
token string
|
||||
sshOpts SSHOptions
|
||||
sshOpts SignSSHOptions
|
||||
key interface{}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
aws *AWS
|
||||
args args
|
||||
expected *SSHOptions
|
||||
expected *SignSSHOptions
|
||||
code int
|
||||
wantErr bool
|
||||
wantSignErr bool
|
||||
}{
|
||||
{"ok", p1, args{t1, SSHOptions{}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-rsa2048", p1, args{t1, SSHOptions{}, rsa2048.Public()}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-type", p1, args{t1, SSHOptions{CertType: "host"}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-principals", p1, args{t1, SSHOptions{Principals: []string{"127.0.0.1", "ip-127-0-0-1.us-west-1.compute.internal"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-principal-ip", p1, args{t1, SSHOptions{Principals: []string{"127.0.0.1"}}, pub}, expectedHostOptionsIP, http.StatusOK, false, false},
|
||||
{"ok-principal-hostname", p1, args{t1, SSHOptions{Principals: []string{"ip-127-0-0-1.us-west-1.compute.internal"}}, pub}, expectedHostOptionsHostname, http.StatusOK, false, false},
|
||||
{"ok-options", p1, args{t1, SSHOptions{CertType: "host", Principals: []string{"127.0.0.1", "ip-127-0-0-1.us-west-1.compute.internal"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-custom", p2, args{t2, SSHOptions{Principals: []string{"foo.local"}}, pub}, expectedCustomOptions, http.StatusOK, false, false},
|
||||
{"fail-rsa1024", p1, args{t1, SSHOptions{}, rsa1024.Public()}, expectedHostOptions, http.StatusOK, false, true},
|
||||
{"fail-type", p1, args{t1, SSHOptions{CertType: "user"}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-principal", p1, args{t1, SSHOptions{Principals: []string{"smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-extra-principal", p1, args{t1, SSHOptions{Principals: []string{"127.0.0.1", "ip-127-0-0-1.us-west-1.compute.internal", "smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-sshCA-disabled", p3, args{"foo", SSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
{"fail-invalid-token", p1, args{"foo", SSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
{"ok", p1, args{t1, SignSSHOptions{}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-rsa2048", p1, args{t1, SignSSHOptions{}, rsa2048.Public()}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-type", p1, args{t1, SignSSHOptions{CertType: "host"}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-principals", p1, args{t1, SignSSHOptions{Principals: []string{"127.0.0.1", "ip-127-0-0-1.us-west-1.compute.internal"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-principal-ip", p1, args{t1, SignSSHOptions{Principals: []string{"127.0.0.1"}}, pub}, expectedHostOptionsIP, http.StatusOK, false, false},
|
||||
{"ok-principal-hostname", p1, args{t1, SignSSHOptions{Principals: []string{"ip-127-0-0-1.us-west-1.compute.internal"}}, pub}, expectedHostOptionsHostname, http.StatusOK, false, false},
|
||||
{"ok-options", p1, args{t1, SignSSHOptions{CertType: "host", Principals: []string{"127.0.0.1", "ip-127-0-0-1.us-west-1.compute.internal"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-custom", p2, args{t2, SignSSHOptions{Principals: []string{"foo.local"}}, pub}, expectedCustomOptions, http.StatusOK, false, false},
|
||||
{"fail-rsa1024", p1, args{t1, SignSSHOptions{}, rsa1024.Public()}, expectedHostOptions, http.StatusOK, false, true},
|
||||
{"fail-type", p1, args{t1, SignSSHOptions{CertType: "user"}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-principal", p1, args{t1, SignSSHOptions{Principals: []string{"smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-extra-principal", p1, args{t1, SignSSHOptions{Principals: []string{"127.0.0.1", "ip-127-0-0-1.us-west-1.compute.internal", "smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-sshCA-disabled", p3, args{"foo", SignSSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
{"fail-invalid-token", p1, args{"foo", SignSSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
@ -83,15 +83,15 @@ type azurePayload struct {
|
|||
// and https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service
|
||||
type Azure struct {
|
||||
*base
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
TenantID string `json:"tenantID"`
|
||||
ResourceGroups []string `json:"resourceGroups"`
|
||||
Audience string `json:"audience,omitempty"`
|
||||
DisableCustomSANs bool `json:"disableCustomSANs"`
|
||||
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *ProvisionerOptions `json:"options,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
TenantID string `json:"tenantID"`
|
||||
ResourceGroups []string `json:"resourceGroups"`
|
||||
Audience string `json:"audience,omitempty"`
|
||||
DisableCustomSANs bool `json:"disableCustomSANs"`
|
||||
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *Options `json:"options,omitempty"`
|
||||
claimer *Claimer
|
||||
config *azureConfig
|
||||
oidcConfig openIDConfiguration
|
||||
|
@ -350,7 +350,7 @@ func (p *Azure) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOptio
|
|||
}
|
||||
|
||||
// Default to host + known hostnames
|
||||
defaults := SSHOptions{
|
||||
defaults := SignSSHOptions{
|
||||
CertType: SSHHostCert,
|
||||
Principals: principals,
|
||||
}
|
||||
|
|
|
@ -571,41 +571,41 @@ func TestAzure_AuthorizeSSHSign(t *testing.T) {
|
|||
assert.FatalError(t, err)
|
||||
|
||||
hostDuration := p1.claimer.DefaultHostSSHCertDuration()
|
||||
expectedHostOptions := &SSHOptions{
|
||||
expectedHostOptions := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"virtualMachine"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
expectedCustomOptions := &SSHOptions{
|
||||
expectedCustomOptions := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"foo.bar"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
|
||||
type args struct {
|
||||
token string
|
||||
sshOpts SSHOptions
|
||||
sshOpts SignSSHOptions
|
||||
key interface{}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
azure *Azure
|
||||
args args
|
||||
expected *SSHOptions
|
||||
expected *SignSSHOptions
|
||||
code int
|
||||
wantErr bool
|
||||
wantSignErr bool
|
||||
}{
|
||||
{"ok", p1, args{t1, SSHOptions{}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-rsa2048", p1, args{t1, SSHOptions{}, rsa2048.Public()}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-type", p1, args{t1, SSHOptions{CertType: "host"}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-principals", p1, args{t1, SSHOptions{Principals: []string{"virtualMachine"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-options", p1, args{t1, SSHOptions{CertType: "host", Principals: []string{"virtualMachine"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-custom", p2, args{t2, SSHOptions{Principals: []string{"foo.bar"}}, pub}, expectedCustomOptions, http.StatusOK, false, false},
|
||||
{"fail-rsa1024", p1, args{t1, SSHOptions{}, rsa1024.Public()}, expectedHostOptions, http.StatusOK, false, true},
|
||||
{"fail-type", p1, args{t1, SSHOptions{CertType: "user"}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-principal", p1, args{t1, SSHOptions{Principals: []string{"smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-extra-principal", p1, args{t1, SSHOptions{Principals: []string{"virtualMachine", "smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-sshCA-disabled", p3, args{"foo", SSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
{"fail-invalid-token", p1, args{"foo", SSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
{"ok", p1, args{t1, SignSSHOptions{}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-rsa2048", p1, args{t1, SignSSHOptions{}, rsa2048.Public()}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-type", p1, args{t1, SignSSHOptions{CertType: "host"}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-principals", p1, args{t1, SignSSHOptions{Principals: []string{"virtualMachine"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-options", p1, args{t1, SignSSHOptions{CertType: "host", Principals: []string{"virtualMachine"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-custom", p2, args{t2, SignSSHOptions{Principals: []string{"foo.bar"}}, pub}, expectedCustomOptions, http.StatusOK, false, false},
|
||||
{"fail-rsa1024", p1, args{t1, SignSSHOptions{}, rsa1024.Public()}, expectedHostOptions, http.StatusOK, false, true},
|
||||
{"fail-type", p1, args{t1, SignSSHOptions{CertType: "user"}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-principal", p1, args{t1, SignSSHOptions{Principals: []string{"smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-extra-principal", p1, args{t1, SignSSHOptions{Principals: []string{"virtualMachine", "smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-sshCA-disabled", p3, args{"foo", SignSSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
{"fail-invalid-token", p1, args{"foo", SignSSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
@ -77,15 +77,15 @@ func newGCPConfig() *gcpConfig {
|
|||
// https://cloud.google.com/compute/docs/instances/verifying-instance-identity
|
||||
type GCP struct {
|
||||
*base
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
ServiceAccounts []string `json:"serviceAccounts"`
|
||||
ProjectIDs []string `json:"projectIDs"`
|
||||
DisableCustomSANs bool `json:"disableCustomSANs"`
|
||||
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
||||
InstanceAge Duration `json:"instanceAge,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *ProvisionerOptions `json:"options,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
ServiceAccounts []string `json:"serviceAccounts"`
|
||||
ProjectIDs []string `json:"projectIDs"`
|
||||
DisableCustomSANs bool `json:"disableCustomSANs"`
|
||||
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
||||
InstanceAge Duration `json:"instanceAge,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *Options `json:"options,omitempty"`
|
||||
claimer *Claimer
|
||||
config *gcpConfig
|
||||
keyStore *keyStore
|
||||
|
@ -394,7 +394,7 @@ func (p *GCP) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
|
|||
}
|
||||
|
||||
// Default to host + known hostnames
|
||||
defaults := SSHOptions{
|
||||
defaults := SignSSHOptions{
|
||||
CertType: SSHHostCert,
|
||||
Principals: principals,
|
||||
}
|
||||
|
|
|
@ -623,51 +623,51 @@ func TestGCP_AuthorizeSSHSign(t *testing.T) {
|
|||
assert.FatalError(t, err)
|
||||
|
||||
hostDuration := p1.claimer.DefaultHostSSHCertDuration()
|
||||
expectedHostOptions := &SSHOptions{
|
||||
expectedHostOptions := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"instance-name.c.project-id.internal", "instance-name.zone.c.project-id.internal"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
expectedHostOptionsPrincipal1 := &SSHOptions{
|
||||
expectedHostOptionsPrincipal1 := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"instance-name.c.project-id.internal"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
expectedHostOptionsPrincipal2 := &SSHOptions{
|
||||
expectedHostOptionsPrincipal2 := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"instance-name.zone.c.project-id.internal"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
expectedCustomOptions := &SSHOptions{
|
||||
expectedCustomOptions := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"foo.bar", "bar.foo"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
|
||||
type args struct {
|
||||
token string
|
||||
sshOpts SSHOptions
|
||||
sshOpts SignSSHOptions
|
||||
key interface{}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
gcp *GCP
|
||||
args args
|
||||
expected *SSHOptions
|
||||
expected *SignSSHOptions
|
||||
code int
|
||||
wantErr bool
|
||||
wantSignErr bool
|
||||
}{
|
||||
{"ok", p1, args{t1, SSHOptions{}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-rsa2048", p1, args{t1, SSHOptions{}, rsa2048.Public()}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-type", p1, args{t1, SSHOptions{CertType: "host"}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-principals", p1, args{t1, SSHOptions{Principals: []string{"instance-name.c.project-id.internal", "instance-name.zone.c.project-id.internal"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-principal1", p1, args{t1, SSHOptions{Principals: []string{"instance-name.c.project-id.internal"}}, pub}, expectedHostOptionsPrincipal1, http.StatusOK, false, false},
|
||||
{"ok-principal2", p1, args{t1, SSHOptions{Principals: []string{"instance-name.zone.c.project-id.internal"}}, pub}, expectedHostOptionsPrincipal2, http.StatusOK, false, false},
|
||||
{"ok-options", p1, args{t1, SSHOptions{CertType: "host", Principals: []string{"instance-name.c.project-id.internal", "instance-name.zone.c.project-id.internal"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-custom", p2, args{t2, SSHOptions{Principals: []string{"foo.bar", "bar.foo"}}, pub}, expectedCustomOptions, http.StatusOK, false, false},
|
||||
{"fail-rsa1024", p1, args{t1, SSHOptions{}, rsa1024.Public()}, expectedHostOptions, http.StatusOK, false, true},
|
||||
{"fail-type", p1, args{t1, SSHOptions{CertType: "user"}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-principal", p1, args{t1, SSHOptions{Principals: []string{"smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-extra-principal", p1, args{t1, SSHOptions{Principals: []string{"instance-name.c.project-id.internal", "instance-name.zone.c.project-id.internal", "smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-sshCA-disabled", p3, args{"foo", SSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
{"fail-invalid-token", p1, args{"foo", SSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
{"ok", p1, args{t1, SignSSHOptions{}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-rsa2048", p1, args{t1, SignSSHOptions{}, rsa2048.Public()}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-type", p1, args{t1, SignSSHOptions{CertType: "host"}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-principals", p1, args{t1, SignSSHOptions{Principals: []string{"instance-name.c.project-id.internal", "instance-name.zone.c.project-id.internal"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-principal1", p1, args{t1, SignSSHOptions{Principals: []string{"instance-name.c.project-id.internal"}}, pub}, expectedHostOptionsPrincipal1, http.StatusOK, false, false},
|
||||
{"ok-principal2", p1, args{t1, SignSSHOptions{Principals: []string{"instance-name.zone.c.project-id.internal"}}, pub}, expectedHostOptionsPrincipal2, http.StatusOK, false, false},
|
||||
{"ok-options", p1, args{t1, SignSSHOptions{CertType: "host", Principals: []string{"instance-name.c.project-id.internal", "instance-name.zone.c.project-id.internal"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"ok-custom", p2, args{t2, SignSSHOptions{Principals: []string{"foo.bar", "bar.foo"}}, pub}, expectedCustomOptions, http.StatusOK, false, false},
|
||||
{"fail-rsa1024", p1, args{t1, SignSSHOptions{}, rsa1024.Public()}, expectedHostOptions, http.StatusOK, false, true},
|
||||
{"fail-type", p1, args{t1, SignSSHOptions{CertType: "user"}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-principal", p1, args{t1, SignSSHOptions{Principals: []string{"smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-extra-principal", p1, args{t1, SignSSHOptions{Principals: []string{"instance-name.c.project-id.internal", "instance-name.zone.c.project-id.internal", "smallstep.com"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-sshCA-disabled", p3, args{"foo", SignSSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
{"fail-invalid-token", p1, args{"foo", SignSSHOptions{}, pub}, expectedHostOptions, http.StatusUnauthorized, true, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
@ -20,19 +20,19 @@ type jwtPayload struct {
|
|||
}
|
||||
|
||||
type stepPayload struct {
|
||||
SSH *SSHOptions `json:"ssh,omitempty"`
|
||||
SSH *SignSSHOptions `json:"ssh,omitempty"`
|
||||
}
|
||||
|
||||
// JWK is the default provisioner, an entity that can sign tokens necessary for
|
||||
// signature requests.
|
||||
type JWK struct {
|
||||
*base
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Key *jose.JSONWebKey `json:"key"`
|
||||
EncryptedKey string `json:"encryptedKey,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *ProvisionerOptions `json:"options,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Key *jose.JSONWebKey `json:"key"`
|
||||
EncryptedKey string `json:"encryptedKey,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *Options `json:"options,omitempty"`
|
||||
claimer *Claimer
|
||||
audiences Audiences
|
||||
}
|
||||
|
|
|
@ -404,41 +404,41 @@ func TestJWK_AuthorizeSSHSign(t *testing.T) {
|
|||
|
||||
userDuration := p1.claimer.DefaultUserSSHCertDuration()
|
||||
hostDuration := p1.claimer.DefaultHostSSHCertDuration()
|
||||
expectedUserOptions := &SSHOptions{
|
||||
expectedUserOptions := &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration)),
|
||||
}
|
||||
expectedHostOptions := &SSHOptions{
|
||||
expectedHostOptions := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"smallstep.com"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
|
||||
type args struct {
|
||||
token string
|
||||
sshOpts SSHOptions
|
||||
sshOpts SignSSHOptions
|
||||
key interface{}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
prov *JWK
|
||||
args args
|
||||
expected *SSHOptions
|
||||
expected *SignSSHOptions
|
||||
code int
|
||||
wantErr bool
|
||||
wantSignErr bool
|
||||
}{
|
||||
{"user", p1, args{t1, SSHOptions{}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"user-rsa2048", p1, args{t1, SSHOptions{}, rsa2048.Public()}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"user-type", p1, args{t1, SSHOptions{CertType: "user"}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"user-principals", p1, args{t1, SSHOptions{Principals: []string{"name"}}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"user-options", p1, args{t1, SSHOptions{CertType: "user", Principals: []string{"name"}}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"host", p1, args{t2, SSHOptions{}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"host-type", p1, args{t2, SSHOptions{CertType: "host"}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"host-principals", p1, args{t2, SSHOptions{Principals: []string{"smallstep.com"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"host-options", p1, args{t2, SSHOptions{CertType: "host", Principals: []string{"smallstep.com"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"fail-sshCA-disabled", p2, args{"foo", SSHOptions{}, pub}, expectedUserOptions, http.StatusUnauthorized, true, false},
|
||||
{"fail-signature", p1, args{failSig, SSHOptions{}, pub}, nil, http.StatusUnauthorized, true, false},
|
||||
{"rail-rsa1024", p1, args{t1, SSHOptions{}, rsa1024.Public()}, expectedUserOptions, http.StatusOK, false, true},
|
||||
{"user", p1, args{t1, SignSSHOptions{}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"user-rsa2048", p1, args{t1, SignSSHOptions{}, rsa2048.Public()}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"user-type", p1, args{t1, SignSSHOptions{CertType: "user"}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"user-principals", p1, args{t1, SignSSHOptions{Principals: []string{"name"}}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"user-options", p1, args{t1, SignSSHOptions{CertType: "user", Principals: []string{"name"}}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"host", p1, args{t2, SignSSHOptions{}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"host-type", p1, args{t2, SignSSHOptions{CertType: "host"}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"host-principals", p1, args{t2, SignSSHOptions{Principals: []string{"smallstep.com"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"host-options", p1, args{t2, SignSSHOptions{CertType: "host", Principals: []string{"smallstep.com"}}, pub}, expectedHostOptions, http.StatusOK, false, false},
|
||||
{"fail-sshCA-disabled", p2, args{"foo", SignSSHOptions{}, pub}, expectedUserOptions, http.StatusUnauthorized, true, false},
|
||||
{"fail-signature", p1, args{failSig, SignSSHOptions{}, pub}, nil, http.StatusUnauthorized, true, false},
|
||||
{"rail-rsa1024", p1, args{t1, SignSSHOptions{}, rsa1024.Public()}, expectedUserOptions, http.StatusOK, false, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
@ -487,72 +487,72 @@ func TestJWK_AuthorizeSign_SSHOptions(t *testing.T) {
|
|||
|
||||
userDuration := p1.claimer.DefaultUserSSHCertDuration()
|
||||
hostDuration := p1.claimer.DefaultHostSSHCertDuration()
|
||||
expectedUserOptions := &SSHOptions{
|
||||
expectedUserOptions := &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration)),
|
||||
}
|
||||
expectedHostOptions := &SSHOptions{
|
||||
expectedHostOptions := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"smallstep.com"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
type args struct {
|
||||
sub, iss, aud string
|
||||
iat time.Time
|
||||
tokSSHOpts *SSHOptions
|
||||
userSSHOpts *SSHOptions
|
||||
tokSSHOpts *SignSSHOptions
|
||||
userSSHOpts *SignSSHOptions
|
||||
jwk *jose.JSONWebKey
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
prov *JWK
|
||||
args args
|
||||
expected *SSHOptions
|
||||
expected *SignSSHOptions
|
||||
wantErr bool
|
||||
wantSignErr bool
|
||||
}{
|
||||
{"ok-user", p1, args{sub, iss, aud, iat, &SSHOptions{CertType: "user", Principals: []string{"name"}}, &SSHOptions{}, jwk}, expectedUserOptions, false, false},
|
||||
{"ok-host", p1, args{sub, iss, aud, iat, &SSHOptions{CertType: "host", Principals: []string{"smallstep.com"}}, &SSHOptions{}, jwk}, expectedHostOptions, false, false},
|
||||
{"ok-user-opts", p1, args{sub, iss, aud, iat, &SSHOptions{}, &SSHOptions{CertType: "user", Principals: []string{"name"}}, jwk}, expectedUserOptions, false, false},
|
||||
{"ok-host-opts", p1, args{sub, iss, aud, iat, &SSHOptions{}, &SSHOptions{CertType: "host", Principals: []string{"smallstep.com"}}, jwk}, expectedHostOptions, false, false},
|
||||
{"ok-user-mixed", p1, args{sub, iss, aud, iat, &SSHOptions{CertType: "user"}, &SSHOptions{Principals: []string{"name"}}, jwk}, expectedUserOptions, false, false},
|
||||
{"ok-host-mixed", p1, args{sub, iss, aud, iat, &SSHOptions{Principals: []string{"smallstep.com"}}, &SSHOptions{CertType: "host"}, jwk}, expectedHostOptions, false, false},
|
||||
{"ok-user-validAfter", p1, args{sub, iss, aud, iat, &SSHOptions{
|
||||
{"ok-user", p1, args{sub, iss, aud, iat, &SignSSHOptions{CertType: "user", Principals: []string{"name"}}, &SignSSHOptions{}, jwk}, expectedUserOptions, false, false},
|
||||
{"ok-host", p1, args{sub, iss, aud, iat, &SignSSHOptions{CertType: "host", Principals: []string{"smallstep.com"}}, &SignSSHOptions{}, jwk}, expectedHostOptions, false, false},
|
||||
{"ok-user-opts", p1, args{sub, iss, aud, iat, &SignSSHOptions{}, &SignSSHOptions{CertType: "user", Principals: []string{"name"}}, jwk}, expectedUserOptions, false, false},
|
||||
{"ok-host-opts", p1, args{sub, iss, aud, iat, &SignSSHOptions{}, &SignSSHOptions{CertType: "host", Principals: []string{"smallstep.com"}}, jwk}, expectedHostOptions, false, false},
|
||||
{"ok-user-mixed", p1, args{sub, iss, aud, iat, &SignSSHOptions{CertType: "user"}, &SignSSHOptions{Principals: []string{"name"}}, jwk}, expectedUserOptions, false, false},
|
||||
{"ok-host-mixed", p1, args{sub, iss, aud, iat, &SignSSHOptions{Principals: []string{"smallstep.com"}}, &SignSSHOptions{CertType: "host"}, jwk}, expectedHostOptions, false, false},
|
||||
{"ok-user-validAfter", p1, args{sub, iss, aud, iat, &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name"},
|
||||
}, &SSHOptions{
|
||||
}, &SignSSHOptions{
|
||||
ValidAfter: NewTimeDuration(tm.Add(-time.Hour)),
|
||||
}, jwk}, &SSHOptions{
|
||||
}, jwk}, &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name"}, ValidAfter: NewTimeDuration(tm.Add(-time.Hour)), ValidBefore: NewTimeDuration(tm.Add(userDuration - time.Hour)),
|
||||
}, false, false},
|
||||
{"ok-user-validBefore", p1, args{sub, iss, aud, iat, &SSHOptions{
|
||||
{"ok-user-validBefore", p1, args{sub, iss, aud, iat, &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name"},
|
||||
}, &SSHOptions{
|
||||
}, &SignSSHOptions{
|
||||
ValidBefore: NewTimeDuration(tm.Add(time.Hour)),
|
||||
}, jwk}, &SSHOptions{
|
||||
}, jwk}, &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name"}, ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(time.Hour)),
|
||||
}, false, false},
|
||||
{"ok-user-validAfter-validBefore", p1, args{sub, iss, aud, iat, &SSHOptions{
|
||||
{"ok-user-validAfter-validBefore", p1, args{sub, iss, aud, iat, &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name"},
|
||||
}, &SSHOptions{
|
||||
}, &SignSSHOptions{
|
||||
ValidAfter: NewTimeDuration(tm.Add(10 * time.Minute)), ValidBefore: NewTimeDuration(tm.Add(time.Hour)),
|
||||
}, jwk}, &SSHOptions{
|
||||
}, jwk}, &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name"}, ValidAfter: NewTimeDuration(tm.Add(10 * time.Minute)), ValidBefore: NewTimeDuration(tm.Add(time.Hour)),
|
||||
}, false, false},
|
||||
{"ok-user-match", p1, args{sub, iss, aud, iat, &SSHOptions{
|
||||
{"ok-user-match", p1, args{sub, iss, aud, iat, &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name"}, ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(1 * time.Hour)),
|
||||
}, &SSHOptions{
|
||||
}, &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name"}, ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(1 * time.Hour)),
|
||||
}, jwk}, &SSHOptions{
|
||||
}, jwk}, &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name"}, ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(time.Hour)),
|
||||
}, false, false},
|
||||
{"fail-certType", p1, args{sub, iss, aud, iat, &SSHOptions{CertType: "user", Principals: []string{"name"}}, &SSHOptions{CertType: "host"}, jwk}, nil, false, true},
|
||||
{"fail-principals", p1, args{sub, iss, aud, iat, &SSHOptions{CertType: "user", Principals: []string{"name"}}, &SSHOptions{Principals: []string{"root"}}, jwk}, nil, false, true},
|
||||
{"fail-validAfter", p1, args{sub, iss, aud, iat, &SSHOptions{CertType: "user", Principals: []string{"name"}, ValidAfter: NewTimeDuration(tm)}, &SSHOptions{ValidAfter: NewTimeDuration(tm.Add(time.Hour))}, jwk}, nil, false, true},
|
||||
{"fail-validBefore", p1, args{sub, iss, aud, iat, &SSHOptions{CertType: "user", Principals: []string{"name"}, ValidBefore: NewTimeDuration(tm.Add(time.Hour))}, &SSHOptions{ValidBefore: NewTimeDuration(tm.Add(10 * time.Hour))}, jwk}, nil, false, true},
|
||||
{"fail-subject", p1, args{"", iss, aud, iat, &SSHOptions{CertType: "user", Principals: []string{"name"}}, &SSHOptions{}, jwk}, nil, true, false},
|
||||
{"fail-issuer", p1, args{sub, "invalid", aud, iat, &SSHOptions{CertType: "user", Principals: []string{"name"}}, &SSHOptions{}, jwk}, nil, true, false},
|
||||
{"fail-audience", p1, args{sub, iss, "invalid", iat, &SSHOptions{CertType: "user", Principals: []string{"name"}}, &SSHOptions{}, jwk}, nil, true, false},
|
||||
{"fail-expired", p1, args{sub, iss, aud, iat.Add(-6 * time.Minute), &SSHOptions{CertType: "user", Principals: []string{"name"}}, &SSHOptions{}, jwk}, nil, true, false},
|
||||
{"fail-notBefore", p1, args{sub, iss, aud, iat.Add(5 * time.Minute), &SSHOptions{CertType: "user", Principals: []string{"name"}}, &SSHOptions{}, jwk}, nil, true, false},
|
||||
{"fail-certType", p1, args{sub, iss, aud, iat, &SignSSHOptions{CertType: "user", Principals: []string{"name"}}, &SignSSHOptions{CertType: "host"}, jwk}, nil, false, true},
|
||||
{"fail-principals", p1, args{sub, iss, aud, iat, &SignSSHOptions{CertType: "user", Principals: []string{"name"}}, &SignSSHOptions{Principals: []string{"root"}}, jwk}, nil, false, true},
|
||||
{"fail-validAfter", p1, args{sub, iss, aud, iat, &SignSSHOptions{CertType: "user", Principals: []string{"name"}, ValidAfter: NewTimeDuration(tm)}, &SignSSHOptions{ValidAfter: NewTimeDuration(tm.Add(time.Hour))}, jwk}, nil, false, true},
|
||||
{"fail-validBefore", p1, args{sub, iss, aud, iat, &SignSSHOptions{CertType: "user", Principals: []string{"name"}, ValidBefore: NewTimeDuration(tm.Add(time.Hour))}, &SignSSHOptions{ValidBefore: NewTimeDuration(tm.Add(10 * time.Hour))}, jwk}, nil, false, true},
|
||||
{"fail-subject", p1, args{"", iss, aud, iat, &SignSSHOptions{CertType: "user", Principals: []string{"name"}}, &SignSSHOptions{}, jwk}, nil, true, false},
|
||||
{"fail-issuer", p1, args{sub, "invalid", aud, iat, &SignSSHOptions{CertType: "user", Principals: []string{"name"}}, &SignSSHOptions{}, jwk}, nil, true, false},
|
||||
{"fail-audience", p1, args{sub, iss, "invalid", iat, &SignSSHOptions{CertType: "user", Principals: []string{"name"}}, &SignSSHOptions{}, jwk}, nil, true, false},
|
||||
{"fail-expired", p1, args{sub, iss, aud, iat.Add(-6 * time.Minute), &SignSSHOptions{CertType: "user", Principals: []string{"name"}}, &SignSSHOptions{}, jwk}, nil, true, false},
|
||||
{"fail-notBefore", p1, args{sub, iss, aud, iat.Add(5 * time.Minute), &SignSSHOptions{CertType: "user", Principals: []string{"name"}}, &SignSSHOptions{}, jwk}, nil, true, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
@ -561,7 +561,7 @@ func TestJWK_AuthorizeSign_SSHOptions(t *testing.T) {
|
|||
if got, err := tt.prov.AuthorizeSSHSign(context.Background(), token); (err != nil) != tt.wantErr {
|
||||
t.Errorf("JWK.AuthorizeSSHSign() error = %v, wantErr %v", err, tt.wantErr)
|
||||
} else if !tt.wantErr && assert.NotNil(t, got) {
|
||||
var opts SSHOptions
|
||||
var opts SignSSHOptions
|
||||
if tt.args.userSSHOpts != nil {
|
||||
opts = *tt.args.userSSHOpts
|
||||
}
|
||||
|
|
|
@ -41,11 +41,11 @@ type k8sSAPayload struct {
|
|||
// entity trusted to make signature requests.
|
||||
type K8sSA struct {
|
||||
*base
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
PubKeys []byte `json:"publicKeys,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *ProvisionerOptions `json:"options,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
PubKeys []byte `json:"publicKeys,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *Options `json:"options,omitempty"`
|
||||
claimer *Claimer
|
||||
audiences Audiences
|
||||
//kauthn kauthn.AuthenticationV1Interface
|
||||
|
|
|
@ -53,18 +53,18 @@ type openIDPayload struct {
|
|||
// ClientSecret is mandatory, but it can be an empty string.
|
||||
type OIDC struct {
|
||||
*base
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
ClientID string `json:"clientID"`
|
||||
ClientSecret string `json:"clientSecret"`
|
||||
ConfigurationEndpoint string `json:"configurationEndpoint"`
|
||||
TenantID string `json:"tenantID,omitempty"`
|
||||
Admins []string `json:"admins,omitempty"`
|
||||
Domains []string `json:"domains,omitempty"`
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
ListenAddress string `json:"listenAddress,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *ProvisionerOptions `json:"options,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
ClientID string `json:"clientID"`
|
||||
ClientSecret string `json:"clientSecret"`
|
||||
ConfigurationEndpoint string `json:"configurationEndpoint"`
|
||||
TenantID string `json:"tenantID,omitempty"`
|
||||
Admins []string `json:"admins,omitempty"`
|
||||
Domains []string `json:"domains,omitempty"`
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
ListenAddress string `json:"listenAddress,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *Options `json:"options,omitempty"`
|
||||
configuration openIDConfiguration
|
||||
keyStore *keyStore
|
||||
claimer *Claimer
|
||||
|
@ -380,7 +380,7 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption
|
|||
if err != nil {
|
||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSSHSign")
|
||||
}
|
||||
defaults := SSHOptions{
|
||||
defaults := SignSSHOptions{
|
||||
CertType: SSHUserCert,
|
||||
Principals: iden.Usernames,
|
||||
}
|
||||
|
|
|
@ -534,64 +534,64 @@ func TestOIDC_AuthorizeSSHSign(t *testing.T) {
|
|||
|
||||
userDuration := p1.claimer.DefaultUserSSHCertDuration()
|
||||
hostDuration := p1.claimer.DefaultHostSSHCertDuration()
|
||||
expectedUserOptions := &SSHOptions{
|
||||
expectedUserOptions := &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"name", "name@smallstep.com"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration)),
|
||||
}
|
||||
expectedAdminOptions := &SSHOptions{
|
||||
expectedAdminOptions := &SignSSHOptions{
|
||||
CertType: "user", Principals: []string{"root", "root@example.com"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration)),
|
||||
}
|
||||
expectedHostOptions := &SSHOptions{
|
||||
expectedHostOptions := &SignSSHOptions{
|
||||
CertType: "host", Principals: []string{"smallstep.com"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
|
||||
}
|
||||
|
||||
type args struct {
|
||||
token string
|
||||
sshOpts SSHOptions
|
||||
sshOpts SignSSHOptions
|
||||
key interface{}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
prov *OIDC
|
||||
args args
|
||||
expected *SSHOptions
|
||||
expected *SignSSHOptions
|
||||
code int
|
||||
wantErr bool
|
||||
wantSignErr bool
|
||||
}{
|
||||
{"ok", p1, args{t1, SSHOptions{}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"ok-rsa2048", p1, args{t1, SSHOptions{}, rsa2048.Public()}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"ok-user", p1, args{t1, SSHOptions{CertType: "user"}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"ok-principals", p1, args{t1, SSHOptions{Principals: []string{"name"}}, pub},
|
||||
&SSHOptions{CertType: "user", Principals: []string{"name"},
|
||||
{"ok", p1, args{t1, SignSSHOptions{}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"ok-rsa2048", p1, args{t1, SignSSHOptions{}, rsa2048.Public()}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"ok-user", p1, args{t1, SignSSHOptions{CertType: "user"}, pub}, expectedUserOptions, http.StatusOK, false, false},
|
||||
{"ok-principals", p1, args{t1, SignSSHOptions{Principals: []string{"name"}}, pub},
|
||||
&SignSSHOptions{CertType: "user", Principals: []string{"name"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration))}, http.StatusOK, false, false},
|
||||
{"ok-principals-getIdentity", p4, args{okGetIdentityToken, SSHOptions{Principals: []string{"mariano"}}, pub},
|
||||
&SSHOptions{CertType: "user", Principals: []string{"mariano"},
|
||||
{"ok-principals-getIdentity", p4, args{okGetIdentityToken, SignSSHOptions{Principals: []string{"mariano"}}, pub},
|
||||
&SignSSHOptions{CertType: "user", Principals: []string{"mariano"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration))}, http.StatusOK, false, false},
|
||||
{"ok-emptyPrincipals-getIdentity", p4, args{okGetIdentityToken, SSHOptions{}, pub},
|
||||
&SSHOptions{CertType: "user", Principals: []string{"max", "mariano"},
|
||||
{"ok-emptyPrincipals-getIdentity", p4, args{okGetIdentityToken, SignSSHOptions{}, pub},
|
||||
&SignSSHOptions{CertType: "user", Principals: []string{"max", "mariano"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration))}, http.StatusOK, false, false},
|
||||
{"ok-options", p1, args{t1, SSHOptions{CertType: "user", Principals: []string{"name"}}, pub},
|
||||
&SSHOptions{CertType: "user", Principals: []string{"name"},
|
||||
{"ok-options", p1, args{t1, SignSSHOptions{CertType: "user", Principals: []string{"name"}}, pub},
|
||||
&SignSSHOptions{CertType: "user", Principals: []string{"name"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration))}, http.StatusOK, false, false},
|
||||
{"admin", p3, args{okAdmin, SSHOptions{}, pub}, expectedAdminOptions, http.StatusOK, false, false},
|
||||
{"admin-user", p3, args{okAdmin, SSHOptions{CertType: "user"}, pub}, expectedAdminOptions, http.StatusOK, false, false},
|
||||
{"admin-principals", p3, args{okAdmin, SSHOptions{Principals: []string{"root"}}, pub},
|
||||
&SSHOptions{CertType: "user", Principals: []string{"root"},
|
||||
{"admin", p3, args{okAdmin, SignSSHOptions{}, pub}, expectedAdminOptions, http.StatusOK, false, false},
|
||||
{"admin-user", p3, args{okAdmin, SignSSHOptions{CertType: "user"}, pub}, expectedAdminOptions, http.StatusOK, false, false},
|
||||
{"admin-principals", p3, args{okAdmin, SignSSHOptions{Principals: []string{"root"}}, pub},
|
||||
&SignSSHOptions{CertType: "user", Principals: []string{"root"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration))}, http.StatusOK, false, false},
|
||||
{"admin-options", p3, args{okAdmin, SSHOptions{CertType: "user", Principals: []string{"name"}}, pub},
|
||||
&SSHOptions{CertType: "user", Principals: []string{"name"},
|
||||
{"admin-options", p3, args{okAdmin, SignSSHOptions{CertType: "user", Principals: []string{"name"}}, pub},
|
||||
&SignSSHOptions{CertType: "user", Principals: []string{"name"},
|
||||
ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration))}, http.StatusOK, false, false},
|
||||
{"admin-host", p3, args{okAdmin, SSHOptions{CertType: "host", Principals: []string{"smallstep.com"}}, pub},
|
||||
{"admin-host", p3, args{okAdmin, SignSSHOptions{CertType: "host", Principals: []string{"smallstep.com"}}, pub},
|
||||
expectedHostOptions, http.StatusOK, false, false},
|
||||
{"fail-rsa1024", p1, args{t1, SSHOptions{}, rsa1024.Public()}, expectedUserOptions, http.StatusOK, false, true},
|
||||
{"fail-user-host", p1, args{t1, SSHOptions{CertType: "host"}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-user-principals", p1, args{t1, SSHOptions{Principals: []string{"root"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-email", p3, args{failEmail, SSHOptions{}, pub}, nil, http.StatusUnauthorized, true, false},
|
||||
{"fail-getIdentity", p5, args{failGetIdentityToken, SSHOptions{}, pub}, nil, http.StatusInternalServerError, true, false},
|
||||
{"fail-sshCA-disabled", p6, args{"foo", SSHOptions{}, pub}, nil, http.StatusUnauthorized, true, false},
|
||||
{"fail-rsa1024", p1, args{t1, SignSSHOptions{}, rsa1024.Public()}, expectedUserOptions, http.StatusOK, false, true},
|
||||
{"fail-user-host", p1, args{t1, SignSSHOptions{CertType: "host"}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-user-principals", p1, args{t1, SignSSHOptions{Principals: []string{"root"}}, pub}, nil, http.StatusOK, false, true},
|
||||
{"fail-email", p3, args{failEmail, SignSSHOptions{}, pub}, nil, http.StatusUnauthorized, true, false},
|
||||
{"fail-getIdentity", p5, args{failGetIdentityToken, SignSSHOptions{}, pub}, nil, http.StatusInternalServerError, true, false},
|
||||
{"fail-sshCA-disabled", p6, args{"foo", SignSSHOptions{}, pub}, nil, http.StatusUnauthorized, true, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
@ -12,19 +12,18 @@ import (
|
|||
// CertificateOptions is an interface that returns a list of options passed when
|
||||
// creating a new certificate.
|
||||
type CertificateOptions interface {
|
||||
Options(Options) []x509util.Option
|
||||
Options(SignOptions) []x509util.Option
|
||||
}
|
||||
|
||||
type certificateOptionsFunc func(Options) []x509util.Option
|
||||
type certificateOptionsFunc func(SignOptions) []x509util.Option
|
||||
|
||||
func (fn certificateOptionsFunc) Options(so Options) []x509util.Option {
|
||||
func (fn certificateOptionsFunc) Options(so SignOptions) []x509util.Option {
|
||||
return fn(so)
|
||||
}
|
||||
|
||||
// ProvisionerOptions are a collection of custom options that can be added to
|
||||
// Options are a collection of custom options that can be added to
|
||||
// each provisioner.
|
||||
// nolint:golint
|
||||
type ProvisionerOptions struct {
|
||||
type Options struct {
|
||||
// Template contains a X.509 certificate template. It can be a JSON template
|
||||
// escaped in a string or it can be also encoded in base64.
|
||||
Template string `json:"template"`
|
||||
|
@ -38,7 +37,7 @@ type ProvisionerOptions struct {
|
|||
}
|
||||
|
||||
// HasTemplate returns true if a template is defined in the provisioner options.
|
||||
func (o *ProvisionerOptions) HasTemplate() bool {
|
||||
func (o *Options) HasTemplate() bool {
|
||||
return o != nil && (o.Template != "" || o.TemplateFile != "")
|
||||
}
|
||||
|
||||
|
@ -46,7 +45,7 @@ func (o *ProvisionerOptions) HasTemplate() bool {
|
|||
// defined in the ProvisionerOptions, the provisioner generated data, and the
|
||||
// user data provided in the request. If no template has been provided,
|
||||
// x509util.DefaultLeafTemplate will be used.
|
||||
func TemplateOptions(o *ProvisionerOptions, data x509util.TemplateData) (CertificateOptions, error) {
|
||||
func TemplateOptions(o *Options, data x509util.TemplateData) (CertificateOptions, error) {
|
||||
return CustomTemplateOptions(o, data, x509util.DefaultLeafTemplate)
|
||||
}
|
||||
|
||||
|
@ -54,7 +53,7 @@ func TemplateOptions(o *ProvisionerOptions, data x509util.TemplateData) (Certifi
|
|||
// defined in the ProvisionerOptions, the provisioner generated data and the
|
||||
// user data provided in the request. If no template has been provided in the
|
||||
// ProvisionerOptions, the given template will be used.
|
||||
func CustomTemplateOptions(o *ProvisionerOptions, data x509util.TemplateData, defaultTemplate string) (CertificateOptions, error) {
|
||||
func CustomTemplateOptions(o *Options, data x509util.TemplateData, defaultTemplate string) (CertificateOptions, error) {
|
||||
if o != nil {
|
||||
if data == nil {
|
||||
data = x509util.NewTemplateData()
|
||||
|
@ -68,7 +67,7 @@ func CustomTemplateOptions(o *ProvisionerOptions, data x509util.TemplateData, de
|
|||
}
|
||||
}
|
||||
|
||||
return certificateOptionsFunc(func(so Options) []x509util.Option {
|
||||
return certificateOptionsFunc(func(so SignOptions) []x509util.Option {
|
||||
// We're not provided user data without custom templates.
|
||||
if !o.HasTemplate() {
|
||||
return []x509util.Option{
|
||||
|
|
|
@ -42,7 +42,7 @@ func TestProvisionerOptions_HasTemplate(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
o := &ProvisionerOptions{
|
||||
o := &Options{
|
||||
Template: tt.fields.Template,
|
||||
TemplateFile: tt.fields.TemplateFile,
|
||||
TemplateData: tt.fields.TemplateData,
|
||||
|
@ -65,7 +65,7 @@ func TestTemplateOptions(t *testing.T) {
|
|||
},
|
||||
}
|
||||
type args struct {
|
||||
o *ProvisionerOptions
|
||||
o *Options
|
||||
data x509util.TemplateData
|
||||
}
|
||||
tests := []struct {
|
||||
|
@ -81,14 +81,14 @@ func TestTemplateOptions(t *testing.T) {
|
|||
"keyUsage": ["digitalSignature"],
|
||||
"extKeyUsage": ["serverAuth", "clientAuth"]
|
||||
}`)}, false},
|
||||
{"okCustomTemplate", args{&ProvisionerOptions{Template: x509util.DefaultIIDLeafTemplate}, data}, x509util.Options{
|
||||
{"okCustomTemplate", args{&Options{Template: x509util.DefaultIIDLeafTemplate}, data}, x509util.Options{
|
||||
CertBuffer: bytes.NewBufferString(`{
|
||||
"subject": {"commonName":"foo"},
|
||||
"sans": [{"type":"dns","value":"foo.com"}],
|
||||
"keyUsage": ["digitalSignature"],
|
||||
"extKeyUsage": ["serverAuth", "clientAuth"]
|
||||
}`)}, false},
|
||||
{"fail", args{&ProvisionerOptions{TemplateData: []byte(`{"badJSON`)}, data}, x509util.Options{}, true},
|
||||
{"fail", args{&Options{TemplateData: []byte(`{"badJSON`)}, data}, x509util.Options{}, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
@ -99,7 +99,7 @@ func TestTemplateOptions(t *testing.T) {
|
|||
}
|
||||
var opts x509util.Options
|
||||
if cof != nil {
|
||||
for _, fn := range cof.Options(Options{}) {
|
||||
for _, fn := range cof.Options(SignOptions{}) {
|
||||
if err := fn(csr, &opts); err != nil {
|
||||
t.Errorf("x509util.Options() error = %v", err)
|
||||
return
|
||||
|
@ -125,10 +125,10 @@ func TestCustomTemplateOptions(t *testing.T) {
|
|||
},
|
||||
}
|
||||
type args struct {
|
||||
o *ProvisionerOptions
|
||||
o *Options
|
||||
data x509util.TemplateData
|
||||
defaultTemplate string
|
||||
userOptions Options
|
||||
userOptions SignOptions
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -136,48 +136,48 @@ func TestCustomTemplateOptions(t *testing.T) {
|
|||
want x509util.Options
|
||||
wantErr bool
|
||||
}{
|
||||
{"ok", args{nil, data, x509util.DefaultLeafTemplate, Options{}}, x509util.Options{
|
||||
{"ok", args{nil, data, x509util.DefaultLeafTemplate, SignOptions{}}, x509util.Options{
|
||||
CertBuffer: bytes.NewBufferString(`{
|
||||
"subject": {"commonName":"foobar"},
|
||||
"sans": [{"type":"dns","value":"foo.com"}],
|
||||
"keyUsage": ["digitalSignature"],
|
||||
"extKeyUsage": ["serverAuth", "clientAuth"]
|
||||
}`)}, false},
|
||||
{"okIID", args{nil, data, x509util.DefaultIIDLeafTemplate, Options{}}, x509util.Options{
|
||||
{"okIID", args{nil, data, x509util.DefaultIIDLeafTemplate, SignOptions{}}, x509util.Options{
|
||||
CertBuffer: bytes.NewBufferString(`{
|
||||
"subject": {"commonName":"foo"},
|
||||
"sans": [{"type":"dns","value":"foo.com"}],
|
||||
"keyUsage": ["digitalSignature"],
|
||||
"extKeyUsage": ["serverAuth", "clientAuth"]
|
||||
}`)}, false},
|
||||
{"okNoData", args{&ProvisionerOptions{}, nil, x509util.DefaultLeafTemplate, Options{}}, x509util.Options{
|
||||
{"okNoData", args{&Options{}, nil, x509util.DefaultLeafTemplate, SignOptions{}}, x509util.Options{
|
||||
CertBuffer: bytes.NewBufferString(`{
|
||||
"subject": null,
|
||||
"sans": null,
|
||||
"keyUsage": ["digitalSignature"],
|
||||
"extKeyUsage": ["serverAuth", "clientAuth"]
|
||||
}`)}, false},
|
||||
{"okTemplateData", args{&ProvisionerOptions{TemplateData: []byte(`{"foo":"bar"}`)}, data, x509util.DefaultLeafTemplate, Options{}}, x509util.Options{
|
||||
{"okTemplateData", args{&Options{TemplateData: []byte(`{"foo":"bar"}`)}, data, x509util.DefaultLeafTemplate, SignOptions{}}, x509util.Options{
|
||||
CertBuffer: bytes.NewBufferString(`{
|
||||
"subject": {"commonName":"foobar"},
|
||||
"sans": [{"type":"dns","value":"foo.com"}],
|
||||
"keyUsage": ["digitalSignature"],
|
||||
"extKeyUsage": ["serverAuth", "clientAuth"]
|
||||
}`)}, false},
|
||||
{"okTemplate", args{&ProvisionerOptions{Template: "{{ toJson .Insecure.CR }}"}, data, x509util.DefaultLeafTemplate, Options{}}, x509util.Options{
|
||||
{"okTemplate", args{&Options{Template: "{{ toJson .Insecure.CR }}"}, data, x509util.DefaultLeafTemplate, SignOptions{}}, x509util.Options{
|
||||
CertBuffer: bytes.NewBufferString(csrCertificate)}, false},
|
||||
{"okFile", args{&ProvisionerOptions{TemplateFile: "./testdata/templates/cr.tpl"}, data, x509util.DefaultLeafTemplate, Options{}}, x509util.Options{
|
||||
{"okFile", args{&Options{TemplateFile: "./testdata/templates/cr.tpl"}, data, x509util.DefaultLeafTemplate, SignOptions{}}, x509util.Options{
|
||||
CertBuffer: bytes.NewBufferString(csrCertificate)}, false},
|
||||
{"okBase64", args{&ProvisionerOptions{Template: "e3sgdG9Kc29uIC5JbnNlY3VyZS5DUiB9fQ=="}, data, x509util.DefaultLeafTemplate, Options{}}, x509util.Options{
|
||||
{"okBase64", args{&Options{Template: "e3sgdG9Kc29uIC5JbnNlY3VyZS5DUiB9fQ=="}, data, x509util.DefaultLeafTemplate, SignOptions{}}, x509util.Options{
|
||||
CertBuffer: bytes.NewBufferString(csrCertificate)}, false},
|
||||
{"okUserOptions", args{&ProvisionerOptions{Template: `{"foo": "{{.Insecure.User.foo}}"}`}, data, x509util.DefaultLeafTemplate, Options{TemplateData: []byte(`{"foo":"bar"}`)}}, x509util.Options{
|
||||
{"okUserOptions", args{&Options{Template: `{"foo": "{{.Insecure.User.foo}}"}`}, data, x509util.DefaultLeafTemplate, SignOptions{TemplateData: []byte(`{"foo":"bar"}`)}}, x509util.Options{
|
||||
CertBuffer: bytes.NewBufferString(`{"foo": "bar"}`),
|
||||
}, false},
|
||||
{"okBadUserOptions", args{&ProvisionerOptions{Template: `{"foo": "{{.Insecure.User.foo}}"}`}, data, x509util.DefaultLeafTemplate, Options{TemplateData: []byte(`{"badJSON"}`)}}, x509util.Options{
|
||||
{"okBadUserOptions", args{&Options{Template: `{"foo": "{{.Insecure.User.foo}}"}`}, data, x509util.DefaultLeafTemplate, SignOptions{TemplateData: []byte(`{"badJSON"}`)}}, x509util.Options{
|
||||
CertBuffer: bytes.NewBufferString(`{"foo": "<no value>"}`),
|
||||
}, false},
|
||||
{"fail", args{&ProvisionerOptions{TemplateData: []byte(`{"badJSON`)}, data, x509util.DefaultLeafTemplate, Options{}}, x509util.Options{}, true},
|
||||
{"failTemplateData", args{&ProvisionerOptions{TemplateData: []byte(`{"badJSON}`)}, data, x509util.DefaultLeafTemplate, Options{}}, x509util.Options{}, true},
|
||||
{"fail", args{&Options{TemplateData: []byte(`{"badJSON`)}, data, x509util.DefaultLeafTemplate, SignOptions{}}, x509util.Options{}, true},
|
||||
{"failTemplateData", args{&Options{TemplateData: []byte(`{"badJSON}`)}, data, x509util.DefaultLeafTemplate, SignOptions{}}, x509util.Options{}, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
@ -20,9 +20,9 @@ import (
|
|||
// DefaultCertValidity is the default validity for a certificate if none is specified.
|
||||
const DefaultCertValidity = 24 * time.Hour
|
||||
|
||||
// Options contains the options that can be passed to the Sign method. Backdate
|
||||
// SignOptions contains the options that can be passed to the Sign method. Backdate
|
||||
// is automatically filled and can only be configured in the CA.
|
||||
type Options struct {
|
||||
type SignOptions struct {
|
||||
NotAfter TimeDuration `json:"notAfter"`
|
||||
NotBefore TimeDuration `json:"notBefore"`
|
||||
TemplateData json.RawMessage `json:"templateData"`
|
||||
|
@ -35,7 +35,7 @@ type SignOption interface{}
|
|||
|
||||
// CertificateValidator is an interface used to validate a given X.509 certificate.
|
||||
type CertificateValidator interface {
|
||||
Valid(cert *x509.Certificate, opts Options) error
|
||||
Valid(cert *x509.Certificate, opts SignOptions) error
|
||||
}
|
||||
|
||||
// CertificateRequestValidator is an interface used to validate a given X.509 certificate request.
|
||||
|
@ -47,7 +47,7 @@ type CertificateRequestValidator interface {
|
|||
// Types implementing this interface will be validated with a
|
||||
// CertificateValidator.
|
||||
type CertificateModifier interface {
|
||||
Modify(cert *x509.Certificate, opts Options) error
|
||||
Modify(cert *x509.Certificate, opts SignOptions) error
|
||||
}
|
||||
|
||||
// CertificateEnforcer is an interface used to modify a given X.509 certificate.
|
||||
|
@ -59,10 +59,10 @@ type CertificateEnforcer interface {
|
|||
|
||||
// CertificateModifierFunc allows to create simple certificate modifiers just
|
||||
// with a function.
|
||||
type CertificateModifierFunc func(cert *x509.Certificate, opts Options) error
|
||||
type CertificateModifierFunc func(cert *x509.Certificate, opts SignOptions) error
|
||||
|
||||
// Modify implements CertificateModifier and just calls the defined function.
|
||||
func (fn CertificateModifierFunc) Modify(cert *x509.Certificate, opts Options) error {
|
||||
func (fn CertificateModifierFunc) Modify(cert *x509.Certificate, opts SignOptions) error {
|
||||
return fn(cert, opts)
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,7 @@ func (eee ExtraExtsEnforcer) Enforce(cert *x509.Certificate) error {
|
|||
// duration.
|
||||
type profileDefaultDuration time.Duration
|
||||
|
||||
func (v profileDefaultDuration) Modify(cert *x509.Certificate, so Options) error {
|
||||
func (v profileDefaultDuration) Modify(cert *x509.Certificate, so SignOptions) error {
|
||||
var backdate time.Duration
|
||||
notBefore := so.NotBefore.Time()
|
||||
if notBefore.IsZero() {
|
||||
|
@ -301,7 +301,7 @@ type profileLimitDuration struct {
|
|||
|
||||
// Option returns an x509util option that limits the validity period of a
|
||||
// certificate to one that is superficially imposed.
|
||||
func (v profileLimitDuration) Modify(cert *x509.Certificate, so Options) error {
|
||||
func (v profileLimitDuration) Modify(cert *x509.Certificate, so SignOptions) error {
|
||||
var backdate time.Duration
|
||||
notBefore := so.NotBefore.Time()
|
||||
if notBefore.IsZero() {
|
||||
|
@ -347,7 +347,7 @@ func newValidityValidator(min, max time.Duration) *validityValidator {
|
|||
|
||||
// Valid validates the certificate validity settings (notBefore/notAfter) and
|
||||
// and total duration.
|
||||
func (v *validityValidator) Valid(cert *x509.Certificate, o Options) error {
|
||||
func (v *validityValidator) Valid(cert *x509.Certificate, o SignOptions) error {
|
||||
var (
|
||||
na = cert.NotAfter.Truncate(time.Second)
|
||||
nb = cert.NotBefore.Truncate(time.Second)
|
||||
|
@ -397,7 +397,7 @@ func newForceCNOption(forceCN bool) *forceCNOption {
|
|||
return &forceCNOption{forceCN}
|
||||
}
|
||||
|
||||
func (o *forceCNOption) Modify(cert *x509.Certificate, _ Options) error {
|
||||
func (o *forceCNOption) Modify(cert *x509.Certificate, _ SignOptions) error {
|
||||
if !o.ForceCN {
|
||||
// Forcing CN is disabled, do nothing to certificate
|
||||
return nil
|
||||
|
@ -430,7 +430,7 @@ func newProvisionerExtensionOption(typ Type, name, credentialID string, keyValue
|
|||
}
|
||||
}
|
||||
|
||||
func (o *provisionerExtensionOption) Modify(cert *x509.Certificate, _ Options) error {
|
||||
func (o *provisionerExtensionOption) Modify(cert *x509.Certificate, _ SignOptions) error {
|
||||
ext, err := createProvisionerExtension(o.Type, o.Name, o.CredentialID, o.KeyValuePairs...)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -399,7 +399,7 @@ func Test_ExtraExtsEnforcer_Enforce(t *testing.T) {
|
|||
func Test_validityValidator_Valid(t *testing.T) {
|
||||
type test struct {
|
||||
cert *x509.Certificate
|
||||
opts Options
|
||||
opts SignOptions
|
||||
vv *validityValidator
|
||||
err error
|
||||
}
|
||||
|
@ -408,7 +408,7 @@ func Test_validityValidator_Valid(t *testing.T) {
|
|||
return test{
|
||||
vv: &validityValidator{5 * time.Minute, 24 * time.Hour},
|
||||
cert: &x509.Certificate{NotAfter: time.Now().Add(-5 * time.Minute)},
|
||||
opts: Options{},
|
||||
opts: SignOptions{},
|
||||
err: errors.New("notAfter cannot be in the past"),
|
||||
}
|
||||
},
|
||||
|
@ -417,7 +417,7 @@ func Test_validityValidator_Valid(t *testing.T) {
|
|||
vv: &validityValidator{5 * time.Minute, 24 * time.Hour},
|
||||
cert: &x509.Certificate{NotBefore: time.Now().Add(10 * time.Minute),
|
||||
NotAfter: time.Now().Add(5 * time.Minute)},
|
||||
opts: Options{},
|
||||
opts: SignOptions{},
|
||||
err: errors.New("notAfter cannot be before notBefore"),
|
||||
}
|
||||
},
|
||||
|
@ -427,7 +427,7 @@ func Test_validityValidator_Valid(t *testing.T) {
|
|||
vv: &validityValidator{5 * time.Minute, 24 * time.Hour},
|
||||
cert: &x509.Certificate{NotBefore: n,
|
||||
NotAfter: n.Add(3 * time.Minute)},
|
||||
opts: Options{},
|
||||
opts: SignOptions{},
|
||||
err: errors.New("is less than the authorized minimum certificate duration of "),
|
||||
}
|
||||
},
|
||||
|
@ -437,7 +437,7 @@ func Test_validityValidator_Valid(t *testing.T) {
|
|||
vv: &validityValidator{5 * time.Minute, 24 * time.Hour},
|
||||
cert: &x509.Certificate{NotBefore: n,
|
||||
NotAfter: n.Add(5 * time.Minute)},
|
||||
opts: Options{},
|
||||
opts: SignOptions{},
|
||||
}
|
||||
},
|
||||
"fail/duration-too-great": func() test {
|
||||
|
@ -464,7 +464,7 @@ func Test_validityValidator_Valid(t *testing.T) {
|
|||
return test{
|
||||
vv: &validityValidator{5 * time.Minute, 24 * time.Hour},
|
||||
cert: cert,
|
||||
opts: Options{Backdate: time.Second},
|
||||
opts: SignOptions{Backdate: time.Second},
|
||||
}
|
||||
},
|
||||
"ok/duration-exact-max-with-backdate": func() test {
|
||||
|
@ -475,7 +475,7 @@ func Test_validityValidator_Valid(t *testing.T) {
|
|||
return test{
|
||||
vv: &validityValidator{5 * time.Minute, 24 * time.Hour},
|
||||
cert: cert,
|
||||
opts: Options{Backdate: backdate},
|
||||
opts: SignOptions{Backdate: backdate},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -496,7 +496,7 @@ func Test_validityValidator_Valid(t *testing.T) {
|
|||
|
||||
func Test_forceCN_Option(t *testing.T) {
|
||||
type test struct {
|
||||
so Options
|
||||
so SignOptions
|
||||
fcn forceCNOption
|
||||
cert *x509.Certificate
|
||||
valid func(*x509.Certificate)
|
||||
|
@ -507,7 +507,7 @@ func Test_forceCN_Option(t *testing.T) {
|
|||
"ok/CN-not-forced": func() test {
|
||||
return test{
|
||||
fcn: forceCNOption{false},
|
||||
so: Options{},
|
||||
so: SignOptions{},
|
||||
cert: &x509.Certificate{
|
||||
Subject: pkix.Name{},
|
||||
DNSNames: []string{"acme.example.com", "step.example.com"},
|
||||
|
@ -520,7 +520,7 @@ func Test_forceCN_Option(t *testing.T) {
|
|||
"ok/CN-forced-and-set": func() test {
|
||||
return test{
|
||||
fcn: forceCNOption{true},
|
||||
so: Options{},
|
||||
so: SignOptions{},
|
||||
cert: &x509.Certificate{
|
||||
Subject: pkix.Name{
|
||||
CommonName: "Some Common Name",
|
||||
|
@ -535,7 +535,7 @@ func Test_forceCN_Option(t *testing.T) {
|
|||
"ok/CN-forced-and-not-set": func() test {
|
||||
return test{
|
||||
fcn: forceCNOption{true},
|
||||
so: Options{},
|
||||
so: SignOptions{},
|
||||
cert: &x509.Certificate{
|
||||
Subject: pkix.Name{},
|
||||
DNSNames: []string{"acme.example.com", "step.example.com"},
|
||||
|
@ -548,7 +548,7 @@ func Test_forceCN_Option(t *testing.T) {
|
|||
"fail/CN-forced-and-empty-DNSNames": func() test {
|
||||
return test{
|
||||
fcn: forceCNOption{true},
|
||||
so: Options{},
|
||||
so: SignOptions{},
|
||||
cert: &x509.Certificate{
|
||||
Subject: pkix.Name{},
|
||||
DNSNames: []string{},
|
||||
|
@ -576,7 +576,7 @@ func Test_forceCN_Option(t *testing.T) {
|
|||
|
||||
func Test_profileDefaultDuration_Option(t *testing.T) {
|
||||
type test struct {
|
||||
so Options
|
||||
so SignOptions
|
||||
pdd profileDefaultDuration
|
||||
cert *x509.Certificate
|
||||
valid func(*x509.Certificate)
|
||||
|
@ -585,7 +585,7 @@ func Test_profileDefaultDuration_Option(t *testing.T) {
|
|||
"ok/notBefore-notAfter-duration-empty": func() test {
|
||||
return test{
|
||||
pdd: profileDefaultDuration(0),
|
||||
so: Options{},
|
||||
so: SignOptions{},
|
||||
cert: new(x509.Certificate),
|
||||
valid: func(cert *x509.Certificate) {
|
||||
n := now()
|
||||
|
@ -601,7 +601,7 @@ func Test_profileDefaultDuration_Option(t *testing.T) {
|
|||
nb := time.Now().Add(5 * time.Minute).UTC()
|
||||
return test{
|
||||
pdd: profileDefaultDuration(0),
|
||||
so: Options{NotBefore: NewTimeDuration(nb)},
|
||||
so: SignOptions{NotBefore: NewTimeDuration(nb)},
|
||||
cert: new(x509.Certificate),
|
||||
valid: func(cert *x509.Certificate) {
|
||||
assert.Equals(t, cert.NotBefore, nb)
|
||||
|
@ -613,7 +613,7 @@ func Test_profileDefaultDuration_Option(t *testing.T) {
|
|||
d := 4 * time.Hour
|
||||
return test{
|
||||
pdd: profileDefaultDuration(d),
|
||||
so: Options{Backdate: time.Second},
|
||||
so: SignOptions{Backdate: time.Second},
|
||||
cert: new(x509.Certificate),
|
||||
valid: func(cert *x509.Certificate) {
|
||||
n := now()
|
||||
|
@ -629,7 +629,7 @@ func Test_profileDefaultDuration_Option(t *testing.T) {
|
|||
na := now().Add(10 * time.Minute).UTC()
|
||||
return test{
|
||||
pdd: profileDefaultDuration(0),
|
||||
so: Options{NotAfter: NewTimeDuration(na)},
|
||||
so: SignOptions{NotAfter: NewTimeDuration(na)},
|
||||
cert: new(x509.Certificate),
|
||||
valid: func(cert *x509.Certificate) {
|
||||
n := now()
|
||||
|
@ -646,7 +646,7 @@ func Test_profileDefaultDuration_Option(t *testing.T) {
|
|||
d := 4 * time.Hour
|
||||
return test{
|
||||
pdd: profileDefaultDuration(d),
|
||||
so: Options{NotBefore: NewTimeDuration(nb), NotAfter: NewTimeDuration(na)},
|
||||
so: SignOptions{NotBefore: NewTimeDuration(nb), NotAfter: NewTimeDuration(na)},
|
||||
cert: new(x509.Certificate),
|
||||
valid: func(cert *x509.Certificate) {
|
||||
assert.Equals(t, cert.NotBefore, nb)
|
||||
|
@ -698,7 +698,7 @@ func Test_newProvisionerExtension_Option(t *testing.T) {
|
|||
for name, run := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
tt := run()
|
||||
assert.FatalError(t, newProvisionerExtensionOption(TypeJWK, "foo", "bar", "baz", "zap").Modify(tt.cert, Options{}))
|
||||
assert.FatalError(t, newProvisionerExtensionOption(TypeJWK, "foo", "bar", "baz", "zap").Modify(tt.cert, SignOptions{}))
|
||||
tt.valid(tt.cert)
|
||||
})
|
||||
}
|
||||
|
@ -710,7 +710,7 @@ func Test_profileLimitDuration_Option(t *testing.T) {
|
|||
|
||||
type test struct {
|
||||
pld profileLimitDuration
|
||||
so Options
|
||||
so SignOptions
|
||||
cert *x509.Certificate
|
||||
valid func(*x509.Certificate)
|
||||
err error
|
||||
|
@ -721,7 +721,7 @@ func Test_profileLimitDuration_Option(t *testing.T) {
|
|||
assert.FatalError(t, err)
|
||||
return test{
|
||||
pld: profileLimitDuration{def: 4 * time.Hour, notBefore: n.Add(8 * time.Hour)},
|
||||
so: Options{NotBefore: d},
|
||||
so: SignOptions{NotBefore: d},
|
||||
cert: new(x509.Certificate),
|
||||
err: errors.New("requested certificate notBefore ("),
|
||||
}
|
||||
|
@ -731,7 +731,7 @@ func Test_profileLimitDuration_Option(t *testing.T) {
|
|||
assert.FatalError(t, err)
|
||||
return test{
|
||||
pld: profileLimitDuration{def: 4 * time.Hour, notAfter: n.Add(6 * time.Hour)},
|
||||
so: Options{NotBefore: NewTimeDuration(n.Add(3 * time.Hour)), NotAfter: d},
|
||||
so: SignOptions{NotBefore: NewTimeDuration(n.Add(3 * time.Hour)), NotAfter: d},
|
||||
cert: new(x509.Certificate),
|
||||
err: errors.New("requested certificate notAfter ("),
|
||||
}
|
||||
|
@ -741,7 +741,7 @@ func Test_profileLimitDuration_Option(t *testing.T) {
|
|||
assert.FatalError(t, err)
|
||||
return test{
|
||||
pld: profileLimitDuration{def: 4 * time.Hour, notAfter: n.Add(6 * time.Hour)},
|
||||
so: Options{NotBefore: NewTimeDuration(n.Add(3 * time.Hour)), NotAfter: d, Backdate: 1 * time.Minute},
|
||||
so: SignOptions{NotBefore: NewTimeDuration(n.Add(3 * time.Hour)), NotAfter: d, Backdate: 1 * time.Minute},
|
||||
cert: new(x509.Certificate),
|
||||
valid: func(cert *x509.Certificate) {
|
||||
assert.Equals(t, cert.NotBefore, n.Add(3*time.Hour))
|
||||
|
@ -752,7 +752,7 @@ func Test_profileLimitDuration_Option(t *testing.T) {
|
|||
"ok/valid-notAfter-nil-limit-over-default": func() test {
|
||||
return test{
|
||||
pld: profileLimitDuration{def: 1 * time.Hour, notAfter: n.Add(6 * time.Hour)},
|
||||
so: Options{NotBefore: NewTimeDuration(n.Add(3 * time.Hour)), Backdate: 1 * time.Minute},
|
||||
so: SignOptions{NotBefore: NewTimeDuration(n.Add(3 * time.Hour)), Backdate: 1 * time.Minute},
|
||||
cert: new(x509.Certificate),
|
||||
valid: func(cert *x509.Certificate) {
|
||||
assert.Equals(t, cert.NotBefore, n.Add(3*time.Hour))
|
||||
|
@ -763,7 +763,7 @@ func Test_profileLimitDuration_Option(t *testing.T) {
|
|||
"ok/valid-notAfter-nil-limit-under-default": func() test {
|
||||
return test{
|
||||
pld: profileLimitDuration{def: 4 * time.Hour, notAfter: n.Add(6 * time.Hour)},
|
||||
so: Options{NotBefore: NewTimeDuration(n.Add(3 * time.Hour)), Backdate: 1 * time.Minute},
|
||||
so: SignOptions{NotBefore: NewTimeDuration(n.Add(3 * time.Hour)), Backdate: 1 * time.Minute},
|
||||
cert: new(x509.Certificate),
|
||||
valid: func(cert *x509.Certificate) {
|
||||
assert.Equals(t, cert.NotBefore, n.Add(3*time.Hour))
|
||||
|
@ -774,7 +774,7 @@ func Test_profileLimitDuration_Option(t *testing.T) {
|
|||
"ok/over-limit-with-backdate": func() test {
|
||||
return test{
|
||||
pld: profileLimitDuration{def: 24 * time.Hour, notAfter: n.Add(6 * time.Hour)},
|
||||
so: Options{Backdate: 1 * time.Minute},
|
||||
so: SignOptions{Backdate: 1 * time.Minute},
|
||||
cert: new(x509.Certificate),
|
||||
valid: func(cert *x509.Certificate) {
|
||||
assert.Equals(t, cert.NotBefore, n.Add(-time.Minute))
|
||||
|
@ -785,7 +785,7 @@ func Test_profileLimitDuration_Option(t *testing.T) {
|
|||
"ok/under-limit-with-backdate": func() test {
|
||||
return test{
|
||||
pld: profileLimitDuration{def: 24 * time.Hour, notAfter: n.Add(30 * time.Hour)},
|
||||
so: Options{Backdate: 1 * time.Minute},
|
||||
so: SignOptions{Backdate: 1 * time.Minute},
|
||||
cert: new(x509.Certificate),
|
||||
valid: func(cert *x509.Certificate) {
|
||||
assert.Equals(t, cert.NotBefore, n.Add(-time.Minute))
|
||||
|
|
|
@ -30,20 +30,20 @@ type SSHCertModifier interface {
|
|||
// to modify the SSH certificate.
|
||||
type SSHCertOptionModifier interface {
|
||||
SignOption
|
||||
Option(o SSHOptions) SSHCertModifier
|
||||
Option(o SignSSHOptions) SSHCertModifier
|
||||
}
|
||||
|
||||
// SSHCertValidator is the interface used to validate an SSH certificate.
|
||||
type SSHCertValidator interface {
|
||||
SignOption
|
||||
Valid(cert *ssh.Certificate, opts SSHOptions) error
|
||||
Valid(cert *ssh.Certificate, opts SignSSHOptions) error
|
||||
}
|
||||
|
||||
// SSHCertOptionsValidator is the interface used to validate the custom
|
||||
// options used to modify the SSH certificate.
|
||||
type SSHCertOptionsValidator interface {
|
||||
SignOption
|
||||
Valid(got SSHOptions) error
|
||||
Valid(got SignSSHOptions) error
|
||||
}
|
||||
|
||||
// sshModifierFunc is an adapter to allow the use of ordinary functions as SSH
|
||||
|
@ -54,8 +54,8 @@ func (f sshModifierFunc) Modify(cert *ssh.Certificate) error {
|
|||
return f(cert)
|
||||
}
|
||||
|
||||
// SSHOptions contains the options that can be passed to the SignSSH method.
|
||||
type SSHOptions struct {
|
||||
// SignSSHOptions contains the options that can be passed to the SignSSH method.
|
||||
type SignSSHOptions struct {
|
||||
CertType string `json:"certType"`
|
||||
KeyID string `json:"keyID"`
|
||||
Principals []string `json:"principals"`
|
||||
|
@ -65,12 +65,12 @@ type SSHOptions struct {
|
|||
}
|
||||
|
||||
// Type returns the uint32 representation of the CertType.
|
||||
func (o SSHOptions) Type() uint32 {
|
||||
func (o SignSSHOptions) Type() uint32 {
|
||||
return sshCertTypeUInt32(o.CertType)
|
||||
}
|
||||
|
||||
// Modify implements SSHCertModifier and sets the SSHOption in the ssh.Certificate.
|
||||
func (o SSHOptions) Modify(cert *ssh.Certificate) error {
|
||||
func (o SignSSHOptions) Modify(cert *ssh.Certificate) error {
|
||||
switch o.CertType {
|
||||
case "": // ignore
|
||||
case SSHUserCert:
|
||||
|
@ -100,7 +100,7 @@ func (o SSHOptions) Modify(cert *ssh.Certificate) error {
|
|||
|
||||
// match compares two SSHOptions and return an error if they don't match. It
|
||||
// ignores zero values.
|
||||
func (o SSHOptions) match(got SSHOptions) error {
|
||||
func (o SignSSHOptions) match(got SignSSHOptions) error {
|
||||
if o.CertType != "" && got.CertType != "" && o.CertType != got.CertType {
|
||||
return errors.Errorf("ssh certificate type does not match - got %v, want %v", got.CertType, o.CertType)
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ func (m sshCertValidBeforeModifier) Modify(cert *ssh.Certificate) error {
|
|||
|
||||
// sshCertDefaultsModifier implements a SSHCertModifier that
|
||||
// modifies the certificate with the given options if they are not set.
|
||||
type sshCertDefaultsModifier SSHOptions
|
||||
type sshCertDefaultsModifier SignSSHOptions
|
||||
|
||||
// Modify implements the SSHCertModifier interface.
|
||||
func (m sshCertDefaultsModifier) Modify(cert *ssh.Certificate) error {
|
||||
|
@ -215,7 +215,7 @@ type sshDefaultDuration struct {
|
|||
*Claimer
|
||||
}
|
||||
|
||||
func (m *sshDefaultDuration) Option(o SSHOptions) SSHCertModifier {
|
||||
func (m *sshDefaultDuration) Option(o SignSSHOptions) SSHCertModifier {
|
||||
return sshModifierFunc(func(cert *ssh.Certificate) error {
|
||||
d, err := m.DefaultSSHCertDuration(cert.CertType)
|
||||
if err != nil {
|
||||
|
@ -248,7 +248,7 @@ type sshLimitDuration struct {
|
|||
NotAfter time.Time
|
||||
}
|
||||
|
||||
func (m *sshLimitDuration) Option(o SSHOptions) SSHCertModifier {
|
||||
func (m *sshLimitDuration) Option(o SignSSHOptions) SSHCertModifier {
|
||||
if m.NotAfter.IsZero() {
|
||||
defaultDuration := &sshDefaultDuration{m.Claimer}
|
||||
return defaultDuration.Option(o)
|
||||
|
@ -297,12 +297,12 @@ func (m *sshLimitDuration) Option(o SSHOptions) SSHCertModifier {
|
|||
|
||||
// sshCertOptionsValidator validates the user SSHOptions with the ones
|
||||
// usually present in the token.
|
||||
type sshCertOptionsValidator SSHOptions
|
||||
type sshCertOptionsValidator SignSSHOptions
|
||||
|
||||
// Valid implements SSHCertOptionsValidator and returns nil if both
|
||||
// SSHOptions match.
|
||||
func (v sshCertOptionsValidator) Valid(got SSHOptions) error {
|
||||
want := SSHOptions(v)
|
||||
func (v sshCertOptionsValidator) Valid(got SignSSHOptions) error {
|
||||
want := SignSSHOptions(v)
|
||||
return want.match(got)
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ type sshCertValidityValidator struct {
|
|||
*Claimer
|
||||
}
|
||||
|
||||
func (v *sshCertValidityValidator) Valid(cert *ssh.Certificate, opts SSHOptions) error {
|
||||
func (v *sshCertValidityValidator) Valid(cert *ssh.Certificate, opts SignSSHOptions) error {
|
||||
switch {
|
||||
case cert.ValidAfter == 0:
|
||||
return errors.New("ssh certificate validAfter cannot be 0")
|
||||
|
@ -355,7 +355,7 @@ func (v *sshCertValidityValidator) Valid(cert *ssh.Certificate, opts SSHOptions)
|
|||
type sshCertDefaultValidator struct{}
|
||||
|
||||
// Valid returns an error if the given certificate does not contain the necessary fields.
|
||||
func (v *sshCertDefaultValidator) Valid(cert *ssh.Certificate, o SSHOptions) error {
|
||||
func (v *sshCertDefaultValidator) Valid(cert *ssh.Certificate, o SignSSHOptions) error {
|
||||
switch {
|
||||
case len(cert.Nonce) == 0:
|
||||
return errors.New("ssh certificate nonce cannot be empty")
|
||||
|
@ -390,7 +390,7 @@ func (v *sshCertDefaultValidator) Valid(cert *ssh.Certificate, o SSHOptions) err
|
|||
type sshDefaultPublicKeyValidator struct{}
|
||||
|
||||
// Valid checks that certificate request common name matches the one configured.
|
||||
func (v sshDefaultPublicKeyValidator) Valid(cert *ssh.Certificate, o SSHOptions) error {
|
||||
func (v sshDefaultPublicKeyValidator) Valid(cert *ssh.Certificate, o SignSSHOptions) error {
|
||||
if cert.Key == nil {
|
||||
return errors.New("ssh certificate key cannot be nil")
|
||||
}
|
||||
|
@ -420,7 +420,7 @@ func (v sshDefaultPublicKeyValidator) Valid(cert *ssh.Certificate, o SSHOptions)
|
|||
type sshCertKeyIDValidator string
|
||||
|
||||
// Valid returns an error if the given certificate does not contain the necessary fields.
|
||||
func (v sshCertKeyIDValidator) Valid(cert *ssh.Certificate, o SSHOptions) error {
|
||||
func (v sshCertKeyIDValidator) Valid(cert *ssh.Certificate, o SignSSHOptions) error {
|
||||
if string(v) != cert.KeyId {
|
||||
return errors.Errorf("invalid ssh certificate KeyId; want %s, but got %s", string(v), cert.KeyId)
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ func TestSSHOptions_Type(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
o := SSHOptions{
|
||||
o := SignSSHOptions{
|
||||
CertType: tt.fields.CertType,
|
||||
}
|
||||
if got := o.Type(); got != tt.want {
|
||||
|
@ -40,7 +40,7 @@ func TestSSHOptions_Type(t *testing.T) {
|
|||
|
||||
func TestSSHOptions_Modify(t *testing.T) {
|
||||
type test struct {
|
||||
so *SSHOptions
|
||||
so *SignSSHOptions
|
||||
cert *ssh.Certificate
|
||||
valid func(*ssh.Certificate)
|
||||
err error
|
||||
|
@ -48,21 +48,21 @@ func TestSSHOptions_Modify(t *testing.T) {
|
|||
tests := map[string](func() test){
|
||||
"fail/unexpected-cert-type": func() test {
|
||||
return test{
|
||||
so: &SSHOptions{CertType: "foo"},
|
||||
so: &SignSSHOptions{CertType: "foo"},
|
||||
cert: new(ssh.Certificate),
|
||||
err: errors.Errorf("ssh certificate has an unknown type - foo"),
|
||||
}
|
||||
},
|
||||
"fail/validAfter-greater-validBefore": func() test {
|
||||
return test{
|
||||
so: &SSHOptions{CertType: "user"},
|
||||
so: &SignSSHOptions{CertType: "user"},
|
||||
cert: &ssh.Certificate{ValidAfter: uint64(15), ValidBefore: uint64(10)},
|
||||
err: errors.Errorf("ssh certificate valid after cannot be greater than valid before"),
|
||||
}
|
||||
},
|
||||
"ok/user-cert": func() test {
|
||||
return test{
|
||||
so: &SSHOptions{CertType: "user"},
|
||||
so: &SignSSHOptions{CertType: "user"},
|
||||
cert: new(ssh.Certificate),
|
||||
valid: func(cert *ssh.Certificate) {
|
||||
assert.Equals(t, cert.CertType, uint32(ssh.UserCert))
|
||||
|
@ -71,7 +71,7 @@ func TestSSHOptions_Modify(t *testing.T) {
|
|||
},
|
||||
"ok/host-cert": func() test {
|
||||
return test{
|
||||
so: &SSHOptions{CertType: "host"},
|
||||
so: &SignSSHOptions{CertType: "host"},
|
||||
cert: new(ssh.Certificate),
|
||||
valid: func(cert *ssh.Certificate) {
|
||||
assert.Equals(t, cert.CertType, uint32(ssh.HostCert))
|
||||
|
@ -81,7 +81,7 @@ func TestSSHOptions_Modify(t *testing.T) {
|
|||
"ok": func() test {
|
||||
va := time.Now().Add(5 * time.Minute)
|
||||
vb := time.Now().Add(1 * time.Hour)
|
||||
so := &SSHOptions{CertType: "host", KeyID: "foo", Principals: []string{"foo", "bar"},
|
||||
so := &SignSSHOptions{CertType: "host", KeyID: "foo", Principals: []string{"foo", "bar"},
|
||||
ValidAfter: NewTimeDuration(va), ValidBefore: NewTimeDuration(vb)}
|
||||
return test{
|
||||
so: so,
|
||||
|
@ -114,43 +114,43 @@ func TestSSHOptions_Modify(t *testing.T) {
|
|||
|
||||
func TestSSHOptions_Match(t *testing.T) {
|
||||
type test struct {
|
||||
so SSHOptions
|
||||
cmp SSHOptions
|
||||
so SignSSHOptions
|
||||
cmp SignSSHOptions
|
||||
err error
|
||||
}
|
||||
tests := map[string](func() test){
|
||||
"fail/cert-type": func() test {
|
||||
return test{
|
||||
so: SSHOptions{CertType: "foo"},
|
||||
cmp: SSHOptions{CertType: "bar"},
|
||||
so: SignSSHOptions{CertType: "foo"},
|
||||
cmp: SignSSHOptions{CertType: "bar"},
|
||||
err: errors.Errorf("ssh certificate type does not match - got bar, want foo"),
|
||||
}
|
||||
},
|
||||
"fail/pricipals": func() test {
|
||||
return test{
|
||||
so: SSHOptions{Principals: []string{"foo"}},
|
||||
cmp: SSHOptions{Principals: []string{"bar"}},
|
||||
so: SignSSHOptions{Principals: []string{"foo"}},
|
||||
cmp: SignSSHOptions{Principals: []string{"bar"}},
|
||||
err: errors.Errorf("ssh certificate principals does not match - got [bar], want [foo]"),
|
||||
}
|
||||
},
|
||||
"fail/validAfter": func() test {
|
||||
return test{
|
||||
so: SSHOptions{ValidAfter: NewTimeDuration(time.Now().Add(1 * time.Minute))},
|
||||
cmp: SSHOptions{ValidAfter: NewTimeDuration(time.Now().Add(5 * time.Minute))},
|
||||
so: SignSSHOptions{ValidAfter: NewTimeDuration(time.Now().Add(1 * time.Minute))},
|
||||
cmp: SignSSHOptions{ValidAfter: NewTimeDuration(time.Now().Add(5 * time.Minute))},
|
||||
err: errors.Errorf("ssh certificate valid after does not match"),
|
||||
}
|
||||
},
|
||||
"fail/validBefore": func() test {
|
||||
return test{
|
||||
so: SSHOptions{ValidBefore: NewTimeDuration(time.Now().Add(1 * time.Minute))},
|
||||
cmp: SSHOptions{ValidBefore: NewTimeDuration(time.Now().Add(5 * time.Minute))},
|
||||
so: SignSSHOptions{ValidBefore: NewTimeDuration(time.Now().Add(1 * time.Minute))},
|
||||
cmp: SignSSHOptions{ValidBefore: NewTimeDuration(time.Now().Add(5 * time.Minute))},
|
||||
err: errors.Errorf("ssh certificate valid before does not match"),
|
||||
}
|
||||
},
|
||||
"ok/original-empty": func() test {
|
||||
return test{
|
||||
so: SSHOptions{},
|
||||
cmp: SSHOptions{
|
||||
so: SignSSHOptions{},
|
||||
cmp: SignSSHOptions{
|
||||
CertType: "foo",
|
||||
Principals: []string{"foo"},
|
||||
ValidAfter: NewTimeDuration(time.Now().Add(1 * time.Minute)),
|
||||
|
@ -160,8 +160,8 @@ func TestSSHOptions_Match(t *testing.T) {
|
|||
},
|
||||
"ok/cmp-empty": func() test {
|
||||
return test{
|
||||
cmp: SSHOptions{},
|
||||
so: SSHOptions{
|
||||
cmp: SignSSHOptions{},
|
||||
so: SignSSHOptions{
|
||||
CertType: "foo",
|
||||
Principals: []string{"foo"},
|
||||
ValidAfter: NewTimeDuration(time.Now().Add(1 * time.Minute)),
|
||||
|
@ -174,13 +174,13 @@ func TestSSHOptions_Match(t *testing.T) {
|
|||
va := NewTimeDuration(n.Add(1 * time.Minute))
|
||||
vb := NewTimeDuration(n.Add(5 * time.Minute))
|
||||
return test{
|
||||
cmp: SSHOptions{
|
||||
cmp: SignSSHOptions{
|
||||
CertType: "foo",
|
||||
Principals: []string{"foo"},
|
||||
ValidAfter: va,
|
||||
ValidBefore: vb,
|
||||
},
|
||||
so: SSHOptions{
|
||||
so: SignSSHOptions{
|
||||
CertType: "foo",
|
||||
Principals: []string{"foo"},
|
||||
ValidAfter: va,
|
||||
|
@ -330,7 +330,7 @@ func Test_sshCertDefaultsModifier_Modify(t *testing.T) {
|
|||
n := time.Now()
|
||||
va := NewTimeDuration(n.Add(1 * time.Minute))
|
||||
vb := NewTimeDuration(n.Add(5 * time.Minute))
|
||||
so := SSHOptions{
|
||||
so := SignSSHOptions{
|
||||
Principals: []string{"foo", "bar"},
|
||||
CertType: "host",
|
||||
ValidAfter: va,
|
||||
|
@ -349,7 +349,7 @@ func Test_sshCertDefaultsModifier_Modify(t *testing.T) {
|
|||
},
|
||||
"ok/no-changes": func() test {
|
||||
n := time.Now()
|
||||
so := SSHOptions{
|
||||
so := SignSSHOptions{
|
||||
Principals: []string{"foo", "bar"},
|
||||
CertType: "host",
|
||||
ValidAfter: NewTimeDuration(n.Add(15 * time.Minute)),
|
||||
|
@ -659,7 +659,7 @@ func Test_sshCertDefaultValidator_Valid(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := v.Valid(tt.cert, SSHOptions{}); err != nil {
|
||||
if err := v.Valid(tt.cert, SignSSHOptions{}); err != nil {
|
||||
if assert.NotNil(t, tt.err) {
|
||||
assert.HasPrefix(t, err.Error(), tt.err.Error())
|
||||
}
|
||||
|
@ -678,31 +678,31 @@ func Test_sshCertValidityValidator(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
cert *ssh.Certificate
|
||||
opts SSHOptions
|
||||
opts SignSSHOptions
|
||||
err error
|
||||
}{
|
||||
{
|
||||
"fail/validAfter-0",
|
||||
&ssh.Certificate{CertType: ssh.UserCert},
|
||||
SSHOptions{},
|
||||
SignSSHOptions{},
|
||||
errors.New("ssh certificate validAfter cannot be 0"),
|
||||
},
|
||||
{
|
||||
"fail/validBefore-in-past",
|
||||
&ssh.Certificate{CertType: ssh.UserCert, ValidAfter: uint64(now().Unix()), ValidBefore: uint64(now().Add(-time.Minute).Unix())},
|
||||
SSHOptions{},
|
||||
SignSSHOptions{},
|
||||
errors.New("ssh certificate validBefore cannot be in the past"),
|
||||
},
|
||||
{
|
||||
"fail/validBefore-before-validAfter",
|
||||
&ssh.Certificate{CertType: ssh.UserCert, ValidAfter: uint64(now().Add(5 * time.Minute).Unix()), ValidBefore: uint64(now().Add(3 * time.Minute).Unix())},
|
||||
SSHOptions{},
|
||||
SignSSHOptions{},
|
||||
errors.New("ssh certificate validBefore cannot be before validAfter"),
|
||||
},
|
||||
{
|
||||
"fail/cert-type-not-set",
|
||||
&ssh.Certificate{ValidAfter: uint64(now().Unix()), ValidBefore: uint64(now().Add(10 * time.Minute).Unix())},
|
||||
SSHOptions{},
|
||||
SignSSHOptions{},
|
||||
errors.New("ssh certificate type has not been set"),
|
||||
},
|
||||
{
|
||||
|
@ -712,7 +712,7 @@ func Test_sshCertValidityValidator(t *testing.T) {
|
|||
ValidAfter: uint64(now().Unix()),
|
||||
ValidBefore: uint64(now().Add(10 * time.Minute).Unix()),
|
||||
},
|
||||
SSHOptions{},
|
||||
SignSSHOptions{},
|
||||
errors.New("unknown ssh certificate type 3"),
|
||||
},
|
||||
{
|
||||
|
@ -722,7 +722,7 @@ func Test_sshCertValidityValidator(t *testing.T) {
|
|||
ValidAfter: uint64(n.Unix()),
|
||||
ValidBefore: uint64(n.Add(4 * time.Minute).Unix()),
|
||||
},
|
||||
SSHOptions{Backdate: time.Second},
|
||||
SignSSHOptions{Backdate: time.Second},
|
||||
errors.New("requested duration of 4m0s is less than minimum accepted duration for selected provisioner of 5m0s"),
|
||||
},
|
||||
{
|
||||
|
@ -732,7 +732,7 @@ func Test_sshCertValidityValidator(t *testing.T) {
|
|||
ValidAfter: uint64(n.Unix()),
|
||||
ValidBefore: uint64(n.Add(5 * time.Minute).Unix()),
|
||||
},
|
||||
SSHOptions{Backdate: time.Second},
|
||||
SignSSHOptions{Backdate: time.Second},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
|
@ -742,7 +742,7 @@ func Test_sshCertValidityValidator(t *testing.T) {
|
|||
ValidAfter: uint64(n.Unix()),
|
||||
ValidBefore: uint64(n.Add(48 * time.Hour).Unix()),
|
||||
},
|
||||
SSHOptions{Backdate: time.Second},
|
||||
SignSSHOptions{Backdate: time.Second},
|
||||
errors.New("requested duration of 48h0m0s is greater than maximum accepted duration for selected provisioner of 24h0m1s"),
|
||||
},
|
||||
{
|
||||
|
@ -752,7 +752,7 @@ func Test_sshCertValidityValidator(t *testing.T) {
|
|||
ValidAfter: uint64(n.Unix()),
|
||||
ValidBefore: uint64(n.Add(24*time.Hour + time.Second).Unix()),
|
||||
},
|
||||
SSHOptions{Backdate: time.Second},
|
||||
SignSSHOptions{Backdate: time.Second},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
|
@ -762,7 +762,7 @@ func Test_sshCertValidityValidator(t *testing.T) {
|
|||
ValidAfter: uint64(now().Unix()),
|
||||
ValidBefore: uint64(now().Add(8 * time.Hour).Unix()),
|
||||
},
|
||||
SSHOptions{Backdate: time.Second},
|
||||
SignSSHOptions{Backdate: time.Second},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
@ -908,7 +908,7 @@ func Test_sshValidityModifier(t *testing.T) {
|
|||
for name, run := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
tt := run()
|
||||
if err := tt.svm.Option(SSHOptions{}).Modify(tt.cert); err != nil {
|
||||
if err := tt.svm.Option(SignSSHOptions{}).Modify(tt.cert); err != nil {
|
||||
if assert.NotNil(t, tt.err) {
|
||||
assert.HasPrefix(t, err.Error(), tt.err.Error())
|
||||
}
|
||||
|
@ -962,7 +962,7 @@ func Test_sshDefaultDuration_Option(t *testing.T) {
|
|||
Claimer *Claimer
|
||||
}
|
||||
type args struct {
|
||||
o SSHOptions
|
||||
o SignSSHOptions
|
||||
cert *ssh.Certificate
|
||||
}
|
||||
tests := []struct {
|
||||
|
@ -972,26 +972,26 @@ func Test_sshDefaultDuration_Option(t *testing.T) {
|
|||
want *ssh.Certificate
|
||||
wantErr bool
|
||||
}{
|
||||
{"user", fields{newClaimer(nil)}, args{SSHOptions{}, &ssh.Certificate{CertType: ssh.UserCert}},
|
||||
{"user", fields{newClaimer(nil)}, args{SignSSHOptions{}, &ssh.Certificate{CertType: ssh.UserCert}},
|
||||
&ssh.Certificate{CertType: ssh.UserCert, ValidAfter: unix(0), ValidBefore: unix(16 * time.Hour)}, false},
|
||||
{"host", fields{newClaimer(nil)}, args{SSHOptions{}, &ssh.Certificate{CertType: ssh.HostCert}},
|
||||
{"host", fields{newClaimer(nil)}, args{SignSSHOptions{}, &ssh.Certificate{CertType: ssh.HostCert}},
|
||||
&ssh.Certificate{CertType: ssh.HostCert, ValidAfter: unix(0), ValidBefore: unix(30 * 24 * time.Hour)}, false},
|
||||
{"user claim", fields{newClaimer(&Claims{DefaultUserSSHDur: &Duration{1 * time.Hour}})}, args{SSHOptions{}, &ssh.Certificate{CertType: ssh.UserCert}},
|
||||
{"user claim", fields{newClaimer(&Claims{DefaultUserSSHDur: &Duration{1 * time.Hour}})}, args{SignSSHOptions{}, &ssh.Certificate{CertType: ssh.UserCert}},
|
||||
&ssh.Certificate{CertType: ssh.UserCert, ValidAfter: unix(0), ValidBefore: unix(1 * time.Hour)}, false},
|
||||
{"host claim", fields{newClaimer(&Claims{DefaultHostSSHDur: &Duration{1 * time.Hour}})}, args{SSHOptions{}, &ssh.Certificate{CertType: ssh.HostCert}},
|
||||
{"host claim", fields{newClaimer(&Claims{DefaultHostSSHDur: &Duration{1 * time.Hour}})}, args{SignSSHOptions{}, &ssh.Certificate{CertType: ssh.HostCert}},
|
||||
&ssh.Certificate{CertType: ssh.HostCert, ValidAfter: unix(0), ValidBefore: unix(1 * time.Hour)}, false},
|
||||
{"user backdate", fields{newClaimer(nil)}, args{SSHOptions{Backdate: 1 * time.Minute}, &ssh.Certificate{CertType: ssh.UserCert}},
|
||||
{"user backdate", fields{newClaimer(nil)}, args{SignSSHOptions{Backdate: 1 * time.Minute}, &ssh.Certificate{CertType: ssh.UserCert}},
|
||||
&ssh.Certificate{CertType: ssh.UserCert, ValidAfter: unix(-1 * time.Minute), ValidBefore: unix(16 * time.Hour)}, false},
|
||||
{"host backdate", fields{newClaimer(nil)}, args{SSHOptions{Backdate: 1 * time.Minute}, &ssh.Certificate{CertType: ssh.HostCert}},
|
||||
{"host backdate", fields{newClaimer(nil)}, args{SignSSHOptions{Backdate: 1 * time.Minute}, &ssh.Certificate{CertType: ssh.HostCert}},
|
||||
&ssh.Certificate{CertType: ssh.HostCert, ValidAfter: unix(-1 * time.Minute), ValidBefore: unix(30 * 24 * time.Hour)}, false},
|
||||
{"user validAfter", fields{newClaimer(nil)}, args{SSHOptions{Backdate: 1 * time.Minute}, &ssh.Certificate{CertType: ssh.UserCert, ValidAfter: unix(1 * time.Hour)}},
|
||||
{"user validAfter", fields{newClaimer(nil)}, args{SignSSHOptions{Backdate: 1 * time.Minute}, &ssh.Certificate{CertType: ssh.UserCert, ValidAfter: unix(1 * time.Hour)}},
|
||||
&ssh.Certificate{CertType: ssh.UserCert, ValidAfter: unix(time.Hour), ValidBefore: unix(17 * time.Hour)}, false},
|
||||
{"user validBefore", fields{newClaimer(nil)}, args{SSHOptions{Backdate: 1 * time.Minute}, &ssh.Certificate{CertType: ssh.UserCert, ValidBefore: unix(1 * time.Hour)}},
|
||||
{"user validBefore", fields{newClaimer(nil)}, args{SignSSHOptions{Backdate: 1 * time.Minute}, &ssh.Certificate{CertType: ssh.UserCert, ValidBefore: unix(1 * time.Hour)}},
|
||||
&ssh.Certificate{CertType: ssh.UserCert, ValidAfter: unix(-1 * time.Minute), ValidBefore: unix(time.Hour)}, false},
|
||||
{"host validAfter validBefore", fields{newClaimer(nil)}, args{SSHOptions{Backdate: 1 * time.Minute}, &ssh.Certificate{CertType: ssh.HostCert, ValidAfter: unix(1 * time.Minute), ValidBefore: unix(2 * time.Minute)}},
|
||||
{"host validAfter validBefore", fields{newClaimer(nil)}, args{SignSSHOptions{Backdate: 1 * time.Minute}, &ssh.Certificate{CertType: ssh.HostCert, ValidAfter: unix(1 * time.Minute), ValidBefore: unix(2 * time.Minute)}},
|
||||
&ssh.Certificate{CertType: ssh.HostCert, ValidAfter: unix(1 * time.Minute), ValidBefore: unix(2 * time.Minute)}, false},
|
||||
{"fail zero", fields{newClaimer(nil)}, args{SSHOptions{}, &ssh.Certificate{}}, &ssh.Certificate{}, true},
|
||||
{"fail type", fields{newClaimer(nil)}, args{SSHOptions{}, &ssh.Certificate{CertType: 3}}, &ssh.Certificate{CertType: 3}, true},
|
||||
{"fail zero", fields{newClaimer(nil)}, args{SignSSHOptions{}, &ssh.Certificate{}}, &ssh.Certificate{}, true},
|
||||
{"fail type", fields{newClaimer(nil)}, args{SignSSHOptions{}, &ssh.Certificate{CertType: 3}}, &ssh.Certificate{CertType: 3}, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
@ -1015,7 +1015,7 @@ func Test_sshLimitDuration_Option(t *testing.T) {
|
|||
NotAfter time.Time
|
||||
}
|
||||
type args struct {
|
||||
o SSHOptions
|
||||
o SignSSHOptions
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
func validateSSHCertificate(cert *ssh.Certificate, opts *SSHOptions) error {
|
||||
func validateSSHCertificate(cert *ssh.Certificate, opts *SignSSHOptions) error {
|
||||
switch {
|
||||
case cert == nil:
|
||||
return fmt.Errorf("certificate is nil")
|
||||
|
@ -39,7 +39,7 @@ func validateSSHCertificate(cert *ssh.Certificate, opts *SSHOptions) error {
|
|||
}
|
||||
}
|
||||
|
||||
func signSSHCertificate(key crypto.PublicKey, opts SSHOptions, signOpts []SignOption, signKey crypto.Signer) (*ssh.Certificate, error) {
|
||||
func signSSHCertificate(key crypto.PublicKey, opts SignSSHOptions, signOpts []SignOption, signKey crypto.Signer) (*ssh.Certificate, error) {
|
||||
pub, err := ssh.NewPublicKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -713,20 +713,20 @@ func generateK8sSAToken(jwk *jose.JSONWebKey, claims *k8sSAPayload, tokOpts ...t
|
|||
}
|
||||
|
||||
func generateSimpleSSHUserToken(iss, aud string, jwk *jose.JSONWebKey) (string, error) {
|
||||
return generateSSHToken("subject@localhost", iss, aud, time.Now(), &SSHOptions{
|
||||
return generateSSHToken("subject@localhost", iss, aud, time.Now(), &SignSSHOptions{
|
||||
CertType: "user",
|
||||
Principals: []string{"name"},
|
||||
}, jwk)
|
||||
}
|
||||
|
||||
func generateSimpleSSHHostToken(iss, aud string, jwk *jose.JSONWebKey) (string, error) {
|
||||
return generateSSHToken("subject@localhost", iss, aud, time.Now(), &SSHOptions{
|
||||
return generateSSHToken("subject@localhost", iss, aud, time.Now(), &SignSSHOptions{
|
||||
CertType: "host",
|
||||
Principals: []string{"smallstep.com"},
|
||||
}, jwk)
|
||||
}
|
||||
|
||||
func generateSSHToken(sub, iss, aud string, iat time.Time, sshOpts *SSHOptions, jwk *jose.JSONWebKey) (string, error) {
|
||||
func generateSSHToken(sub, iss, aud string, iat time.Time, sshOpts *SignSSHOptions, jwk *jose.JSONWebKey) (string, error) {
|
||||
sig, err := jose.NewSigner(
|
||||
jose.SigningKey{Algorithm: jose.ES256, Key: jwk.Key},
|
||||
new(jose.SignerOptions).WithType("JWT").WithHeader("kid", jwk.KeyID),
|
||||
|
|
|
@ -25,11 +25,11 @@ type x5cPayload struct {
|
|||
// signature requests.
|
||||
type X5C struct {
|
||||
*base
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Roots []byte `json:"roots"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *ProvisionerOptions `json:"options,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Roots []byte `json:"roots"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *Options `json:"options,omitempty"`
|
||||
claimer *Claimer
|
||||
audiences Audiences
|
||||
rootPool *x509.CertPool
|
||||
|
|
|
@ -696,7 +696,7 @@ func TestX5C_AuthorizeSSHSign(t *testing.T) {
|
|||
Expiry: jose.NewNumericDate(now.Add(5 * time.Minute)),
|
||||
Audience: []string{testAudiences.SSHSign[0]},
|
||||
},
|
||||
Step: &stepPayload{SSH: &SSHOptions{
|
||||
Step: &stepPayload{SSH: &SignSSHOptions{
|
||||
CertType: SSHHostCert,
|
||||
Principals: []string{"max", "mariano", "alan"},
|
||||
ValidAfter: TimeDuration{d: 5 * time.Minute},
|
||||
|
@ -728,7 +728,7 @@ func TestX5C_AuthorizeSSHSign(t *testing.T) {
|
|||
Expiry: jose.NewNumericDate(now.Add(5 * time.Minute)),
|
||||
Audience: []string{testAudiences.SSHSign[0]},
|
||||
},
|
||||
Step: &stepPayload{SSH: &SSHOptions{}},
|
||||
Step: &stepPayload{SSH: &SignSSHOptions{}},
|
||||
}
|
||||
tok, err := generateX5CSSHToken(x5cJWK, claims, withX5CHdr(x5cCerts))
|
||||
assert.FatalError(t, err)
|
||||
|
@ -759,7 +759,7 @@ func TestX5C_AuthorizeSSHSign(t *testing.T) {
|
|||
case sshCertOptionsValidator:
|
||||
tc.claims.Step.SSH.ValidAfter.t = time.Time{}
|
||||
tc.claims.Step.SSH.ValidBefore.t = time.Time{}
|
||||
assert.Equals(t, SSHOptions(v), *tc.claims.Step.SSH)
|
||||
assert.Equals(t, SignSSHOptions(v), *tc.claims.Step.SSH)
|
||||
case sshCertKeyIDModifier:
|
||||
assert.Equals(t, string(v), "foo")
|
||||
case sshCertTypeModifier:
|
||||
|
@ -771,7 +771,7 @@ func TestX5C_AuthorizeSSHSign(t *testing.T) {
|
|||
case sshCertValidBeforeModifier:
|
||||
assert.Equals(t, int64(v), tc.claims.Step.SSH.ValidBefore.RelativeTime(nw).Unix())
|
||||
case sshCertDefaultsModifier:
|
||||
assert.Equals(t, SSHOptions(v), SSHOptions{CertType: SSHUserCert})
|
||||
assert.Equals(t, SignSSHOptions(v), SignSSHOptions{CertType: SSHUserCert})
|
||||
case *sshLimitDuration:
|
||||
assert.Equals(t, v.Claimer, tc.p.claimer)
|
||||
assert.Equals(t, v.NotAfter, x5cCerts[0].NotAfter)
|
||||
|
|
|
@ -204,7 +204,7 @@ func (a *Authority) GetSSHBastion(ctx context.Context, user string, hostname str
|
|||
}
|
||||
|
||||
// SignSSH creates a signed SSH certificate with the given public key and options.
|
||||
func (a *Authority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisioner.SSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error) {
|
||||
func (a *Authority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisioner.SignSSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error) {
|
||||
var mods []provisioner.SSHCertModifier
|
||||
var validators []provisioner.SSHCertValidator
|
||||
|
||||
|
@ -453,7 +453,7 @@ func (a *Authority) RekeySSH(ctx context.Context, oldCert *ssh.Certificate, pub
|
|||
|
||||
// Apply validators from provisioner.
|
||||
for _, v := range validators {
|
||||
if err := v.Valid(cert, provisioner.SSHOptions{Backdate: backdate}); err != nil {
|
||||
if err := v.Valid(cert, provisioner.SignSSHOptions{Backdate: backdate}); err != nil {
|
||||
return nil, errs.Wrap(http.StatusForbidden, err, "rekeySSH")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ func (m sshTestCertModifier) Modify(cert *ssh.Certificate) error {
|
|||
|
||||
type sshTestCertValidator string
|
||||
|
||||
func (v sshTestCertValidator) Valid(crt *ssh.Certificate, opts provisioner.SSHOptions) error {
|
||||
func (v sshTestCertValidator) Valid(crt *ssh.Certificate, opts provisioner.SignSSHOptions) error {
|
||||
if v == "" {
|
||||
return nil
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ func (v sshTestCertValidator) Valid(crt *ssh.Certificate, opts provisioner.SSHOp
|
|||
|
||||
type sshTestOptionsValidator string
|
||||
|
||||
func (v sshTestOptionsValidator) Valid(opts provisioner.SSHOptions) error {
|
||||
func (v sshTestOptionsValidator) Valid(opts provisioner.SignSSHOptions) error {
|
||||
if v == "" {
|
||||
return nil
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ func (v sshTestOptionsValidator) Valid(opts provisioner.SSHOptions) error {
|
|||
|
||||
type sshTestOptionsModifier string
|
||||
|
||||
func (m sshTestOptionsModifier) Option(opts provisioner.SSHOptions) provisioner.SSHCertModifier {
|
||||
func (m sshTestOptionsModifier) Option(opts provisioner.SignSSHOptions) provisioner.SSHCertModifier {
|
||||
return sshTestCertModifier(string(m))
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ func TestAuthority_SignSSH(t *testing.T) {
|
|||
}
|
||||
type args struct {
|
||||
key ssh.PublicKey
|
||||
opts provisioner.SSHOptions
|
||||
opts provisioner.SignSSHOptions
|
||||
signOpts []provisioner.SignOption
|
||||
}
|
||||
type want struct {
|
||||
|
@ -125,27 +125,27 @@ func TestAuthority_SignSSH(t *testing.T) {
|
|||
want want
|
||||
wantErr bool
|
||||
}{
|
||||
{"ok-user", fields{signer, signer}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{userOptions}}, want{CertType: ssh.UserCert}, false},
|
||||
{"ok-host", fields{signer, signer}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{hostOptions}}, want{CertType: ssh.HostCert}, false},
|
||||
{"ok-opts-type-user", fields{signer, signer}, args{pub, provisioner.SSHOptions{CertType: "user"}, []provisioner.SignOption{}}, want{CertType: ssh.UserCert}, false},
|
||||
{"ok-opts-type-host", fields{signer, signer}, args{pub, provisioner.SSHOptions{CertType: "host"}, []provisioner.SignOption{}}, want{CertType: ssh.HostCert}, false},
|
||||
{"ok-opts-principals", fields{signer, signer}, args{pub, provisioner.SSHOptions{CertType: "user", Principals: []string{"user"}}, []provisioner.SignOption{}}, want{CertType: ssh.UserCert, Principals: []string{"user"}}, false},
|
||||
{"ok-opts-principals", fields{signer, signer}, args{pub, provisioner.SSHOptions{CertType: "host", Principals: []string{"foo.test.com", "bar.test.com"}}, []provisioner.SignOption{}}, want{CertType: ssh.HostCert, Principals: []string{"foo.test.com", "bar.test.com"}}, false},
|
||||
{"ok-opts-valid-after", fields{signer, signer}, args{pub, provisioner.SSHOptions{CertType: "user", ValidAfter: provisioner.NewTimeDuration(now)}, []provisioner.SignOption{}}, want{CertType: ssh.UserCert, ValidAfter: uint64(now.Unix())}, false},
|
||||
{"ok-opts-valid-before", fields{signer, signer}, args{pub, provisioner.SSHOptions{CertType: "host", ValidBefore: provisioner.NewTimeDuration(now)}, []provisioner.SignOption{}}, want{CertType: ssh.HostCert, ValidBefore: uint64(now.Unix())}, false},
|
||||
{"ok-cert-validator", fields{signer, signer}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{userOptions, sshTestCertValidator("")}}, want{CertType: ssh.UserCert}, false},
|
||||
{"ok-cert-modifier", fields{signer, signer}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{userOptions, sshTestCertModifier("")}}, want{CertType: ssh.UserCert}, false},
|
||||
{"ok-opts-validator", fields{signer, signer}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{userOptions, sshTestOptionsValidator("")}}, want{CertType: ssh.UserCert}, false},
|
||||
{"ok-opts-modifier", fields{signer, signer}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{userOptions, sshTestOptionsModifier("")}}, want{CertType: ssh.UserCert}, false},
|
||||
{"fail-opts-type", fields{signer, signer}, args{pub, provisioner.SSHOptions{CertType: "foo"}, []provisioner.SignOption{}}, want{}, true},
|
||||
{"fail-cert-validator", fields{signer, signer}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{userOptions, sshTestCertValidator("an error")}}, want{}, true},
|
||||
{"fail-cert-modifier", fields{signer, signer}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{userOptions, sshTestCertModifier("an error")}}, want{}, true},
|
||||
{"fail-opts-validator", fields{signer, signer}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{userOptions, sshTestOptionsValidator("an error")}}, want{}, true},
|
||||
{"fail-opts-modifier", fields{signer, signer}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{userOptions, sshTestOptionsModifier("an error")}}, want{}, true},
|
||||
{"fail-bad-sign-options", fields{signer, signer}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{userOptions, "wrong type"}}, want{}, true},
|
||||
{"fail-no-user-key", fields{nil, signer}, args{pub, provisioner.SSHOptions{CertType: "user"}, []provisioner.SignOption{}}, want{}, true},
|
||||
{"fail-no-host-key", fields{signer, nil}, args{pub, provisioner.SSHOptions{CertType: "host"}, []provisioner.SignOption{}}, want{}, true},
|
||||
{"fail-bad-type", fields{signer, nil}, args{pub, provisioner.SSHOptions{}, []provisioner.SignOption{sshTestModifier{CertType: 0}}}, want{}, true},
|
||||
{"ok-user", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{userOptions}}, want{CertType: ssh.UserCert}, false},
|
||||
{"ok-host", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{hostOptions}}, want{CertType: ssh.HostCert}, false},
|
||||
{"ok-opts-type-user", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{CertType: "user"}, []provisioner.SignOption{}}, want{CertType: ssh.UserCert}, false},
|
||||
{"ok-opts-type-host", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{CertType: "host"}, []provisioner.SignOption{}}, want{CertType: ssh.HostCert}, false},
|
||||
{"ok-opts-principals", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{CertType: "user", Principals: []string{"user"}}, []provisioner.SignOption{}}, want{CertType: ssh.UserCert, Principals: []string{"user"}}, false},
|
||||
{"ok-opts-principals", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{CertType: "host", Principals: []string{"foo.test.com", "bar.test.com"}}, []provisioner.SignOption{}}, want{CertType: ssh.HostCert, Principals: []string{"foo.test.com", "bar.test.com"}}, false},
|
||||
{"ok-opts-valid-after", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{CertType: "user", ValidAfter: provisioner.NewTimeDuration(now)}, []provisioner.SignOption{}}, want{CertType: ssh.UserCert, ValidAfter: uint64(now.Unix())}, false},
|
||||
{"ok-opts-valid-before", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{CertType: "host", ValidBefore: provisioner.NewTimeDuration(now)}, []provisioner.SignOption{}}, want{CertType: ssh.HostCert, ValidBefore: uint64(now.Unix())}, false},
|
||||
{"ok-cert-validator", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{userOptions, sshTestCertValidator("")}}, want{CertType: ssh.UserCert}, false},
|
||||
{"ok-cert-modifier", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{userOptions, sshTestCertModifier("")}}, want{CertType: ssh.UserCert}, false},
|
||||
{"ok-opts-validator", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{userOptions, sshTestOptionsValidator("")}}, want{CertType: ssh.UserCert}, false},
|
||||
{"ok-opts-modifier", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{userOptions, sshTestOptionsModifier("")}}, want{CertType: ssh.UserCert}, false},
|
||||
{"fail-opts-type", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{CertType: "foo"}, []provisioner.SignOption{}}, want{}, true},
|
||||
{"fail-cert-validator", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{userOptions, sshTestCertValidator("an error")}}, want{}, true},
|
||||
{"fail-cert-modifier", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{userOptions, sshTestCertModifier("an error")}}, want{}, true},
|
||||
{"fail-opts-validator", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{userOptions, sshTestOptionsValidator("an error")}}, want{}, true},
|
||||
{"fail-opts-modifier", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{userOptions, sshTestOptionsModifier("an error")}}, want{}, true},
|
||||
{"fail-bad-sign-options", fields{signer, signer}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{userOptions, "wrong type"}}, want{}, true},
|
||||
{"fail-no-user-key", fields{nil, signer}, args{pub, provisioner.SignSSHOptions{CertType: "user"}, []provisioner.SignOption{}}, want{}, true},
|
||||
{"fail-no-host-key", fields{signer, nil}, args{pub, provisioner.SignSSHOptions{CertType: "host"}, []provisioner.SignOption{}}, want{}, true},
|
||||
{"fail-bad-type", fields{signer, nil}, args{pub, provisioner.SignSSHOptions{}, []provisioner.SignOption{sshTestModifier{CertType: 0}}}, want{}, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
@ -32,7 +32,7 @@ var oidAuthorityKeyIdentifier = asn1.ObjectIdentifier{2, 5, 29, 35}
|
|||
var oidSubjectKeyIdentifier = asn1.ObjectIdentifier{2, 5, 29, 14}
|
||||
|
||||
func withDefaultASN1DN(def *x509legacy.ASN1DN) provisioner.CertificateModifierFunc {
|
||||
return func(crt *x509.Certificate, opts provisioner.Options) error {
|
||||
return func(crt *x509.Certificate, opts provisioner.SignOptions) error {
|
||||
if def == nil {
|
||||
return errors.New("default ASN1DN template cannot be nil")
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func withDefaultASN1DN(def *x509legacy.ASN1DN) provisioner.CertificateModifierFu
|
|||
}
|
||||
|
||||
// Sign creates a signed certificate from a certificate signing request.
|
||||
func (a *Authority) Sign(csr *x509.CertificateRequest, signOpts provisioner.Options, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
func (a *Authority) Sign(csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
|
||||
var (
|
||||
certOptions []x509util.Option
|
||||
certValidators []provisioner.CertificateValidator
|
||||
|
|
|
@ -132,7 +132,7 @@ func TestAuthority_Sign(t *testing.T) {
|
|||
}
|
||||
|
||||
nb := time.Now()
|
||||
signOpts := provisioner.Options{
|
||||
signOpts := provisioner.SignOptions{
|
||||
NotBefore: provisioner.NewTimeDuration(nb),
|
||||
NotAfter: provisioner.NewTimeDuration(nb.Add(time.Minute * 5)),
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ func TestAuthority_Sign(t *testing.T) {
|
|||
type signTest struct {
|
||||
auth *Authority
|
||||
csr *x509.CertificateRequest
|
||||
signOpts provisioner.Options
|
||||
signOpts provisioner.SignOptions
|
||||
extraOpts []provisioner.SignOption
|
||||
notBefore time.Time
|
||||
notAfter time.Time
|
||||
|
@ -210,7 +210,7 @@ func TestAuthority_Sign(t *testing.T) {
|
|||
},
|
||||
"fail provisioner duration claim": func(t *testing.T) *signTest {
|
||||
csr := getCSR(t, priv)
|
||||
_signOpts := provisioner.Options{
|
||||
_signOpts := provisioner.SignOptions{
|
||||
NotBefore: provisioner.NewTimeDuration(nb),
|
||||
NotAfter: provisioner.NewTimeDuration(nb.Add(time.Hour * 25)),
|
||||
}
|
||||
|
@ -429,14 +429,14 @@ func TestAuthority_Renew(t *testing.T) {
|
|||
certModToWithOptions := func(m provisioner.CertificateModifierFunc) x509util.WithOption {
|
||||
return func(p x509util.Profile) error {
|
||||
crt := p.Subject()
|
||||
return m.Modify(crt, provisioner.Options{})
|
||||
return m.Modify(crt, provisioner.SignOptions{})
|
||||
}
|
||||
}
|
||||
|
||||
now := time.Now().UTC()
|
||||
nb1 := now.Add(-time.Minute * 7)
|
||||
na1 := now
|
||||
so := &provisioner.Options{
|
||||
so := &provisioner.SignOptions{
|
||||
NotBefore: provisioner.NewTimeDuration(nb1),
|
||||
NotAfter: provisioner.NewTimeDuration(na1),
|
||||
}
|
||||
|
@ -656,14 +656,14 @@ func TestAuthority_Rekey(t *testing.T) {
|
|||
certModToWithOptions := func(m provisioner.CertificateModifierFunc) x509util.WithOption {
|
||||
return func(p x509util.Profile) error {
|
||||
crt := p.Subject()
|
||||
return m.Modify(crt, provisioner.Options{})
|
||||
return m.Modify(crt, provisioner.SignOptions{})
|
||||
}
|
||||
}
|
||||
|
||||
now := time.Now().UTC()
|
||||
nb1 := now.Add(-time.Minute * 7)
|
||||
na1 := now
|
||||
so := &provisioner.Options{
|
||||
so := &provisioner.SignOptions{
|
||||
NotBefore: provisioner.NewTimeDuration(nb1),
|
||||
NotAfter: provisioner.NewTimeDuration(na1),
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ func (p *Provisioner) SSHToken(certType, keyID string, principals []string) (str
|
|||
token.WithIssuer(p.name),
|
||||
token.WithAudience(p.sshAudience),
|
||||
token.WithValidity(notBefore, notAfter),
|
||||
token.WithSSH(provisioner.SSHOptions{
|
||||
token.WithSSH(provisioner.SignSSHOptions{
|
||||
CertType: certType,
|
||||
Principals: principals,
|
||||
KeyID: keyID,
|
||||
|
|
Loading…
Reference in a new issue