91 lines
2.3 KiB
Go
91 lines
2.3 KiB
Go
package controller
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"errors"
|
|
"net"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/boundary/internal/cmd/base"
|
|
wrapping "github.com/hashicorp/go-kms-wrapping"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
type workerAuthEntry struct {
|
|
*base.WorkerAuthInfo
|
|
conn net.Conn
|
|
}
|
|
|
|
func (c Controller) validateWorkerTLS(hello *tls.ClientHelloInfo) (*tls.Config, error) {
|
|
for _, p := range hello.SupportedProtos {
|
|
switch {
|
|
case strings.HasPrefix(p, "v1workerauth-"):
|
|
tlsConf, workerInfo, err := c.v1WorkerAuthConfig(hello.SupportedProtos)
|
|
if err == nil {
|
|
// Set the info we need to prevent replays
|
|
c.workerAuthCache.Set(workerInfo.ConnectionNonce, &workerAuthEntry{
|
|
WorkerAuthInfo: workerInfo,
|
|
}, 0)
|
|
}
|
|
return tlsConf, err
|
|
}
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (c Controller) v1WorkerAuthConfig(protos []string) (*tls.Config, *base.WorkerAuthInfo, error) {
|
|
var firstMatchProto string
|
|
var encString string
|
|
for _, p := range protos {
|
|
if strings.HasPrefix(p, "v1workerauth-") {
|
|
// Strip that and the number
|
|
encString += strings.TrimPrefix(p, "v1workerauth-")[3:]
|
|
if firstMatchProto == "" {
|
|
firstMatchProto = p
|
|
}
|
|
}
|
|
}
|
|
if firstMatchProto == "" {
|
|
return nil, nil, errors.New("no matching proto found")
|
|
}
|
|
marshaledEncInfo, err := base64.RawStdEncoding.DecodeString(encString)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
encInfo := new(wrapping.EncryptedBlobInfo)
|
|
if err := proto.Unmarshal(marshaledEncInfo, encInfo); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
marshaledInfo, err := c.conf.WorkerAuthKms.Decrypt(context.Background(), encInfo, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
info := new(base.WorkerAuthInfo)
|
|
if err := json.Unmarshal(marshaledInfo, info); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
rootCAs := x509.NewCertPool()
|
|
if ok := rootCAs.AppendCertsFromPEM(info.CACertPEM); !ok {
|
|
return nil, info, errors.New("unable to add ca cert to cert pool")
|
|
}
|
|
tlsCert, err := tls.X509KeyPair(info.CertPEM, info.KeyPEM)
|
|
if err != nil {
|
|
return nil, info, err
|
|
}
|
|
tlsConfig := &tls.Config{
|
|
Certificates: []tls.Certificate{tlsCert},
|
|
ClientCAs: rootCAs,
|
|
ClientAuth: tls.RequireAndVerifyClientCert,
|
|
NextProtos: []string{firstMatchProto},
|
|
MinVersion: tls.VersionTLS13,
|
|
}
|
|
tlsConfig.BuildNameToCertificate()
|
|
|
|
return tlsConfig, info, nil
|
|
}
|