Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions integration/benchmark/node/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,13 @@ func setupClient(tb testing.TB, confPath string) (*benchmark.ViewClient, error)
return nil, err
}

tlsEnabled := config.TLSConfig.Enabled
tlsRootCACert := path.Clean(config.TLSConfig.RootCACertPath)

cc := &grpc.ConnectionConfig{
Address: config.Address,
TLSEnabled: true,
TLSRootCertFile: path.Join(config.TLSConfig.PeerCACertPath),
TLSEnabled: tlsEnabled,
TLSRootCertFile: tlsRootCACert,
ConnectionTimeout: 10 * time.Second,
}

Expand Down
10 changes: 6 additions & 4 deletions integration/fsc/pingpong/pingpong_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ package pingpong_test
import (
"bytes"
"fmt"
"path"
"strings"
"time"

"github.com/hyperledger-labs/fabric-smart-client/integration"
"github.com/hyperledger-labs/fabric-smart-client/integration/fsc/pingpong"
"github.com/hyperledger-labs/fabric-smart-client/integration/fsc/pingpong/mock"
"github.com/hyperledger-labs/fabric-smart-client/integration/nwo/client"
"github.com/hyperledger-labs/fabric-smart-client/integration/nwo/common"
"github.com/hyperledger-labs/fabric-smart-client/integration/nwo/fsc"
"github.com/hyperledger-labs/fabric-smart-client/pkg/node"
Expand Down Expand Up @@ -62,15 +62,17 @@ var _ = Describe("EndToEnd", func() {

time.Sleep(3 * time.Second)

webClientConfig, err := client.NewWebClientConfigFromFSC("./testdata/fsc/nodes/initiator.0")
//webClientConfig, err := client.NewWebClientConfigFromFSC("./testdata/fsc/nodes/initiator.0")
webClientConfig, err := client2.ConfigFromFile(path.Join("./testdata/fsc/nodes/initiator.0", "client-config.yaml"))
Expect(err).NotTo(HaveOccurred())
initiatorWebClient, err := client2.NewClient(webClientConfig)
Expect(err).NotTo(HaveOccurred())
res, err := initiatorWebClient.CallView("init", bytes.NewBuffer([]byte("hi")).Bytes())
Expect(err).NotTo(HaveOccurred())
Expect(common.JSONUnmarshalString(res)).To(BeEquivalentTo("OK"))

webClientConfig.TLSCertPath = ""
// test client without TLS
webClientConfig.TLSConfig.Enabled = false
initiatorWebClient, err = client2.NewClient(webClientConfig)
Expect(err).NotTo(HaveOccurred())
_, err = initiatorWebClient.CallView("init", bytes.NewBuffer([]byte("hi")).Bytes())
Expand Down Expand Up @@ -315,7 +317,7 @@ func (s *TestSuite) TestGenerateAndMockPingPong() {
}

func newWebClient(confDir string) *client2.Client {
c, err := client.NewWebClientConfigFromFSC(confDir)
c, err := client2.ConfigFromFile(path.Join(confDir, "client-config.yaml"))
Expect(err).NotTo(HaveOccurred())
initiator, err := client2.NewClient(c)
Expect(err).NotTo(HaveOccurred())
Expand Down
8 changes: 7 additions & 1 deletion integration/fsc/stoprestart/stoprestart_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,13 @@ type TestSuite struct {

func NewTestSuite(commType fsc.P2PCommunicationType, nodeOpts *integration.ReplicationOptions) *TestSuite {
return &TestSuite{integration.NewTestSuite(func() (*integration.Infrastructure, error) {
return integration.Generate(StartPort(), integration.WithRaceDetection, stoprestart.Topology(commType, nodeOpts)...)
ii, err := integration.GenerateAt(StartPort(), "./out/testdata", integration.WithRaceDetection, stoprestart.Topology(commType, nodeOpts)...)
if err != nil {
return nil, err
}
ii.DeleteOnStart = true
ii.DeleteOnStop = false
return ii, nil
})}
}

Expand Down
33 changes: 0 additions & 33 deletions integration/nwo/client/web.go

This file was deleted.

22 changes: 14 additions & 8 deletions integration/nwo/fsc/fsc.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"time"

"github.com/hyperledger-labs/fabric-smart-client/integration/nwo/api"
"github.com/hyperledger-labs/fabric-smart-client/integration/nwo/client"
"github.com/hyperledger-labs/fabric-smart-client/integration/nwo/common"
runner2 "github.com/hyperledger-labs/fabric-smart-client/integration/nwo/common/runner"
"github.com/hyperledger-labs/fabric-smart-client/integration/nwo/fsc/commands"
Expand Down Expand Up @@ -151,13 +150,18 @@ func (p *Platform) GenerateArtifacts() {
p.GenerateRoutingConfig()
}

// TLS settings
var tlsConfig view2.TLSClientConfig
tlsConfig.RootCACertPath = path.Join(p.NodeLocalTLSDir(peer.Peer), "ca.crt")
tlsConfig.Enabled = len(tlsConfig.RootCACertPath) > 0

// TODO: note that NWO does not yet support mTLS
tlsConfig.ClientAuthRequired = p.ClientAuthRequired()

c := view2.Config{
Version: 0,
Address: p.PeerAddress(peer, ListenPort),
TLSConfig: view2.TLSConfig{
PeerCACertPath: path.Join(p.NodeLocalTLSDir(peer.Peer), "ca.crt"),
Timeout: 10 * time.Minute,
},
Version: 0,
Address: p.PeerAddress(peer, ListenPort),
TLSConfig: tlsConfig,
SignerConfig: view2.SignerConfig{
IdentityPath: p.LocalMSPIdentityCert(peer.Peer),
KeyPath: p.LocalMSPPrivateKey(peer.Peer),
Expand Down Expand Up @@ -344,7 +348,9 @@ func (p *Platform) PostRun(bool) {
}

// Web Client
webClientConfig, err := client.NewWebClientConfigFromFSC(p.NodeDir(node))
//webClientConfig, err := client.NewWebClientConfigFromFSC(p.NodeDir(node))
webClientConfig, err := client2.ConfigFromFile(path.Join(p.NodeDir(node), "client-config.yaml"))

gomega.Expect(err).NotTo(gomega.HaveOccurred())
webClient, err := client2.NewClient(webClientConfig)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
Expand Down
15 changes: 10 additions & 5 deletions integration/nwo/fsc/node/core_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ fsc:
# Private key used for TLS server
key:
file: {{ .NodeLocalTLSDir Peer }}/server.key
{{- if .ClientAuthRequired }}
# If mutual TLS is enabled, clientRootCAs.files contains a list of additional root certificates
# used for verifying certificates of client connections.
{{- if .ClientAuthRequired }}
clientRootCAs:
files:
- {{ .NodeLocalTLSDir Peer }}/ca.crt
Expand Down Expand Up @@ -122,20 +122,25 @@ fsc:
# HTTPS server listener address
address: 0.0.0.0:{{ .NodePort Replica "Web" }}
tls:
# Require server-side TLS
enabled: true
# Require client certificates / mutual TLS for inbound connections.
# Note that clients that are not configured to use a certificate will
# fail to connect to the node.
clientAuthRequired: {{ .ClientAuthRequired }}
# X.509 certificate used for TLS server
cert:
file: {{ .NodeLocalTLSDir Peer }}/server.crt
# Private key used for TLS server
key:
file: {{ .NodeLocalTLSDir Peer }}/server.key
# Require client certificates / mutual TLS for inbound connections.
# Note that clients that are not configured to use a certificate will
# fail to connect to the node.
clientAuthRequired: false
{{- if .ClientAuthRequired }}
# If mutual TLS is enabled, clientRootCAs.files contains a list of additional root certificates
# used for verifying certificates of client connections.
clientRootCAs:
files:
- {{ .NodeLocalTLSDir Peer }}/ca.crt
{{- end }}
tracing:
# Type of provider to be used: none (default), file, otlp, console
provider: {{ Topology.Monitoring.TracingType }}
Expand Down
44 changes: 36 additions & 8 deletions platform/view/services/view/grpc/client/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ package view

import (
"os"
"time"

"github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors"
"gopkg.in/yaml.v2"
Expand All @@ -20,19 +19,20 @@ type SignerConfig struct {
KeyPath string
}

// TLSConfig defines configuration of a Client
type TLSConfig struct {
CertPath string
KeyPath string
PeerCACertPath string
Timeout time.Duration
// TLSClientConfig defines configuration of a Client
type TLSClientConfig struct {
Enabled bool `yaml:"enabled"`
RootCACertPath string `yaml:"rootCACertPath,omitempty"`
ClientAuthRequired bool `yaml:"clientAuthRequired,omitempty"`
ClientCertPath string `yaml:"clientCertPath,omitempty"`
ClientKeyPath string `yaml:"clientKeyPath,omitempty"`
}

// Config aggregates configuration of TLS and signing
type Config struct {
Version int
Address string
TLSConfig TLSConfig
TLSConfig TLSClientConfig
SignerConfig SignerConfig
}

Expand Down Expand Up @@ -76,3 +76,31 @@ func validateConfig(conf Config) error {
}
return nil
}

func ValidateTLSConfig(config TLSClientConfig) error {
isEmpty := func(val string) bool {
return len(val) == 0
}

if !config.Enabled {
return nil
}

if isEmpty(config.RootCACertPath) {
return errors.New("rootCACertPath not set")
}

if !config.ClientAuthRequired {
return nil
}

if isEmpty(config.ClientKeyPath) {
return errors.New("clientKeyPath not set")
}

if isEmpty(config.ClientCertPath) {
return errors.New("ClientCertPath not set")
}

return nil
}
11 changes: 6 additions & 5 deletions platform/view/services/view/grpc/client/cmd/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ func TestConfig(t *testing.T) {
fmt.Println(configFilePath)
t.Run("save and load a config", func(t *testing.T) {
c := Config{
TLSConfig: TLSConfig{
CertPath: "foo",
KeyPath: "foo",
PeerCACertPath: "foo",
Timeout: time.Second * 3,
TLSConfig: TLSClientConfig{
Enabled: true,
ClientAuthRequired: true,
ClientCertPath: "foo",
ClientKeyPath: "foo",
RootCACertPath: "foo",
},
SignerConfig: SignerConfig{
KeyPath: "foo",
Expand Down
31 changes: 24 additions & 7 deletions platform/view/services/view/grpc/client/cmd/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,12 @@ func parseFlagsToConfig() Config {
IdentityPath: userCert,
KeyPath: userKey,
},
TLSConfig: TLSConfig{
KeyPath: tlsKey,
CertPath: tlsCert,
PeerCACertPath: tlsCA,
TLSConfig: TLSClientConfig{
Enabled: len(tlsCA) > 0,
RootCACertPath: tlsCA,
ClientAuthRequired: len(tlsCert) > 0 && len(tlsKey) > 0,
ClientCertPath: tlsCert,
ClientKeyPath: tlsKey,
},
}
return conf
Expand Down Expand Up @@ -145,10 +147,25 @@ func invoke() error {
return err
}

if err := ValidateTLSConfig(config.TLSConfig); err != nil {
return err
}

// parse TLS configuration
tlsEnabled := config.TLSConfig.Enabled
tlsRootCACert := path.Clean(config.TLSConfig.RootCACertPath)

// TODO:
// parse mTLS configuration
//mtlsEnabled := config.TLSConfig.ClientAuthRequired
//tlsClientCert := path.Clean(config.TLSConfig.ClientCertPath)
//tlsClientKey := path.Clean(config.TLSConfig.ClientKeyPath)

cc := &grpc.ConnectionConfig{
Address: config.Address,
TLSEnabled: true,
TLSRootCertFile: path.Join(config.TLSConfig.PeerCACertPath),
Address: config.Address,
TLSEnabled: tlsEnabled,
TLSRootCertFile: tlsRootCACert,
//TLSClientSideAuth: mtlsEnabled,
ConnectionTimeout: 10 * time.Second,
}

Expand Down
Loading
Loading