Store provisioner with SignSSH

This change also allows to store the old certificate on renewal on
linkedca or if the db interface supports it.
This commit is contained in:
Mariano Cano 2022-05-18 18:33:53 -07:00
parent c8d7ad7ab9
commit 293586079a

View file

@ -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")
} }