Skip to content

Commit

Permalink
Add MTLS to Static Binding (openconfig#1919)
Browse files Browse the repository at this point in the history
  • Loading branch information
mojiiba authored Jul 20, 2023
1 parent f4d2164 commit bbda851
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 12 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ require (
golang.org/x/text v0.10.0
google.golang.org/api v0.122.0
google.golang.org/grpc v1.56.0
google.golang.org/protobuf v1.30.0
google.golang.org/protobuf v1.31.0
gopkg.in/yaml.v2 v2.4.0
)

Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1703,6 +1703,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
33 changes: 33 additions & 0 deletions topologies/binding/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package binding
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"net"
"net/http"
Expand Down Expand Up @@ -75,6 +76,27 @@ type dialer struct {
*bindpb.Options
}

// load trust bundle and client key and certificate
func (d *dialer) loadCertificates() (*x509.CertPool, tls.Certificate, error) {
if d.CertFile == "" || d.KeyFile == "" || d.TrustBundleFile == "" {
return nil, tls.Certificate{}, fmt.Errorf("cert_file, key_file, and trust_bundle_file need to be set when mutual tls is set")
}
caCertBytes, err := os.ReadFile(d.TrustBundleFile)
if err != nil {
return nil, tls.Certificate{}, err
}
trusBundle := x509.NewCertPool()
if !trusBundle.AppendCertsFromPEM(caCertBytes) {
return nil, tls.Certificate{}, fmt.Errorf("error in loading ca trust bundle")
}
keyPair, err := tls.LoadX509KeyPair(d.CertFile, d.KeyFile)
if err != nil {
return nil, tls.Certificate{}, fmt.Errorf("could load the client keys")
}
return trusBundle, keyPair, nil

}

// dialGRPC dials a gRPC connection using the binding options.
//
//lint:ignore U1000 will be used by the binding.
Expand All @@ -86,6 +108,17 @@ func (d *dialer) dialGRPC(ctx context.Context, opts ...grpc.DialOption) (*grpc.C
case d.SkipVerify:
tc := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})
opts = append(opts, grpc.WithTransportCredentials(tc))
case d.MutualTls:
trusBundle, keyPair, err := d.loadCertificates()
if err != nil {
return nil, err
}
tls := &tls.Config{
Certificates: []tls.Certificate{keyPair},
RootCAs: trusBundle,
}
tlsConfig := credentials.NewTLS(tls)
opts = append(opts, grpc.WithTransportCredentials(tlsConfig))
}
if d.Username != "" {
c := &creds{d.Username, d.Password, !d.Insecure}
Expand Down
13 changes: 13 additions & 0 deletions topologies/proto/binding.proto
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,19 @@ message Options {

// gRPC dial option to set the maximum recv message size in bytes.
int32 max_recv_msg_size = 8;

// When using TLS, enable mutual certificate verification (gRPC)
bool mutual_tls = 9;

// Trust bundle file: a *.pem file that contains one or more certificates (root and intermediate CAs)
string trust_bundle_file = 10;

// Certificate file path : a *.pem file that is signed by root or intermediate CA
string cert_file = 11;

// Key file Path: a *.pem file that contains a private key
string key_file = 12;

}

// Port binding.
Expand Down
66 changes: 55 additions & 11 deletions topologies/proto/binding/binding.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit bbda851

Please sign in to comment.