forked from kyma-project/kyma
-
Notifications
You must be signed in to change notification settings - Fork 0
/
provider.go
113 lines (87 loc) · 3.09 KB
/
provider.go
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 certificates
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"k8s.io/apimachinery/pkg/types"
"github.com/kyma-project/kyma/components/connectivity-certs-controller/internal/secrets"
"github.com/pkg/errors"
)
type Provider interface {
GetClientCredentials() (*rsa.PrivateKey, *x509.Certificate, error)
GetCACertificates() ([]*x509.Certificate, error)
}
type certificateProvider struct {
clusterCertSecretName types.NamespacedName
caCertSecretName types.NamespacedName
secretsRepository secrets.Repository
}
func NewCertificateProvider(clusterCertSecretName types.NamespacedName, caCertSecretName types.NamespacedName, secretsRepository secrets.Repository) Provider {
return &certificateProvider{
secretsRepository: secretsRepository,
caCertSecretName: caCertSecretName,
clusterCertSecretName: clusterCertSecretName,
}
}
func (cp *certificateProvider) GetCACertificates() ([]*x509.Certificate, error) {
secretData, err := cp.secretsRepository.Get(cp.caCertSecretName)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("Failed to read %s secret with certificates", cp.clusterCertSecretName))
}
caCerts, err := decodeCertificates(secretData[caCertificateSecretKey])
if err != nil {
return nil, errors.Wrap(err, "Failed to read client certificate")
}
return caCerts, nil
}
func (cp *certificateProvider) GetClientCredentials() (*rsa.PrivateKey, *x509.Certificate, error) {
secretData, err := cp.secretsRepository.Get(cp.clusterCertSecretName)
if err != nil {
return nil, nil, errors.Wrap(err, fmt.Sprintf("Failed to read %s secret with certificates", cp.clusterCertSecretName))
}
clientCert, err := decodeCertificate(secretData[clusterCertificateSecretKey])
if err != nil {
return nil, nil, errors.Wrap(err, "Failed to read client certificate")
}
clientKey, err := getClientPrivateKey(secretData[clusterKeySecretKey])
if err != nil {
return nil, nil, errors.Wrap(err, "Failed to read client key")
}
return clientKey, clientCert, nil
}
func decodeCertificate(certificate []byte) (*x509.Certificate, error) {
certs, err := decodeCertificates(certificate)
if err != nil {
return nil, err
}
return certs[0], nil
}
func decodeCertificates(certificate []byte) ([]*x509.Certificate, error) {
if certificate == nil {
return nil, errors.New("Certificate data is empty")
}
var certificates []*x509.Certificate
for block, rest := pem.Decode(certificate); block != nil && rest != nil; {
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, errors.Wrap(err, "Failed to decode one of the pem blocks")
}
certificates = append(certificates, cert)
block, rest = pem.Decode(rest)
}
if len(certificates) == 0 {
return nil, errors.New("No certificates found in the pem block")
}
return certificates, nil
}
func getClientPrivateKey(clusterKey []byte) (*rsa.PrivateKey, error) {
if clusterKey == nil {
return nil, errors.New("Private key data is empty")
}
block, _ := pem.Decode(clusterKey)
if block == nil {
return nil, errors.New("Failed to decode client key pem")
}
return x509.ParsePKCS1PrivateKey(block.Bytes)
}