86 lines
2.7 KiB
Go
86 lines
2.7 KiB
Go
|
package vault
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"crypto/ecdsa"
|
||
|
"crypto/tls"
|
||
|
"crypto/x509"
|
||
|
"fmt"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
clusterTLSServerLookup = func(ctx context.Context, c *Core, repClusters *ReplicatedClusters, _ *ReplicatedCluster) func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||
|
return func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||
|
c.logger.Debug("performing server cert lookup")
|
||
|
|
||
|
switch {
|
||
|
default:
|
||
|
currCert := c.localClusterCert.Load().([]byte)
|
||
|
if len(currCert) == 0 {
|
||
|
return nil, fmt.Errorf("got forwarding connection but no local cert")
|
||
|
}
|
||
|
|
||
|
localCert := make([]byte, len(currCert))
|
||
|
copy(localCert, currCert)
|
||
|
|
||
|
return &tls.Certificate{
|
||
|
Certificate: [][]byte{localCert},
|
||
|
PrivateKey: c.localClusterPrivateKey.Load().(*ecdsa.PrivateKey),
|
||
|
Leaf: c.localClusterParsedCert.Load().(*x509.Certificate),
|
||
|
}, nil
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
clusterTLSClientLookup = func(ctx context.Context, c *Core, repClusters *ReplicatedClusters, _ *ReplicatedCluster) func(*tls.CertificateRequestInfo) (*tls.Certificate, error) {
|
||
|
return func(requestInfo *tls.CertificateRequestInfo) (*tls.Certificate, error) {
|
||
|
if len(requestInfo.AcceptableCAs) != 1 {
|
||
|
return nil, fmt.Errorf("expected only a single acceptable CA")
|
||
|
}
|
||
|
|
||
|
currCert := c.localClusterCert.Load().([]byte)
|
||
|
if len(currCert) == 0 {
|
||
|
return nil, fmt.Errorf("forwarding connection client but no local cert")
|
||
|
}
|
||
|
|
||
|
localCert := make([]byte, len(currCert))
|
||
|
copy(localCert, currCert)
|
||
|
|
||
|
return &tls.Certificate{
|
||
|
Certificate: [][]byte{localCert},
|
||
|
PrivateKey: c.localClusterPrivateKey.Load().(*ecdsa.PrivateKey),
|
||
|
Leaf: c.localClusterParsedCert.Load().(*x509.Certificate),
|
||
|
}, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
clusterTLSServerConfigLookup = func(ctx context.Context, c *Core, repClusters *ReplicatedClusters, repCluster *ReplicatedCluster) func(clientHello *tls.ClientHelloInfo) (*tls.Config, error) {
|
||
|
return func(clientHello *tls.ClientHelloInfo) (*tls.Config, error) {
|
||
|
//c.logger.Trace("performing server config lookup")
|
||
|
|
||
|
caPool := x509.NewCertPool()
|
||
|
|
||
|
ret := &tls.Config{
|
||
|
ClientAuth: tls.RequireAndVerifyClientCert,
|
||
|
GetCertificate: clusterTLSServerLookup(ctx, c, repClusters, repCluster),
|
||
|
GetClientCertificate: clusterTLSClientLookup(ctx, c, repClusters, repCluster),
|
||
|
MinVersion: tls.VersionTLS12,
|
||
|
RootCAs: caPool,
|
||
|
ClientCAs: caPool,
|
||
|
NextProtos: clientHello.SupportedProtos,
|
||
|
CipherSuites: c.clusterCipherSuites,
|
||
|
}
|
||
|
|
||
|
parsedCert := c.localClusterParsedCert.Load().(*x509.Certificate)
|
||
|
|
||
|
if parsedCert == nil {
|
||
|
return nil, fmt.Errorf("forwarding connection client but no local cert")
|
||
|
}
|
||
|
|
||
|
caPool.AddCert(parsedCert)
|
||
|
|
||
|
return ret, nil
|
||
|
}
|
||
|
}
|
||
|
)
|