Files
Gábor Farkas ecd6de826a Postgres: Switch the datasource plugin from lib/pq to pgx (#83768)
postgres: switch from lib/pq to pgx
2024-03-13 09:52:39 +01:00

102 lines
2.4 KiB
Go

package tls
import (
"crypto/tls"
"crypto/x509"
"errors"
"github.com/grafana/grafana/pkg/tsdb/sqleng"
)
// this file deals with locating and loading the certificates,
// from json-data or from disk.
type CertBytes struct {
rootCert []byte
clientKey []byte
clientCert []byte
}
type ReadFileFunc = func(name string) ([]byte, error)
var errPartialClientCertNoKey = errors.New("tls: client cert provided but client key missing")
var errPartialClientCertNoCert = errors.New("tls: client key provided but client cert missing")
// certificates can be stored either as encrypted-json-data, or as file-path
func loadCertificateBytes(dsInfo sqleng.DataSourceInfo, readFile ReadFileFunc) (*CertBytes, error) {
if dsInfo.JsonData.ConfigurationMethod == "file-content" {
return &CertBytes{
rootCert: []byte(dsInfo.DecryptedSecureJSONData["tlsCACert"]),
clientKey: []byte(dsInfo.DecryptedSecureJSONData["tlsClientKey"]),
clientCert: []byte(dsInfo.DecryptedSecureJSONData["tlsClientCert"]),
}, nil
} else {
c := CertBytes{}
if dsInfo.JsonData.RootCertFile != "" {
rootCert, err := readFile(dsInfo.JsonData.RootCertFile)
if err != nil {
return nil, err
}
c.rootCert = rootCert
}
if dsInfo.JsonData.CertKeyFile != "" {
clientKey, err := readFile(dsInfo.JsonData.CertKeyFile)
if err != nil {
return nil, err
}
c.clientKey = clientKey
}
if dsInfo.JsonData.CertFile != "" {
clientCert, err := readFile(dsInfo.JsonData.CertFile)
if err != nil {
return nil, err
}
c.clientCert = clientCert
}
return &c, nil
}
}
type Certs struct {
clientCerts []tls.Certificate
rootCerts *x509.CertPool
}
func createCertificates(certBytes *CertBytes) (*Certs, error) {
certs := Certs{}
if len(certBytes.rootCert) > 0 {
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM(certBytes.rootCert)
if !ok {
return nil, errors.New("tls: failed to add root certificate")
}
certs.rootCerts = pool
}
hasClientKey := len(certBytes.clientKey) > 0
hasClientCert := len(certBytes.clientCert) > 0
if hasClientKey && hasClientCert {
cert, err := tls.X509KeyPair(certBytes.clientCert, certBytes.clientKey)
if err != nil {
return nil, err
}
certs.clientCerts = []tls.Certificate{cert}
}
if hasClientKey && (!hasClientCert) {
return nil, errPartialClientCertNoCert
}
if hasClientCert && (!hasClientKey) {
return nil, errPartialClientCertNoKey
}
return &certs, nil
}