* [COMPLIANCE] Update Copyright and License Headers * chore: make gen to generate files with copyright headers * chore: update missed copyright headers --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Co-authored-by: Justin Nguyen <justin.nguyen@hashicorp.com>
73 lines
2.1 KiB
Go
73 lines
2.1 KiB
Go
// Copyright IBM Corp. 2020, 2025
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package connect
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
|
|
targetspb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/targets"
|
|
)
|
|
|
|
// ClientTlsConfig creates a TLS configuration from the session authorization
|
|
// data and host
|
|
func ClientTlsConfig(sessionAuthzData *targetspb.SessionAuthorizationData, host string) (*tls.Config, error) {
|
|
const op = "connect.ClientTlsConfig"
|
|
if sessionAuthzData == nil {
|
|
return nil, fmt.Errorf("%s: nil session authorization data", op)
|
|
}
|
|
parsedCert, err := x509.ParseCertificate(sessionAuthzData.Certificate)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to decode mTLS certificate: %w", err)
|
|
}
|
|
|
|
certPool := x509.NewCertPool()
|
|
certPool.AddCert(parsedCert)
|
|
|
|
tlsConf := &tls.Config{
|
|
Certificates: []tls.Certificate{
|
|
{
|
|
Certificate: [][]byte{sessionAuthzData.Certificate},
|
|
PrivateKey: ed25519.PrivateKey(sessionAuthzData.PrivateKey),
|
|
Leaf: parsedCert,
|
|
},
|
|
},
|
|
ServerName: host,
|
|
MinVersion: tls.VersionTLS13,
|
|
NextProtos: []string{"http/1.1", sessionAuthzData.SessionId},
|
|
|
|
// This is set this way so we can make use of VerifyConnection, which we
|
|
// set on this TLS config below. We are not skipping verification!
|
|
InsecureSkipVerify: true,
|
|
}
|
|
if host == "" {
|
|
tlsConf.ServerName = parsedCert.DNSNames[0]
|
|
}
|
|
|
|
// We disable normal DNS SAN behavior as we don't rely on DNS or IP
|
|
// addresses for security and want to avoid issues with including localhost
|
|
// etc.
|
|
verifyOpts := x509.VerifyOptions{
|
|
DNSName: sessionAuthzData.SessionId,
|
|
Roots: certPool,
|
|
KeyUsages: []x509.ExtKeyUsage{
|
|
x509.ExtKeyUsageClientAuth,
|
|
x509.ExtKeyUsageServerAuth,
|
|
},
|
|
}
|
|
tlsConf.VerifyConnection = func(cs tls.ConnectionState) error {
|
|
// Go will not run this without at least one peer certificate, but
|
|
// doesn't hurt to check
|
|
if len(cs.PeerCertificates) == 0 {
|
|
return fmt.Errorf("%s: no peer certificates provided", op)
|
|
}
|
|
_, err := cs.PeerCertificates[0].Verify(verifyOpts)
|
|
return err
|
|
}
|
|
|
|
return tlsConf, nil
|
|
}
|