Skip to content

Commit

Permalink
FAB-17228 External cc clients/servers use consistent key/cert model (#…
Browse files Browse the repository at this point in the history
…407)

Consistently provide PEM encoded certificates/keys instead of paths
to files.

Signed-off-by: Will Lahti <wtlahti@us.ibm.com>
  • Loading branch information
wlahti authored and muralisrini committed Dec 14, 2019
1 parent b3ac630 commit f0ef0b5
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 90 deletions.
49 changes: 18 additions & 31 deletions core/container/externalbuilder/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ package externalbuilder

import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"os/exec"
Expand Down Expand Up @@ -69,63 +68,51 @@ func (d *Duration) UnmarshalJSON(b []byte) error {
type ChaincodeServerUserData struct {
Address string `json:"address"`
DialTimeout Duration `json:"dial_timeout"`
TlsRequired bool `json:"tls_required"`
TLSRequired bool `json:"tls_required"`
ClientAuthRequired bool `json:"client_auth_required"`
KeyPath string `json:"key_path"`
CertPath string `json:"cert_path"`
RootCertPath string `json:"root_cert_path"`
ClientKey string `json:"client_key"` // PEM encoded client key
ClientCert string `json:"client_cert"` // PEM encoded client certificate
RootCert string `json:"root_cert"` // PEM encoded peer chaincode certificate

}

func (ccdata *ChaincodeServerUserData) ChaincodeServerInfo(cryptoDir string) (*ccintf.ChaincodeServerInfo, error) {
if ccdata.Address == "" {
func (c *ChaincodeServerUserData) ChaincodeServerInfo(cryptoDir string) (*ccintf.ChaincodeServerInfo, error) {
if c.Address == "" {
return nil, errors.New("chaincode address not provided")
}
connInfo := &ccintf.ChaincodeServerInfo{Address: ccdata.Address}
connInfo := &ccintf.ChaincodeServerInfo{Address: c.Address}

if ccdata.DialTimeout == (Duration{}) {
if c.DialTimeout == (Duration{}) {
connInfo.ClientConfig.Timeout = DialTimeout
} else {
connInfo.ClientConfig.Timeout = ccdata.DialTimeout.Duration
connInfo.ClientConfig.Timeout = c.DialTimeout.Duration
}

// we can expose this if necessary
connInfo.ClientConfig.KaOpts = comm.DefaultKeepaliveOptions

if !ccdata.TlsRequired {
if !c.TLSRequired {
return connInfo, nil
}
if ccdata.ClientAuthRequired && ccdata.KeyPath == "" {
if c.ClientAuthRequired && c.ClientKey == "" {
return nil, errors.New("chaincode tls key not provided")
}
if ccdata.ClientAuthRequired && ccdata.CertPath == "" {
if c.ClientAuthRequired && c.ClientCert == "" {
return nil, errors.New("chaincode tls cert not provided")
}
if ccdata.RootCertPath == "" {
if c.RootCert == "" {
return nil, errors.New("chaincode tls root cert not provided")
}

connInfo.ClientConfig.SecOpts.UseTLS = true

if ccdata.ClientAuthRequired {
if c.ClientAuthRequired {
connInfo.ClientConfig.SecOpts.RequireClientCert = true
b, err := ioutil.ReadFile(filepath.Join(cryptoDir, ccdata.CertPath))
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("error reading cert file %s", ccdata.CertPath))
}
connInfo.ClientConfig.SecOpts.Certificate = b

b, err = ioutil.ReadFile(filepath.Join(cryptoDir, ccdata.KeyPath))
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("error reading key file %s", ccdata.KeyPath))
}
connInfo.ClientConfig.SecOpts.Key = b
connInfo.ClientConfig.SecOpts.Certificate = []byte(c.ClientCert)
connInfo.ClientConfig.SecOpts.Key = []byte(c.ClientKey)
}

b, err := ioutil.ReadFile(filepath.Join(cryptoDir, ccdata.RootCertPath))
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("error reading root cert file %s", ccdata.RootCertPath))
}
connInfo.ClientConfig.SecOpts.ServerRootCAs = [][]byte{b}
connInfo.ClientConfig.SecOpts.ServerRootCAs = [][]byte{[]byte(c.RootCert)}

return connInfo, nil
}
Expand Down
77 changes: 18 additions & 59 deletions core/container/externalbuilder/instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,10 @@ var _ = Describe("Instance", func() {

err = os.MkdirAll(filepath.Join(instance.ReleaseDir, "chaincode", "server"), 0755)
Expect(err).NotTo(HaveOccurred())
//initiaze with a well-formed, all fields set, connection.json file
ccdata := `{"address": "ccaddress:12345", "tls_required": true, "dial_timeout": "10s", "client_auth_required": true, "key_path": "key.pem", "cert_path": "cert.pem", "root_cert_path": "root.pem"}`
// initialize with a well-formed, all fields set, connection.json file
ccdata := `{"address": "ccaddress:12345", "tls_required": true, "dial_timeout": "10s", "client_auth_required": true, "client_key": "fake-key", "client_cert": "fake-cert", "root_cert": "fake-root-cert"}`
err = ioutil.WriteFile(filepath.Join(instance.ChaincodeServerReleaseDir(), "connection.json"), []byte(ccdata), 0600)
Expect(err).NotTo(HaveOccurred())
err = ioutil.WriteFile(filepath.Join(instance.ChaincodeServerReleaseDir(), "key.pem"), []byte("fake-key"), 0600)
Expect(err).NotTo(HaveOccurred())
err = ioutil.WriteFile(filepath.Join(instance.ChaincodeServerReleaseDir(), "cert.pem"), []byte("fake-cert"), 0600)
Expect(err).NotTo(HaveOccurred())
err = ioutil.WriteFile(filepath.Join(instance.ChaincodeServerReleaseDir(), "root.pem"), []byte("fake-root-cert"), 0600)
Expect(err).NotTo(HaveOccurred())
})

AfterEach(func() {
Expand Down Expand Up @@ -127,31 +121,26 @@ var _ = Describe("Instance", func() {

err = os.MkdirAll(filepath.Join(releaseDir, "chaincode", "server"), 0755)
Expect(err).NotTo(HaveOccurred())
err = ioutil.WriteFile(filepath.Join(releaseDir, "key.pem"), []byte("fake-key"), 0600)
Expect(err).NotTo(HaveOccurred())
err = ioutil.WriteFile(filepath.Join(releaseDir, "cert.pem"), []byte("fake-cert"), 0600)
Expect(err).NotTo(HaveOccurred())
err = ioutil.WriteFile(filepath.Join(releaseDir, "root.pem"), []byte("fake-root-cert"), 0600)
Expect(err).NotTo(HaveOccurred())

ccuserdata = &externalbuilder.ChaincodeServerUserData{
Address: "ccaddress:12345",
DialTimeout: externalbuilder.Duration{10 * time.Second},
TlsRequired: true,
TLSRequired: true,
ClientAuthRequired: true,
KeyPath: "key.pem",
CertPath: "cert.pem",
RootCertPath: "root.pem",
ClientKey: "fake-key",
ClientCert: "fake-cert",
RootCert: "fake-root-cert",
}
})

AfterEach(func() {
os.RemoveAll(releaseDir)
})

When("chaincode does not provide all info", func() {
Context("tls is not provided", func() {
It("returns TLS without client auth information", func() {
//"tls" missing
ccuserdata.TlsRequired = false
ccuserdata.TLSRequired = false

ccinfo, err := ccuserdata.ChaincodeServerInfo(releaseDir)
Expect(err).NotTo(HaveOccurred())
Expand All @@ -164,9 +153,9 @@ var _ = Describe("Instance", func() {
}))
})
})

Context("client auth is not provided", func() {
It("returns TLS without client auth information", func() {
//"client_auth_required" missing
ccuserdata.ClientAuthRequired = false

ccinfo, err := ccuserdata.ChaincodeServerInfo(releaseDir)
Expand All @@ -184,9 +173,9 @@ var _ = Describe("Instance", func() {
}))
})
})

Context("dial timeout not provided", func() {
It("returns default dial timeout without dialtimeout", func() {
//"dial_timeout" missing
ccuserdata.DialTimeout = externalbuilder.Duration{}

ccinfo, err := ccuserdata.ChaincodeServerInfo(releaseDir)
Expand All @@ -207,72 +196,42 @@ var _ = Describe("Instance", func() {
}))
})
})

Context("address is not provided", func() {
It("returns missing address error", func() {
//"address" missing
ccuserdata.Address = ""

_, err := ccuserdata.ChaincodeServerInfo(releaseDir)
Expect(err).To(MatchError("chaincode address not provided"))
})
})

Context("key is not provided", func() {
It("returns missing key error", func() {
//"key" missing
ccuserdata.KeyPath = ""
ccuserdata.ClientKey = ""

_, err := ccuserdata.ChaincodeServerInfo(releaseDir)
Expect(err).To(MatchError("chaincode tls key not provided"))
})
})

Context("cert is not provided", func() {
It("returns missing key error", func() {
//"cert" missing
ccuserdata.CertPath = ""
ccuserdata.ClientCert = ""

_, err := ccuserdata.ChaincodeServerInfo(releaseDir)
Expect(err).To(MatchError("chaincode tls cert not provided"))
})
})

Context("root cert is not provided", func() {
It("returns missing root cert error", func() {
//"root" missing
ccuserdata.RootCertPath = ""
ccuserdata.RootCert = ""

_, err := ccuserdata.ChaincodeServerInfo(releaseDir)
Expect(err).To(MatchError("chaincode tls root cert not provided"))
})
})
Context("cert file is missing", func() {
It("returns missing cert file error", func() {
//cert file is missing
err := os.Remove(filepath.Join(releaseDir, "cert.pem"))
Expect(err).NotTo(HaveOccurred())

_, err = ccuserdata.ChaincodeServerInfo(releaseDir)
Expect(err).To(MatchError(ContainSubstring("error reading cert file")))
})
})
Context("key file is missing", func() {
It("returns missing key file error", func() {
//key file is missing
err := os.Remove(filepath.Join(releaseDir, "key.pem"))
Expect(err).NotTo(HaveOccurred())

_, err = ccuserdata.ChaincodeServerInfo(releaseDir)
Expect(err).To(MatchError(ContainSubstring("error reading key file")))
})
})
Context("root cert file is missing", func() {
It("returns missing root cert file error", func() {
//key file is missing
err := os.Remove(filepath.Join(releaseDir, "root.pem"))
Expect(err).NotTo(HaveOccurred())

_, err = ccuserdata.ChaincodeServerInfo(releaseDir)
Expect(err).To(MatchError(ContainSubstring("error reading root cert file")))
})
})
})
})

Expand Down

0 comments on commit f0ef0b5

Please sign in to comment.