forked from TrueCloudLab/certificates
Merge pull request #941 from smallstep/ssh-provisioner
Report SSH provisioner
This commit is contained in:
commit
3c4d0412ef
20 changed files with 110 additions and 28 deletions
|
@ -1034,7 +1034,7 @@ func TestAuthority_authorizeSSHSign(t *testing.T) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if assert.Nil(t, tc.err) {
|
if assert.Nil(t, tc.err) {
|
||||||
assert.Len(t, 8, got) // number of provisioner.SignOptions returned
|
assert.Len(t, 9, got) // number of provisioner.SignOptions returned
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -289,18 +289,29 @@ func (c *linkedCaClient) StoreRenewedCertificate(parent *x509.Certificate, fullc
|
||||||
PemCertificateChain: serializeCertificateChain(fullchain[1:]...),
|
PemCertificateChain: serializeCertificateChain(fullchain[1:]...),
|
||||||
PemParentCertificate: serializeCertificateChain(parent),
|
PemParentCertificate: serializeCertificateChain(parent),
|
||||||
})
|
})
|
||||||
return errors.Wrap(err, "error posting certificate")
|
return errors.Wrap(err, "error posting renewed certificate")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *linkedCaClient) StoreSSHCertificate(crt *ssh.Certificate) error {
|
func (c *linkedCaClient) StoreSSHCertificate(prov provisioner.Interface, crt *ssh.Certificate) error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
_, err := c.client.PostSSHCertificate(ctx, &linkedca.SSHCertificateRequest{
|
_, err := c.client.PostSSHCertificate(ctx, &linkedca.SSHCertificateRequest{
|
||||||
Certificate: string(ssh.MarshalAuthorizedKey(crt)),
|
Certificate: string(ssh.MarshalAuthorizedKey(crt)),
|
||||||
|
Provisioner: createProvisionerIdentity(prov),
|
||||||
})
|
})
|
||||||
return errors.Wrap(err, "error posting ssh certificate")
|
return errors.Wrap(err, "error posting ssh certificate")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *linkedCaClient) StoreRenewedSSHCertificate(parent, crt *ssh.Certificate) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
_, err := c.client.PostSSHCertificate(ctx, &linkedca.SSHCertificateRequest{
|
||||||
|
Certificate: string(ssh.MarshalAuthorizedKey(crt)),
|
||||||
|
ParentCertificate: string(ssh.MarshalAuthorizedKey(parent)),
|
||||||
|
})
|
||||||
|
return errors.Wrap(err, "error posting renewed ssh certificate")
|
||||||
|
}
|
||||||
|
|
||||||
func (c *linkedCaClient) Revoke(crt *x509.Certificate, rci *db.RevokedCertificateInfo) error {
|
func (c *linkedCaClient) Revoke(crt *x509.Certificate, rci *db.RevokedCertificateInfo) error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
|
@ -747,6 +747,7 @@ func (p *AWS) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
|
||||||
signOptions = append(signOptions, templateOptions)
|
signOptions = append(signOptions, templateOptions)
|
||||||
|
|
||||||
return append(signOptions,
|
return append(signOptions,
|
||||||
|
p,
|
||||||
// Validate user SignSSHOptions.
|
// Validate user SignSSHOptions.
|
||||||
sshCertOptionsValidator(defaults),
|
sshCertOptionsValidator(defaults),
|
||||||
// Set the validity bounds if not set.
|
// Set the validity bounds if not set.
|
||||||
|
|
|
@ -813,7 +813,6 @@ func TestAWS_AuthorizeSSHSign(t *testing.T) {
|
||||||
} else if assert.NotNil(t, got) {
|
} else if assert.NotNil(t, got) {
|
||||||
cert, err := signSSHCertificate(tt.args.key, tt.args.sshOpts, got, signer.Key.(crypto.Signer))
|
cert, err := signSSHCertificate(tt.args.key, tt.args.sshOpts, got, signer.Key.(crypto.Signer))
|
||||||
if (err != nil) != tt.wantSignErr {
|
if (err != nil) != tt.wantSignErr {
|
||||||
|
|
||||||
t.Errorf("SignSSH error = %v, wantSignErr %v", err, tt.wantSignErr)
|
t.Errorf("SignSSH error = %v, wantSignErr %v", err, tt.wantSignErr)
|
||||||
} else {
|
} else {
|
||||||
if tt.wantSignErr {
|
if tt.wantSignErr {
|
||||||
|
|
|
@ -418,6 +418,7 @@ func (p *Azure) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOptio
|
||||||
signOptions = append(signOptions, templateOptions)
|
signOptions = append(signOptions, templateOptions)
|
||||||
|
|
||||||
return append(signOptions,
|
return append(signOptions,
|
||||||
|
p,
|
||||||
// Validate user SignSSHOptions.
|
// Validate user SignSSHOptions.
|
||||||
sshCertOptionsValidator(defaults),
|
sshCertOptionsValidator(defaults),
|
||||||
// Set the validity bounds if not set.
|
// Set the validity bounds if not set.
|
||||||
|
|
|
@ -425,6 +425,7 @@ func (p *GCP) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
|
||||||
signOptions = append(signOptions, templateOptions)
|
signOptions = append(signOptions, templateOptions)
|
||||||
|
|
||||||
return append(signOptions,
|
return append(signOptions,
|
||||||
|
p,
|
||||||
// Validate user SignSSHOptions.
|
// Validate user SignSSHOptions.
|
||||||
sshCertOptionsValidator(defaults),
|
sshCertOptionsValidator(defaults),
|
||||||
// Set the validity bounds if not set.
|
// Set the validity bounds if not set.
|
||||||
|
|
|
@ -257,6 +257,7 @@ func (p *JWK) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(signOptions,
|
return append(signOptions,
|
||||||
|
p,
|
||||||
// Set the validity bounds if not set.
|
// Set the validity bounds if not set.
|
||||||
&sshDefaultDuration{p.ctl.Claimer},
|
&sshDefaultDuration{p.ctl.Claimer},
|
||||||
// Validate public key
|
// Validate public key
|
||||||
|
|
|
@ -275,6 +275,7 @@ func (p *K8sSA) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOptio
|
||||||
signOptions := []SignOption{templateOptions}
|
signOptions := []SignOption{templateOptions}
|
||||||
|
|
||||||
return append(signOptions,
|
return append(signOptions,
|
||||||
|
p,
|
||||||
// Require type, key-id and principals in the SignSSHOptions.
|
// Require type, key-id and principals in the SignSSHOptions.
|
||||||
&sshCertOptionsRequireValidator{CertType: true, KeyID: true, Principals: true},
|
&sshCertOptionsRequireValidator{CertType: true, KeyID: true, Principals: true},
|
||||||
// Set the validity bounds if not set.
|
// Set the validity bounds if not set.
|
||||||
|
|
|
@ -368,9 +368,10 @@ func TestK8sSA_AuthorizeSSHSign(t *testing.T) {
|
||||||
} else {
|
} else {
|
||||||
if assert.Nil(t, tc.err) {
|
if assert.Nil(t, tc.err) {
|
||||||
if assert.NotNil(t, opts) {
|
if assert.NotNil(t, opts) {
|
||||||
assert.Len(t, 7, opts)
|
assert.Len(t, 8, opts)
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
switch v := o.(type) {
|
switch v := o.(type) {
|
||||||
|
case Interface:
|
||||||
case sshCertificateOptionsFunc:
|
case sshCertificateOptionsFunc:
|
||||||
case *sshCertOptionsRequireValidator:
|
case *sshCertOptionsRequireValidator:
|
||||||
assert.Equals(t, v, &sshCertOptionsRequireValidator{CertType: true, KeyID: true, Principals: true})
|
assert.Equals(t, v, &sshCertOptionsRequireValidator{CertType: true, KeyID: true, Principals: true})
|
||||||
|
|
|
@ -250,6 +250,7 @@ func (p *Nebula) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOpti
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(signOptions,
|
return append(signOptions,
|
||||||
|
p,
|
||||||
templateOptions,
|
templateOptions,
|
||||||
// Checks the validity bounds, and set the validity if has not been set.
|
// Checks the validity bounds, and set the validity if has not been set.
|
||||||
&sshLimitDuration{p.ctl.Claimer, crt.Details.NotAfter},
|
&sshLimitDuration{p.ctl.Claimer, crt.Details.NotAfter},
|
||||||
|
|
|
@ -50,7 +50,7 @@ func (p *noop) AuthorizeRevoke(ctx context.Context, token string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noop) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption, error) {
|
func (p *noop) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption, error) {
|
||||||
return []SignOption{}, nil
|
return []SignOption{p}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noop) AuthorizeSSHRenew(ctx context.Context, token string) (*ssh.Certificate, error) {
|
func (p *noop) AuthorizeSSHRenew(ctx context.Context, token string) (*ssh.Certificate, error) {
|
||||||
|
|
|
@ -434,6 +434,7 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(signOptions,
|
return append(signOptions,
|
||||||
|
o,
|
||||||
// Set the validity bounds if not set.
|
// Set the validity bounds if not set.
|
||||||
&sshDefaultDuration{o.ctl.Claimer},
|
&sshDefaultDuration{o.ctl.Claimer},
|
||||||
// Validate public key
|
// Validate public key
|
||||||
|
|
|
@ -53,6 +53,7 @@ func signSSHCertificate(key crypto.PublicKey, opts SignSSHOptions, signOpts []Si
|
||||||
|
|
||||||
for _, op := range signOpts {
|
for _, op := range signOpts {
|
||||||
switch o := op.(type) {
|
switch o := op.(type) {
|
||||||
|
case Interface:
|
||||||
// add options to NewCertificate
|
// add options to NewCertificate
|
||||||
case SSHCertificateOptions:
|
case SSHCertificateOptions:
|
||||||
certOptions = append(certOptions, o.Options(opts)...)
|
certOptions = append(certOptions, o.Options(opts)...)
|
||||||
|
|
|
@ -312,6 +312,7 @@ func (p *X5C) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(signOptions,
|
return append(signOptions,
|
||||||
|
p,
|
||||||
// Checks the validity bounds, and set the validity if has not been set.
|
// Checks the validity bounds, and set the validity if has not been set.
|
||||||
&sshLimitDuration{p.ctl.Claimer, claims.chains[0][0].NotAfter},
|
&sshLimitDuration{p.ctl.Claimer, claims.chains[0][0].NotAfter},
|
||||||
// Validate public key.
|
// Validate public key.
|
||||||
|
|
|
@ -769,6 +769,7 @@ func TestX5C_AuthorizeSSHSign(t *testing.T) {
|
||||||
nw := now()
|
nw := now()
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
switch v := o.(type) {
|
switch v := o.(type) {
|
||||||
|
case Interface:
|
||||||
case sshCertOptionsValidator:
|
case sshCertOptionsValidator:
|
||||||
tc.claims.Step.SSH.ValidAfter.t = time.Time{}
|
tc.claims.Step.SSH.ValidAfter.t = time.Time{}
|
||||||
tc.claims.Step.SSH.ValidBefore.t = time.Time{}
|
tc.claims.Step.SSH.ValidBefore.t = time.Time{}
|
||||||
|
@ -799,9 +800,9 @@ func TestX5C_AuthorizeSSHSign(t *testing.T) {
|
||||||
tot++
|
tot++
|
||||||
}
|
}
|
||||||
if len(tc.claims.Step.SSH.CertType) > 0 {
|
if len(tc.claims.Step.SSH.CertType) > 0 {
|
||||||
assert.Equals(t, tot, 10)
|
assert.Equals(t, tot, 11)
|
||||||
} else {
|
} else {
|
||||||
assert.Equals(t, tot, 8)
|
assert.Equals(t, tot, 9)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,8 +161,13 @@ func (a *Authority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisi
|
||||||
// Set backdate with the configured value
|
// Set backdate with the configured value
|
||||||
opts.Backdate = a.config.AuthorityConfig.Backdate.Duration
|
opts.Backdate = a.config.AuthorityConfig.Backdate.Duration
|
||||||
|
|
||||||
|
var prov provisioner.Interface
|
||||||
for _, op := range signOpts {
|
for _, op := range signOpts {
|
||||||
switch o := op.(type) {
|
switch o := op.(type) {
|
||||||
|
// Capture current provisioner
|
||||||
|
case provisioner.Interface:
|
||||||
|
prov = o
|
||||||
|
|
||||||
// add options to NewCertificate
|
// add options to NewCertificate
|
||||||
case provisioner.SSHCertificateOptions:
|
case provisioner.SSHCertificateOptions:
|
||||||
certOptions = append(certOptions, o.Options(opts)...)
|
certOptions = append(certOptions, o.Options(opts)...)
|
||||||
|
@ -276,7 +281,7 @@ func (a *Authority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
if err = a.storeSSHCertificate(prov, cert); err != nil && err != db.ErrNotImplemented {
|
||||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "authority.SignSSH: error storing certificate in db")
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "authority.SignSSH: error storing certificate in db")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +345,7 @@ func (a *Authority) RenewSSH(ctx context.Context, oldCert *ssh.Certificate) (*ss
|
||||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "signSSH: error signing certificate")
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "signSSH: error signing certificate")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
if err = a.storeRenewedSSHCertificate(oldCert, cert); err != nil && err != db.ErrNotImplemented {
|
||||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "renewSSH: error storing certificate in db")
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "renewSSH: error storing certificate in db")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,21 +424,59 @@ func (a *Authority) RekeySSH(ctx context.Context, oldCert *ssh.Certificate, pub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
if err = a.storeRenewedSSHCertificate(oldCert, cert); err != nil && err != db.ErrNotImplemented {
|
||||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "rekeySSH; error storing certificate in db")
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "rekeySSH; error storing certificate in db")
|
||||||
}
|
}
|
||||||
|
|
||||||
return cert, nil
|
return cert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Authority) storeSSHCertificate(cert *ssh.Certificate) error {
|
func (a *Authority) storeSSHCertificate(prov provisioner.Interface, cert *ssh.Certificate) error {
|
||||||
type sshCertificateStorer interface {
|
type sshCertificateStorer interface {
|
||||||
StoreSSHCertificate(crt *ssh.Certificate) error
|
StoreSSHCertificate(provisioner.Interface, *ssh.Certificate) error
|
||||||
}
|
}
|
||||||
if s, ok := a.adminDB.(sshCertificateStorer); ok {
|
|
||||||
|
// Store certificate in admindb or linkedca
|
||||||
|
switch s := a.adminDB.(type) {
|
||||||
|
case sshCertificateStorer:
|
||||||
|
return s.StoreSSHCertificate(prov, cert)
|
||||||
|
case db.CertificateStorer:
|
||||||
return s.StoreSSHCertificate(cert)
|
return s.StoreSSHCertificate(cert)
|
||||||
}
|
}
|
||||||
return a.db.StoreSSHCertificate(cert)
|
|
||||||
|
// Store certificate in localdb
|
||||||
|
switch s := a.db.(type) {
|
||||||
|
case sshCertificateStorer:
|
||||||
|
return s.StoreSSHCertificate(prov, cert)
|
||||||
|
case db.CertificateStorer:
|
||||||
|
return s.StoreSSHCertificate(cert)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Authority) storeRenewedSSHCertificate(parent, cert *ssh.Certificate) error {
|
||||||
|
type sshRenewerCertificateStorer interface {
|
||||||
|
StoreRenewedSSHCertificate(parent, cert *ssh.Certificate) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store certificate in admindb or linkedca
|
||||||
|
switch s := a.adminDB.(type) {
|
||||||
|
case sshRenewerCertificateStorer:
|
||||||
|
return s.StoreRenewedSSHCertificate(parent, cert)
|
||||||
|
case db.CertificateStorer:
|
||||||
|
return s.StoreSSHCertificate(cert)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store certificate in localdb
|
||||||
|
switch s := a.db.(type) {
|
||||||
|
case sshRenewerCertificateStorer:
|
||||||
|
return s.StoreRenewedSSHCertificate(parent, cert)
|
||||||
|
case db.CertificateStorer:
|
||||||
|
return s.StoreSSHCertificate(cert)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValidForAddUser checks if a user provisioner certificate can be issued to
|
// IsValidForAddUser checks if a user provisioner certificate can be issued to
|
||||||
|
@ -511,7 +554,7 @@ func (a *Authority) SignSSHAddUser(ctx context.Context, key ssh.PublicKey, subje
|
||||||
}
|
}
|
||||||
cert.Signature = sig
|
cert.Signature = sig
|
||||||
|
|
||||||
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
if err = a.storeRenewedSSHCertificate(subject, cert); err != nil && err != db.ErrNotImplemented {
|
||||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "signSSHAddUser: error storing certificate in db")
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "signSSHAddUser: error storing certificate in db")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -365,28 +365,31 @@ func (a *Authority) Rekey(oldCert *x509.Certificate, pk crypto.PublicKey) ([]*x5
|
||||||
// `StoreCertificate(...*x509.Certificate) error` instead of just
|
// `StoreCertificate(...*x509.Certificate) error` instead of just
|
||||||
// `StoreCertificate(*x509.Certificate) error`.
|
// `StoreCertificate(*x509.Certificate) error`.
|
||||||
func (a *Authority) storeCertificate(prov provisioner.Interface, fullchain []*x509.Certificate) error {
|
func (a *Authority) storeCertificate(prov provisioner.Interface, fullchain []*x509.Certificate) error {
|
||||||
type linkedChainStorer interface {
|
type certificateChainStorer interface {
|
||||||
StoreCertificateChain(provisioner.Interface, ...*x509.Certificate) error
|
StoreCertificateChain(provisioner.Interface, ...*x509.Certificate) error
|
||||||
}
|
}
|
||||||
type certificateChainStorer interface {
|
type certificateChainSimpleStorer interface {
|
||||||
StoreCertificateChain(...*x509.Certificate) error
|
StoreCertificateChain(...*x509.Certificate) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store certificate in linkedca
|
// Store certificate in linkedca
|
||||||
switch s := a.adminDB.(type) {
|
switch s := a.adminDB.(type) {
|
||||||
case linkedChainStorer:
|
|
||||||
return s.StoreCertificateChain(prov, fullchain...)
|
|
||||||
case certificateChainStorer:
|
case certificateChainStorer:
|
||||||
|
return s.StoreCertificateChain(prov, fullchain...)
|
||||||
|
case certificateChainSimpleStorer:
|
||||||
return s.StoreCertificateChain(fullchain...)
|
return s.StoreCertificateChain(fullchain...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store certificate in local db
|
// Store certificate in local db
|
||||||
switch s := a.db.(type) {
|
switch s := a.db.(type) {
|
||||||
case linkedChainStorer:
|
|
||||||
return s.StoreCertificateChain(prov, fullchain...)
|
|
||||||
case certificateChainStorer:
|
case certificateChainStorer:
|
||||||
|
return s.StoreCertificateChain(prov, fullchain...)
|
||||||
|
case certificateChainSimpleStorer:
|
||||||
return s.StoreCertificateChain(fullchain...)
|
return s.StoreCertificateChain(fullchain...)
|
||||||
|
case db.CertificateStorer:
|
||||||
|
return s.StoreCertificate(fullchain[0])
|
||||||
default:
|
default:
|
||||||
return a.db.StoreCertificate(fullchain[0])
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,15 +401,21 @@ func (a *Authority) storeRenewedCertificate(oldCert *x509.Certificate, fullchain
|
||||||
type renewedCertificateChainStorer interface {
|
type renewedCertificateChainStorer interface {
|
||||||
StoreRenewedCertificate(*x509.Certificate, ...*x509.Certificate) error
|
StoreRenewedCertificate(*x509.Certificate, ...*x509.Certificate) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store certificate in linkedca
|
// Store certificate in linkedca
|
||||||
if s, ok := a.adminDB.(renewedCertificateChainStorer); ok {
|
if s, ok := a.adminDB.(renewedCertificateChainStorer); ok {
|
||||||
return s.StoreRenewedCertificate(oldCert, fullchain...)
|
return s.StoreRenewedCertificate(oldCert, fullchain...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store certificate in local db
|
// Store certificate in local db
|
||||||
if s, ok := a.db.(renewedCertificateChainStorer); ok {
|
switch s := a.db.(type) {
|
||||||
|
case renewedCertificateChainStorer:
|
||||||
return s.StoreRenewedCertificate(oldCert, fullchain...)
|
return s.StoreRenewedCertificate(oldCert, fullchain...)
|
||||||
|
case db.CertificateStorer:
|
||||||
|
return s.StoreCertificate(fullchain[0])
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return a.db.StoreCertificate(fullchain[0])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RevokeOptions are the options for the Revoke API.
|
// RevokeOptions are the options for the Revoke API.
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -370,6 +371,9 @@ func TestBootstrapClient(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBootstrapClientServerRotation(t *testing.T) {
|
func TestBootstrapClientServerRotation(t *testing.T) {
|
||||||
|
if os.Getenv("CI") == "true" {
|
||||||
|
t.Skipf("skip until we fix https://github.com/smallstep/certificates/issues/873")
|
||||||
|
}
|
||||||
reset := setMinCertDuration(1 * time.Second)
|
reset := setMinCertDuration(1 * time.Second)
|
||||||
defer reset()
|
defer reset()
|
||||||
|
|
||||||
|
|
9
db/db.go
9
db/db.go
|
@ -50,14 +50,19 @@ type AuthDB interface {
|
||||||
Revoke(rci *RevokedCertificateInfo) error
|
Revoke(rci *RevokedCertificateInfo) error
|
||||||
RevokeSSH(rci *RevokedCertificateInfo) error
|
RevokeSSH(rci *RevokedCertificateInfo) error
|
||||||
GetCertificate(serialNumber string) (*x509.Certificate, error)
|
GetCertificate(serialNumber string) (*x509.Certificate, error)
|
||||||
StoreCertificate(crt *x509.Certificate) error
|
|
||||||
UseToken(id, tok string) (bool, error)
|
UseToken(id, tok string) (bool, error)
|
||||||
IsSSHHost(name string) (bool, error)
|
IsSSHHost(name string) (bool, error)
|
||||||
StoreSSHCertificate(crt *ssh.Certificate) error
|
|
||||||
GetSSHHostPrincipals() ([]string, error)
|
GetSSHHostPrincipals() ([]string, error)
|
||||||
Shutdown() error
|
Shutdown() error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CertificateStorer is an extension of AuthDB that allows to store
|
||||||
|
// certificates.
|
||||||
|
type CertificateStorer interface {
|
||||||
|
StoreCertificate(crt *x509.Certificate) error
|
||||||
|
StoreSSHCertificate(crt *ssh.Certificate) error
|
||||||
|
}
|
||||||
|
|
||||||
// DB is a wrapper over the nosql.DB interface.
|
// DB is a wrapper over the nosql.DB interface.
|
||||||
type DB struct {
|
type DB struct {
|
||||||
nosql.DB
|
nosql.DB
|
||||||
|
|
|
@ -20,7 +20,7 @@ type SimpleDB struct {
|
||||||
usedTokens *sync.Map
|
usedTokens *sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSimpleDB(c *Config) (AuthDB, error) {
|
func newSimpleDB(c *Config) (*SimpleDB, error) {
|
||||||
db := &SimpleDB{}
|
db := &SimpleDB{}
|
||||||
db.usedTokens = new(sync.Map)
|
db.usedTokens = new(sync.Map)
|
||||||
return db, nil
|
return db, nil
|
||||||
|
|
Loading…
Reference in a new issue