Implement revocation using linkedca.

This commit is contained in:
Mariano Cano 2021-08-05 18:45:50 -07:00
parent 81004ce1f9
commit 3f07eb597a
2 changed files with 69 additions and 2 deletions

View file

@ -15,6 +15,7 @@ import (
"time"
"github.com/pkg/errors"
"github.com/smallstep/certificates/db"
"go.step.sm/crypto/jose"
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/tlsutil"
@ -257,6 +258,34 @@ func (c *linkedCaClient) StoreSSHCertificate(crt *ssh.Certificate) error {
return errors.Wrap(err, "error posting ssh certificate")
}
func (c *linkedCaClient) Revoke(crt *x509.Certificate, rci *db.RevokedCertificateInfo) error {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
_, err := c.client.RevokeCertificate(ctx, &linkedca.RevokeCertificateRequest{
Serial: rci.Serial,
PemCertificate: serializeCertificate(crt),
Reason: rci.Reason,
ReasonCode: linkedca.RevocationReasonCode(rci.ReasonCode),
Passive: true,
})
return errors.Wrap(err, "error revoking certificate")
}
func (c *linkedCaClient) RevokeSSH(ssh *ssh.Certificate, rci *db.RevokedCertificateInfo) error {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
_, err := c.client.RevokeSSHCertificate(ctx, &linkedca.RevokeSSHCertificateRequest{
Serial: rci.Serial,
Certificate: serializeSSHCertificate(ssh),
Reason: rci.Reason,
ReasonCode: linkedca.RevocationReasonCode(rci.ReasonCode),
Passive: true,
})
return errors.Wrap(err, "error revoking ssh certificate")
}
func (c *linkedCaClient) IsRevoked(serial string) (bool, error) {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
@ -281,6 +310,16 @@ func (c *linkedCaClient) IsSSHRevoked(serial string) (bool, error) {
return resp.Status != linkedca.RevocationStatus_ACTIVE, nil
}
func serializeCertificate(crt *x509.Certificate) string {
if crt == nil {
return ""
}
return string(pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: crt.Raw,
}))
}
func serializeCertificateChain(fullchain ...*x509.Certificate) string {
var chain string
for _, crt := range fullchain {
@ -292,6 +331,13 @@ func serializeCertificateChain(fullchain ...*x509.Certificate) string {
return chain
}
func serializeSSHCertificate(crt *ssh.Certificate) string {
if crt == nil {
return ""
}
return string(ssh.MarshalAuthorizedKey(crt))
}
func getAuthority(sans []string) (string, error) {
for _, s := range sans {
if strings.HasPrefix(s, "urn:smallstep:authority:") {

View file

@ -21,6 +21,7 @@ import (
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/pemutil"
"go.step.sm/crypto/x509util"
"golang.org/x/crypto/ssh"
)
// GetTLSOptions returns the tls options configured.
@ -397,7 +398,7 @@ func (a *Authority) Revoke(ctx context.Context, revokeOpts *RevokeOptions) error
}
if provisioner.MethodFromContext(ctx) == provisioner.SSHRevokeMethod {
err = a.db.RevokeSSH(rci)
err = a.revokeSSH(nil, rci)
} else {
// Revoke an X.509 certificate using CAS. If the certificate is not
// provided we will try to read it from the db. If the read fails we
@ -424,7 +425,7 @@ func (a *Authority) Revoke(ctx context.Context, revokeOpts *RevokeOptions) error
}
// Save as revoked in the Db.
err = a.db.Revoke(rci)
err = a.revoke(revokedCert, rci)
}
switch err {
case nil:
@ -439,6 +440,26 @@ func (a *Authority) Revoke(ctx context.Context, revokeOpts *RevokeOptions) error
}
}
func (a *Authority) revoke(crt *x509.Certificate, rci *db.RevokedCertificateInfo) error {
if lca, ok := a.adminDB.(interface {
Revoke(*x509.Certificate, *db.RevokedCertificateInfo) error
}); ok {
println(true)
return lca.Revoke(crt, rci)
}
println(false)
return a.db.Revoke(rci)
}
func (a *Authority) revokeSSH(crt *ssh.Certificate, rci *db.RevokedCertificateInfo) error {
if lca, ok := a.adminDB.(interface {
RevokeSSH(*ssh.Certificate, *db.RevokedCertificateInfo) error
}); ok {
return lca.RevokeSSH(crt, rci)
}
return a.db.Revoke(rci)
}
// GetTLSCertificate creates a new leaf certificate to be used by the CA HTTPS server.
func (a *Authority) GetTLSCertificate() (*tls.Certificate, error) {
fatal := func(err error) (*tls.Certificate, error) {