forked from TrueCloudLab/certificates
Implement revocation using linkedca.
This commit is contained in:
parent
81004ce1f9
commit
3f07eb597a
2 changed files with 69 additions and 2 deletions
|
@ -15,6 +15,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/certificates/db"
|
||||||
"go.step.sm/crypto/jose"
|
"go.step.sm/crypto/jose"
|
||||||
"go.step.sm/crypto/keyutil"
|
"go.step.sm/crypto/keyutil"
|
||||||
"go.step.sm/crypto/tlsutil"
|
"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")
|
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) {
|
func (c *linkedCaClient) IsRevoked(serial string) (bool, error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -281,6 +310,16 @@ func (c *linkedCaClient) IsSSHRevoked(serial string) (bool, error) {
|
||||||
return resp.Status != linkedca.RevocationStatus_ACTIVE, nil
|
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 {
|
func serializeCertificateChain(fullchain ...*x509.Certificate) string {
|
||||||
var chain string
|
var chain string
|
||||||
for _, crt := range fullchain {
|
for _, crt := range fullchain {
|
||||||
|
@ -292,6 +331,13 @@ func serializeCertificateChain(fullchain ...*x509.Certificate) string {
|
||||||
return chain
|
return chain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func serializeSSHCertificate(crt *ssh.Certificate) string {
|
||||||
|
if crt == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return string(ssh.MarshalAuthorizedKey(crt))
|
||||||
|
}
|
||||||
|
|
||||||
func getAuthority(sans []string) (string, error) {
|
func getAuthority(sans []string) (string, error) {
|
||||||
for _, s := range sans {
|
for _, s := range sans {
|
||||||
if strings.HasPrefix(s, "urn:smallstep:authority:") {
|
if strings.HasPrefix(s, "urn:smallstep:authority:") {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"go.step.sm/crypto/keyutil"
|
"go.step.sm/crypto/keyutil"
|
||||||
"go.step.sm/crypto/pemutil"
|
"go.step.sm/crypto/pemutil"
|
||||||
"go.step.sm/crypto/x509util"
|
"go.step.sm/crypto/x509util"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetTLSOptions returns the tls options configured.
|
// 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 {
|
if provisioner.MethodFromContext(ctx) == provisioner.SSHRevokeMethod {
|
||||||
err = a.db.RevokeSSH(rci)
|
err = a.revokeSSH(nil, rci)
|
||||||
} else {
|
} else {
|
||||||
// Revoke an X.509 certificate using CAS. If the certificate is not
|
// 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
|
// 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.
|
// Save as revoked in the Db.
|
||||||
err = a.db.Revoke(rci)
|
err = a.revoke(revokedCert, rci)
|
||||||
}
|
}
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
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.
|
// GetTLSCertificate creates a new leaf certificate to be used by the CA HTTPS server.
|
||||||
func (a *Authority) GetTLSCertificate() (*tls.Certificate, error) {
|
func (a *Authority) GetTLSCertificate() (*tls.Certificate, error) {
|
||||||
fatal := func(err error) (*tls.Certificate, error) {
|
fatal := func(err error) (*tls.Certificate, error) {
|
||||||
|
|
Loading…
Reference in a new issue