Store x509 and ssh certificates on linkedca if enabled.
This commit is contained in:
parent
17eef81c91
commit
71f8019243
4 changed files with 74 additions and 9 deletions
|
@ -6,6 +6,7 @@ import (
|
|||
"crypto/sha256"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
|
@ -21,6 +22,7 @@ import (
|
|||
"go.step.sm/crypto/tlsutil"
|
||||
"go.step.sm/crypto/x509util"
|
||||
"go.step.sm/linkedca"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
@ -237,6 +239,47 @@ func (c *linkedCaClient) DeleteAdmin(ctx context.Context, id string) error {
|
|||
return errors.Wrap(err, "error deleting admin")
|
||||
}
|
||||
|
||||
func (c *linkedCaClient) StoreCertificateChain(fullchain ...*x509.Certificate) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
_, err := c.client.PostCertificate(ctx, &linkedca.CertificateRequest{
|
||||
PemCertificate: serializeCertificateChain(fullchain[0]),
|
||||
PemCertificateChain: serializeCertificateChain(fullchain[1:]...),
|
||||
})
|
||||
return errors.Wrap(err, "error posting certificate")
|
||||
}
|
||||
|
||||
func (c *linkedCaClient) StoreRenewedCertificate(parent *x509.Certificate, fullchain ...*x509.Certificate) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
_, err := c.client.PostCertificate(ctx, &linkedca.CertificateRequest{
|
||||
PemCertificate: serializeCertificateChain(fullchain[0]),
|
||||
PemCertificateChain: serializeCertificateChain(fullchain[1:]...),
|
||||
PemParentCertificate: serializeCertificateChain(parent),
|
||||
})
|
||||
return errors.Wrap(err, "error posting certificate")
|
||||
}
|
||||
|
||||
func (c *linkedCaClient) StoreSSHCertificate(crt *ssh.Certificate) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
_, err := c.client.PostSSHCertificate(ctx, &linkedca.SSHCertificateRequest{
|
||||
Certificate: base64.StdEncoding.EncodeToString(crt.Marshal()),
|
||||
})
|
||||
return errors.Wrap(err, "error posting ssh certificate")
|
||||
}
|
||||
|
||||
func serializeCertificateChain(fullchain ...*x509.Certificate) string {
|
||||
var chain string
|
||||
for _, crt := range fullchain {
|
||||
chain += string(pem.EncodeToMemory(&pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: crt.Raw,
|
||||
}))
|
||||
}
|
||||
return chain
|
||||
}
|
||||
|
||||
func getAuthority(sans []string) (string, error) {
|
||||
for _, s := range sans {
|
||||
if strings.HasPrefix(s, "urn:smallstep:authority:") {
|
||||
|
|
|
@ -239,7 +239,7 @@ func (a *Authority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisi
|
|||
}
|
||||
}
|
||||
|
||||
if err = a.db.StoreSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
||||
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "authority.SignSSH: error storing certificate in db")
|
||||
}
|
||||
|
||||
|
@ -294,7 +294,7 @@ func (a *Authority) RenewSSH(ctx context.Context, oldCert *ssh.Certificate) (*ss
|
|||
return nil, errs.Wrap(http.StatusInternalServerError, err, "signSSH: error signing certificate")
|
||||
}
|
||||
|
||||
if err = a.db.StoreSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
||||
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "renewSSH: error storing certificate in db")
|
||||
}
|
||||
|
||||
|
@ -369,13 +369,23 @@ func (a *Authority) RekeySSH(ctx context.Context, oldCert *ssh.Certificate, pub
|
|||
}
|
||||
}
|
||||
|
||||
if err = a.db.StoreSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
||||
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "rekeySSH; error storing certificate in db")
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
func (a *Authority) storeSSHCertificate(cert *ssh.Certificate) error {
|
||||
type sshCertificateStorer interface {
|
||||
StoreSSHCertificate(crt *ssh.Certificate) error
|
||||
}
|
||||
if s, ok := a.adminDB.(sshCertificateStorer); ok {
|
||||
return s.StoreSSHCertificate(cert)
|
||||
}
|
||||
return a.db.StoreSSHCertificate(cert)
|
||||
}
|
||||
|
||||
// IsValidForAddUser checks if a user provisioner certificate can be issued to
|
||||
// the given certificate.
|
||||
func IsValidForAddUser(cert *ssh.Certificate) error {
|
||||
|
@ -451,7 +461,7 @@ func (a *Authority) SignSSHAddUser(ctx context.Context, key ssh.PublicKey, subje
|
|||
}
|
||||
cert.Signature = sig
|
||||
|
||||
if err = a.db.StoreSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
||||
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
|
||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "signSSHAddUser: error storing certificate in db")
|
||||
}
|
||||
|
||||
|
|
|
@ -280,9 +280,15 @@ func (a *Authority) Rekey(oldCert *x509.Certificate, pk crypto.PublicKey) ([]*x5
|
|||
// `StoreCertificate(...*x509.Certificate) error` instead of just
|
||||
// `StoreCertificate(*x509.Certificate) error`.
|
||||
func (a *Authority) storeCertificate(fullchain []*x509.Certificate) error {
|
||||
if s, ok := a.db.(interface {
|
||||
type certificateChainStorer interface {
|
||||
StoreCertificateChain(...*x509.Certificate) error
|
||||
}); ok {
|
||||
}
|
||||
// Store certificate in linkedca
|
||||
if s, ok := a.adminDB.(certificateChainStorer); ok {
|
||||
return s.StoreCertificateChain(fullchain...)
|
||||
}
|
||||
// Store certificate in local db
|
||||
if s, ok := a.db.(certificateChainStorer); ok {
|
||||
return s.StoreCertificateChain(fullchain...)
|
||||
}
|
||||
return a.db.StoreCertificate(fullchain[0])
|
||||
|
@ -293,9 +299,15 @@ func (a *Authority) storeCertificate(fullchain []*x509.Certificate) error {
|
|||
//
|
||||
// TODO: at some point we should implement this in the standard implementation.
|
||||
func (a *Authority) storeRenewedCertificate(oldCert *x509.Certificate, fullchain []*x509.Certificate) error {
|
||||
if s, ok := a.db.(interface {
|
||||
type renewedCertificateChainStorer interface {
|
||||
StoreRenewedCertificate(*x509.Certificate, ...*x509.Certificate) error
|
||||
}); ok {
|
||||
}
|
||||
// Store certificate in linkedca
|
||||
if s, ok := a.adminDB.(renewedCertificateChainStorer); ok {
|
||||
return s.StoreRenewedCertificate(oldCert, fullchain...)
|
||||
}
|
||||
// Store certificate in local db
|
||||
if s, ok := a.db.(renewedCertificateChainStorer); ok {
|
||||
return s.StoreRenewedCertificate(oldCert, fullchain...)
|
||||
}
|
||||
return a.db.StoreCertificate(fullchain[0])
|
||||
|
|
2
go.mod
2
go.mod
|
@ -42,6 +42,6 @@ require (
|
|||
// replace github.com/smallstep/nosql => ../nosql
|
||||
// replace go.step.sm/crypto => ../crypto
|
||||
// replace go.step.sm/cli-utils => ../cli-utils
|
||||
// replace go.step.sm/linkedca => ../linkedca
|
||||
replace go.step.sm/linkedca => ../linkedca
|
||||
|
||||
replace go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 => github.com/omorsi/pkcs7 v0.0.0-20210217142924-a7b80a2a8568
|
||||
|
|
Loading…
Reference in a new issue