Skip to content

Commit

Permalink
reworked meter signature
Browse files Browse the repository at this point in the history
  • Loading branch information
azazeal committed Jan 23, 2024
1 parent ecf2da6 commit 93f7932
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 121 deletions.
48 changes: 0 additions & 48 deletions authority/authority.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"io"
"log"
"net/http"
"strings"
Expand Down Expand Up @@ -972,50 +971,3 @@ func (a *Authority) startCRLGenerator() error {

return nil
}

//nolint:gocritic // used in defered statements
func (a *Authority) incrProvisionerCounter(prov *provisioner.Interface, err *error, count func(Meter, string, bool)) {
var name string
if p := *prov; p != nil {
name = p.GetName()
}

count(a.meter, name, *err == nil)
}

func (a *Authority) incrWebhookCounter(prov provisioner.Interface, err error, count func(Meter, string, bool)) {
var name string
if prov != nil {
name = prov.GetName()
}

count(a.meter, name, err == nil)
}

type instrumentedKeyManager struct {
kms.KeyManager
meter Meter
}

func (i *instrumentedKeyManager) CreateSigner(req *kmsapi.CreateSignerRequest) (s crypto.Signer, err error) {
if s, err = i.KeyManager.CreateSigner(req); err == nil {
s = &instrumentedKMSSigner{s, i.meter}
}

return
}

type instrumentedKMSSigner struct {
crypto.Signer
meter Meter
}

func (i *instrumentedKMSSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
if signature, err = i.Signer.Sign(rand, digest, opts); err != nil {
i.meter.KMSError()
} else {
i.meter.KMSSigned()
}

return
}
83 changes: 57 additions & 26 deletions authority/meter.go
Original file line number Diff line number Diff line change
@@ -1,56 +1,87 @@
package authority

import (
"crypto"
"io"

"go.step.sm/crypto/kms"
kmsapi "go.step.sm/crypto/kms/apiv1"

"github.com/smallstep/certificates/authority/provisioner"
)

// Meter wraps the set of defined callbacks for metrics gatherers.
type Meter interface {
// X509Signed is called whenever an X509 certificate is signed.
X509Signed(provisioner string, success bool)
X509Signed(provisioner.Interface, error)

// X509Renewed is called whenever an X509 certificate is renewed.
X509Renewed(provisioner string, success bool)
X509Renewed(provisioner.Interface, error)

// X509Rekeyed is called whenever an X509 certificate is rekeyed.
X509Rekeyed(provisioner string, success bool)
X509Rekeyed(provisioner.Interface, error)

// X509WebhookAuthorized is called whenever an X509 authoring webhook is called.
X509WebhookAuthorized(provisioner string, success bool)
X509WebhookAuthorized(provisioner.Interface, error)

// X509WebhookEnriched is called whenever an X509 enriching webhook is called.
X509WebhookEnriched(provisioner string, success bool)
X509WebhookEnriched(provisioner.Interface, error)

// SSHSigned is called whenever an SSH certificate is signed.
SSHSigned(provisioner string, success bool)
SSHSigned(provisioner.Interface, error)

// SSHRenewed is called whenever an SSH certificate is renewed.
SSHRenewed(provisioner string, success bool)
SSHRenewed(provisioner.Interface, error)

// SSHRekeyed is called whenever an SSH certificate is rekeyed.
SSHRekeyed(provisioner string, success bool)
SSHRekeyed(provisioner.Interface, error)

// SSHWebhookAuthorized is called whenever an SSH authoring webhook is called.
SSHWebhookAuthorized(provisioner string, success bool)
SSHWebhookAuthorized(provisioner.Interface, error)

// SSHWebhookEnriched is called whenever an SSH enriching webhook is called.
SSHWebhookEnriched(provisioner string, success bool)
SSHWebhookEnriched(provisioner.Interface, error)

// KMSSigned is called per KMS signer signature.
KMSSigned()

// KMSSigned is called per KMS signer signature error.
KMSError()
KMSSigned(error)
}

// noopMeter implements a noop [Meter].
type noopMeter struct{}

func (noopMeter) SSHRekeyed(string, bool) {}
func (noopMeter) SSHRenewed(string, bool) {}
func (noopMeter) SSHSigned(string, bool) {}
func (noopMeter) SSHWebhookAuthorized(string, bool) {}
func (noopMeter) SSHWebhookEnriched(string, bool) {}
func (noopMeter) X509Rekeyed(string, bool) {}
func (noopMeter) X509Renewed(string, bool) {}
func (noopMeter) X509Signed(string, bool) {}
func (noopMeter) X509WebhookAuthorized(string, bool) {}
func (noopMeter) X509WebhookEnriched(string, bool) {}
func (noopMeter) KMSSigned() {}
func (noopMeter) KMSError() {}
func (noopMeter) SSHRekeyed(provisioner.Interface, error) {}
func (noopMeter) SSHRenewed(provisioner.Interface, error) {}
func (noopMeter) SSHSigned(provisioner.Interface, error) {}
func (noopMeter) SSHWebhookAuthorized(provisioner.Interface, error) {}
func (noopMeter) SSHWebhookEnriched(provisioner.Interface, error) {}
func (noopMeter) X509Rekeyed(provisioner.Interface, error) {}
func (noopMeter) X509Renewed(provisioner.Interface, error) {}
func (noopMeter) X509Signed(provisioner.Interface, error) {}
func (noopMeter) X509WebhookAuthorized(provisioner.Interface, error) {}
func (noopMeter) X509WebhookEnriched(provisioner.Interface, error) {}
func (noopMeter) KMSSigned(error) {}

