11
"google.golang.org/protobuf/types/known/wrapperspb"
13
"github.com/kumahq/kuma/pkg/core/resources/apis/system"
14
"github.com/kumahq/kuma/pkg/core/resources/manager"
15
"github.com/kumahq/kuma/pkg/core/resources/model"
16
"github.com/kumahq/kuma/pkg/core/resources/store"
17
util_tls "github.com/kumahq/kuma/pkg/tls"
21
ClientCertSAN = "kuma-cp"
24
var GlobalSecretKey = model.ResourceKey{
25
Name: "envoy-admin-ca",
28
// GenerateCA generates CA for Envoy Admin communication (CP sending requests to Envoy Admin).
29
// While we could reuse CA from enable mTLS backend on a Mesh object there are two problems
30
// 1. mTLS on Mesh can be disabled and Envoy Admin communication needs security in place.
31
// Otherwise, malicious actor could execute /quitquitquit endpoint and perform DDoS
32
// 2. ZoneIngress and ZoneEgress are not scoped to a Mesh.
34
// To solve this we need at least self-signed client certificate for the control plane.
35
// But we can just as well have a CA and generate client and server certs from it.
37
// Rotation: users can change the CA. To do this, they can swap the secret and restart all instances of the CP.
38
// Multizone: CA is generated for every zone. There is no need for it to be stable.
39
func GenerateCA() (*util_tls.KeyPair, error) {
41
Organization: []string{"Kuma"},
42
OrganizationalUnit: []string{"Mesh"},
43
CommonName: "Envoy Admin CA",
45
return util_tls.GenerateCA(util_tls.DefaultKeyType, subject)
48
func LoadCA(ctx context.Context, resManager manager.ReadOnlyResourceManager) (tls.Certificate, error) {
49
globalSecret := system.NewGlobalSecretResource()
50
if err := resManager.Get(ctx, globalSecret, store.GetBy(GlobalSecretKey)); err != nil {
51
return tls.Certificate{}, err
53
bytes := globalSecret.Spec.GetData().GetValue()
54
certBlock, rest := pem.Decode(bytes)
55
keyBlock, _ := pem.Decode(rest)
56
return tls.X509KeyPair(pem.EncodeToMemory(certBlock), pem.EncodeToMemory(keyBlock))
59
func CreateCA(ctx context.Context, keyPair util_tls.KeyPair, resManager manager.ResourceManager) error {
60
bytes := append(keyPair.CertPEM, keyPair.KeyPEM...)
61
globalSecret := system.NewGlobalSecretResource()
62
globalSecret.Spec.Data = &wrapperspb.BytesValue{
65
return resManager.Create(ctx, globalSecret, store.CreateBy(GlobalSecretKey))
68
func GenerateClientCert(ca tls.Certificate) (util_tls.KeyPair, error) {
69
rootCert, err := x509.ParseCertificate(ca.Certificate[0])
71
return util_tls.KeyPair{}, err
73
return util_tls.NewCert(*rootCert, ca.PrivateKey.(*rsa.PrivateKey), util_tls.ClientCertType, util_tls.DefaultKeyType, ClientCertSAN)
76
func GenerateServerCert(ca tls.Certificate, hosts ...string) (util_tls.KeyPair, error) {
77
rootCert, err := x509.ParseCertificate(ca.Certificate[0])
79
return util_tls.KeyPair{}, err
81
return util_tls.NewCert(*rootCert, ca.PrivateKey.(*rsa.PrivateKey), util_tls.ServerCertType, util_tls.DefaultKeyType, hosts...)