File: meter.go

package info (click to toggle)
golang-github-smallstep-certificates 0.28.4-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 6,676 kB
  • sloc: sh: 367; makefile: 129
file content (113 lines) | stat: -rw-r--r-- 3,996 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package authority

import (
	"crypto"
	"crypto/x509"
	"io"

	"go.step.sm/crypto/kms"
	kmsapi "go.step.sm/crypto/kms/apiv1"
	"golang.org/x/crypto/ssh"

	"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([]*x509.Certificate, provisioner.Interface, error)

	// X509Renewed is called whenever an X509 certificate is renewed.
	X509Renewed([]*x509.Certificate, provisioner.Interface, error)

	// X509Rekeyed is called whenever an X509 certificate is rekeyed.
	X509Rekeyed([]*x509.Certificate, provisioner.Interface, error)

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

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

	// SSHSigned is called whenever an SSH certificate is signed.
	SSHSigned(*ssh.Certificate, provisioner.Interface, error)

	// SSHRenewed is called whenever an SSH certificate is renewed.
	SSHRenewed(*ssh.Certificate, provisioner.Interface, error)

	// SSHRekeyed is called whenever an SSH certificate is rekeyed.
	SSHRekeyed(*ssh.Certificate, provisioner.Interface, error)

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

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

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

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

func (noopMeter) SSHRekeyed(*ssh.Certificate, provisioner.Interface, error)     {}
func (noopMeter) SSHRenewed(*ssh.Certificate, provisioner.Interface, error)     {}
func (noopMeter) SSHSigned(*ssh.Certificate, provisioner.Interface, error)      {}
func (noopMeter) SSHWebhookAuthorized(provisioner.Interface, error)             {}
func (noopMeter) SSHWebhookEnriched(provisioner.Interface, error)               {}
func (noopMeter) X509Rekeyed([]*x509.Certificate, provisioner.Interface, error) {}
func (noopMeter) X509Renewed([]*x509.Certificate, provisioner.Interface, error) {}
func (noopMeter) X509Signed([]*x509.Certificate, 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
}

type instrumentedKeyAndDecrypterManager struct {
	kms.KeyManager
	decrypter kmsapi.Decrypter
	meter     Meter
}

func newInstrumentedKeyManager(k kms.KeyManager, m Meter) kms.KeyManager {
	decrypter, isDecrypter := k.(kmsapi.Decrypter)
	switch {
	case isDecrypter:
		return &instrumentedKeyAndDecrypterManager{&instrumentedKeyManager{k, m}, decrypter, m}
	default:
		return &instrumentedKeyManager{k, m}
	}
}

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
}

func (i *instrumentedKeyAndDecrypterManager) CreateDecrypter(req *kmsapi.CreateDecrypterRequest) (s crypto.Decrypter, err error) {
	return i.decrypter.CreateDecrypter(req)
}

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
}

var _ kms.KeyManager = (*instrumentedKeyManager)(nil)
var _ kms.KeyManager = (*instrumentedKeyAndDecrypterManager)(nil)
var _ kmsapi.Decrypter = (*instrumentedKeyAndDecrypterManager)(nil)