type instrumentedKeyManager struct {
kms.KeyManager
meter Meter
}

func (i *instrumentedKeyManager) CreateSigner(req *kmsapi.CreateSignerRequest) (s crypto.Signer, err error) {
if s, err = i.KeyManager.CreateSigner(req); err == nil {
s = &instrumentedKMSSigner{s, i.meter}
}

return
}

type instrumentedKMSSigner struct {
crypto.Signer
meter Meter
}

func (i *instrumentedKMSSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
signature, err = i.Signer.Sign(rand, digest, opts)
i.meter.KMSSigned(err)

return
}
10 changes: 5 additions & 5 deletions authority/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func (a *Authority) GetSSHBastion(ctx context.Context, user, hostname string) (*
// SignSSH creates a signed SSH certificate with the given public key and options.
func (a *Authority) SignSSH(_ context.Context, key ssh.PublicKey, opts provisioner.SignSSHOptions, signOpts ...provisioner.SignOption) (cert *ssh.Certificate, err error) {
var prov provisioner.Interface
defer a.incrProvisionerCounter(&prov, &err, Meter.SSHSigned)
defer func() { a.meter.SSHSigned(prov, err) }()

var (
certOptions []sshutil.Option
Expand Down Expand Up @@ -345,7 +345,7 @@ func (a *Authority) isAllowedToSignSSHCertificate(cert *ssh.Certificate) error {
// RenewSSH creates a signed SSH certificate using the old SSH certificate as a template.
func (a *Authority) RenewSSH(ctx context.Context, oldCert *ssh.Certificate) (cert *ssh.Certificate, err error) {
var prov provisioner.Interface
defer a.incrProvisionerCounter(&prov, &err, Meter.SSHRenewed)
defer func() { a.meter.SSHRenewed(prov, err) }()

if oldCert.ValidAfter == 0 || oldCert.ValidBefore == 0 {
err = errs.BadRequest("cannot renew a certificate without validity period")
Expand Down Expand Up @@ -426,7 +426,7 @@ func (a *Authority) RenewSSH(ctx context.Context, oldCert *ssh.Certificate) (cer
// RekeySSH creates a signed SSH certificate using the old SSH certificate as a template.
func (a *Authority) RekeySSH(ctx context.Context, oldCert *ssh.Certificate, pub ssh.PublicKey, signOpts ...provisioner.SignOption) (cert *ssh.Certificate, err error) {
var prov provisioner.Interface
defer a.incrProvisionerCounter(&prov, &err, Meter.SSHRekeyed)
defer func() { a.meter.SSHRekeyed(prov, err) }()

var validators []provisioner.SSHCertValidator

Expand Down Expand Up @@ -733,7 +733,7 @@ func (a *Authority) callEnrichingWebhooksSSH(prov provisioner.Interface, webhook
); err == nil {
err = webhookCtl.Enrich(whEnrichReq)

a.incrWebhookCounter(prov, err, Meter.SSHWebhookEnriched)
a.meter.SSHWebhookEnriched(prov, err)
}

return
Expand All @@ -750,7 +750,7 @@ func (a *Authority) callAuthorizingWebhooksSSH(prov provisioner.Interface, webho
); err == nil {
err = webhookCtl.Authorize(whAuthBody)

a.incrWebhookCounter(prov, err, Meter.SSHWebhookAuthorized)
a.meter.SSHWebhookAuthorized(prov, err)
}

return
Expand Down
10 changes: 5 additions & 5 deletions authority/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func withDefaultASN1DN(def *config.ASN1DN) provisioner.CertificateModifierFunc {
// Sign creates a signed certificate from a certificate signing request.
func (a *Authority) Sign(csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) (cert []*x509.Certificate, err error) {
var prov provisioner.Interface
defer a.incrProvisionerCounter(&prov, &err, Meter.X509Signed)
defer func() { a.meter.X509Signed(prov, err) }()

var (
certOptions []x509util.Option
Expand Down Expand Up @@ -374,9 +374,9 @@ func (a *Authority) Rekey(oldCert *x509.Certificate, pk crypto.PublicKey) ([]*x5
func (a *Authority) RenewContext(ctx context.Context, oldCert *x509.Certificate, pk crypto.PublicKey) (cert []*x509.Certificate, err error) {
var prov provisioner.Interface
if pk == nil {
defer a.incrProvisionerCounter(&prov, &err, Meter.X509Renewed)
defer func() { a.meter.X509Renewed(prov, err) }()
} else {
defer a.incrProvisionerCounter(&prov, &err, Meter.X509Rekeyed)
defer func() { a.meter.X509Rekeyed(prov, err) }()
}

isRekey := (pk != nil)
Expand Down Expand Up @@ -1024,7 +1024,7 @@ func (a *Authority) callEnrichingWebhooksX509(prov provisioner.Interface, webhoo
); err == nil {
err = webhookCtl.Enrich(whEnrichReq)

a.incrWebhookCounter(prov, err, Meter.X509WebhookEnriched)
a.meter.X509WebhookEnriched(prov, err)
}

return
Expand All @@ -1049,7 +1049,7 @@ func (a *Authority) callAuthorizingWebhooksX509(prov provisioner.Interface, webh
); err == nil {
err = webhookCtl.Authorize(whAuthBody)

a.incrWebhookCounter(prov, err, Meter.X509WebhookAuthorized)
a.meter.X509WebhookAuthorized(prov, err)
}

return
Expand Down
Loading

0 comments on commit 93f7932

Please sign in to comment.