|
| 1 | +// Package main implements a Composition Function. |
| 2 | +package main |
| 3 | + |
| 4 | +import ( |
| 5 | + "crypto/tls" |
| 6 | + "crypto/x509" |
| 7 | + "os" |
| 8 | + "path/filepath" |
| 9 | + |
| 10 | + "github.com/crossplane/function-sdk-go" |
| 11 | + "github.com/pkg/errors" |
| 12 | + "google.golang.org/grpc/credentials" |
| 13 | +) |
| 14 | + |
| 15 | +// mtlsCertificates returns a ServeOption that configures mTLS using certificates |
| 16 | +// loaded from the given directory. Unlike the SDK's function.MTLSCertificates, |
| 17 | +// this allows configuring the certificate filenames to support emissary-provided |
| 18 | +// TLS certs (https://datadoghq.atlassian.net/wiki/spaces/RPC/pages/4745232414). |
| 19 | +func mtlsCertificates(dir, caCertFile, certFile, keyFile string) function.ServeOption { |
| 20 | + return func(o *function.ServeOptions) error { |
| 21 | + if dir == "" { |
| 22 | + return nil |
| 23 | + } |
| 24 | + |
| 25 | + crt, err := tls.LoadX509KeyPair( |
| 26 | + filepath.Join(dir, certFile), |
| 27 | + filepath.Join(dir, keyFile), |
| 28 | + ) |
| 29 | + if err != nil { |
| 30 | + return errors.Wrap(err, "cannot load X509 keypair") |
| 31 | + } |
| 32 | + |
| 33 | + ca, err := os.ReadFile(filepath.Clean(filepath.Join(dir, caCertFile))) |
| 34 | + if err != nil { |
| 35 | + return errors.Wrap(err, "cannot read CA certificate") |
| 36 | + } |
| 37 | + |
| 38 | + pool := x509.NewCertPool() |
| 39 | + if !pool.AppendCertsFromPEM(ca) { |
| 40 | + return errors.New("invalid CA certificate") |
| 41 | + } |
| 42 | + |
| 43 | + o.Credentials = credentials.NewTLS(&tls.Config{ |
| 44 | + MinVersion: tls.VersionTLS12, |
| 45 | + Certificates: []tls.Certificate{crt}, |
| 46 | + ClientCAs: pool, |
| 47 | + ClientAuth: tls.RequireAndVerifyClientCert, |
| 48 | + }) |
| 49 | + |
| 50 | + return nil |
| 51 | + } |
| 52 | +} |
0 commit comments