gitee.com/hyperledger/fabric-ca@v2.0.0-alpha+incompatible/util/util_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package util
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/ecdsa"
    22  	"crypto/elliptic"
    23  	"crypto/rand"
    24  	"crypto/rsa"
    25  	"crypto/x509"
    26  	"encoding/pem"
    27  	"fmt"
    28  	"io"
    29  	"io/ioutil"
    30  	"math/big"
    31  	"net/http"
    32  	"os"
    33  	"path"
    34  	"path/filepath"
    35  	"strings"
    36  	"testing"
    37  
    38  	"github.com/hyperledger/fabric/bccsp/factory"
    39  	_ "github.com/mattn/go-sqlite3"
    40  	"github.com/spf13/viper"
    41  	"github.com/stretchr/testify/assert"
    42  )
    43  
    44  func TestMain(m *testing.M) {
    45  	factory.InitFactories(nil)
    46  	os.Exit(m.Run())
    47  }
    48  
    49  func TestGetEnrollmentIDFromPEM(t *testing.T) {
    50  	cert, err := ioutil.ReadFile(getPath("ec.pem"))
    51  	if err != nil {
    52  		t.Fatalf("TestGetEnrollmentIDFromPEM.ReadFile failed: %s", err)
    53  	}
    54  	_, err = GetEnrollmentIDFromPEM(cert)
    55  	if err != nil {
    56  		t.Fatalf("Failed to get enrollment ID from PEM: %s", err)
    57  	}
    58  }
    59  
    60  func TestECCreateToken(t *testing.T) {
    61  	cert, _ := ioutil.ReadFile(getPath("ec.pem"))
    62  	bccsp := GetDefaultBCCSP()
    63  	privKey, err := ImportBCCSPKeyFromPEM(getPath("ec-key.pem"), bccsp, true)
    64  	if err != nil {
    65  		t.Logf("Failed importing key %s", err)
    66  	}
    67  	body := []byte("request byte array")
    68  
    69  	ECtoken, err := CreateToken(bccsp, cert, privKey, "GET", "/enroll", body)
    70  	if err != nil {
    71  		t.Fatalf("CreatToken failed: %s", err)
    72  	}
    73  
    74  	os.Setenv("FABRIC_CA_SERVER_COMPATIBILITY_MODE_V1_3", "false") // Test new token
    75  	_, err = VerifyToken(bccsp, ECtoken, "GET", "/enroll", body, false)
    76  	if err != nil {
    77  		t.Fatalf("VerifyToken failed: %s", err)
    78  	}
    79  
    80  	_, err = VerifyToken(nil, ECtoken, "GET", "/enroll", body, false)
    81  	if err == nil {
    82  		t.Fatal("VerifyToken should have failed as no instance of csp is passed")
    83  	}
    84  
    85  	_, err = VerifyToken(bccsp, "", "GET", "/enroll", body, false)
    86  	if err == nil {
    87  		t.Fatal("VerifyToken should have failed as no EC Token is passed")
    88  	}
    89  
    90  	_, err = VerifyToken(bccsp, ECtoken, "GET", "/enroll", nil, false)
    91  	if err == nil {
    92  		t.Fatal("VerifyToken should have failed as no body is passed")
    93  	}
    94  
    95  	_, err = VerifyToken(bccsp, ECtoken, "POST", "/enroll", nil, false)
    96  	if err == nil {
    97  		t.Fatal("VerifyToken should have failed as method was tampered")
    98  	}
    99  
   100  	_, err = VerifyToken(bccsp, ECtoken, "GET", "/affiliations", nil, false)
   101  	if err == nil {
   102  		t.Fatal("VerifyToken should have failed as path was tampered")
   103  	}
   104  
   105  	verifiedByte := []byte("TEST")
   106  	body = append(body, verifiedByte[0])
   107  	_, err = VerifyToken(bccsp, ECtoken, "GET", "/enroll", body, false)
   108  	if err == nil {
   109  		t.Fatal("VerifyToken should have failed as body was tampered")
   110  	}
   111  
   112  	ski, skierror := ioutil.ReadFile(getPath("ec-key.ski"))
   113  	if skierror != nil {
   114  		t.Fatalf("SKI File Read failed with error : %s", skierror)
   115  	}
   116  	ECtoken, err = CreateToken(bccsp, ski, privKey, "GET", "/enroll", body)
   117  	if (err == nil) || (ECtoken != "") {
   118  		t.Fatal("CreatToken should have failed as certificate passed is not correct")
   119  	}
   120  
   121  	// With comptability mode disabled, using old token should fail
   122  	b64Cert := B64Encode(cert)
   123  	payload := B64Encode(body) + "." + b64Cert
   124  	oldToken, err := genECDSAToken(bccsp, privKey, b64Cert, payload)
   125  	FatalError(t, err, "Failed to create token")
   126  	_, err = VerifyToken(bccsp, oldToken, "GET", "/enroll", body, false)
   127  	assert.Error(t, err)
   128  
   129  	// Test that by default with no environment variable set, the old token is considered valid
   130  	os.Unsetenv("FABRIC_CA_SERVER_COMPATIBILITY_MODE_V1_3")
   131  	_, err = VerifyToken(bccsp, oldToken, "GET", "/enroll", body, true)
   132  	assert.NoError(t, err, "Failed to verify token using old token type")
   133  }
   134  
   135  func TestDecodeToken(t *testing.T) {
   136  	token := "x.y.z"
   137  	_, _, _, err := DecodeToken(token)
   138  	assert.Error(t, err, "Decode should fail if the token has more than two parts")
   139  
   140  	token = "x"
   141  	_, _, _, err = DecodeToken(token)
   142  	assert.Error(t, err, "Decode should fail if the token has less than two parts")
   143  
   144  	token = "x.y"
   145  	_, _, _, err = DecodeToken(token)
   146  	assert.Error(t, err, "Decode should fail if the 1st part of the token is not in base64 encoded format")
   147  
   148  	fakecert := B64Encode([]byte("hello"))
   149  	token = fakecert + ".y"
   150  	_, _, _, err = DecodeToken(token)
   151  	assert.Error(t, err, "Decode should fail if the 1st part of the token is not base64 bytes of a X509 cert")
   152  }
   153  func TestGetX509CertFromPem(t *testing.T) {
   154  
   155  	certBuffer, error := ioutil.ReadFile(getPath("ec.pem"))
   156  	if error != nil {
   157  		t.Fatalf("Certificate File Read from file failed with error : %s", error)
   158  	}
   159  	certificate, err := GetX509CertificateFromPEM(certBuffer)
   160  	if err != nil {
   161  		t.Fatalf("GetX509CertificateFromPEM failed with error : %s", err)
   162  	}
   163  	if certificate == nil {
   164  		t.Fatal("Certificate cannot be nil")
   165  	}
   166  
   167  	skiBuffer, skiError := ioutil.ReadFile(getPath("ec-key.ski"))
   168  	if skiError != nil {
   169  		t.Fatalf("SKI File read failed with error : %s", skiError)
   170  	}
   171  
   172  	certificate, err = GetX509CertificateFromPEM(skiBuffer)
   173  	if err == nil {
   174  		t.Fatal("GetX509CertificateFromPEM should have failed as bytes passed was not in correct format")
   175  	}
   176  	if certificate != nil {
   177  		t.Fatalf("GetX509CertificateFromPEM should have failed as bytes passed was not in correct format")
   178  	}
   179  }
   180  
   181  func TestGetX509CertsFromPem(t *testing.T) {
   182  	certBuffer, error := ioutil.ReadFile(getPath("ec.pem"))
   183  	if error != nil {
   184  		t.Fatalf("Certificate File Read from file failed with error : %s", error)
   185  	}
   186  	certificates, err := GetX509CertificatesFromPEM(certBuffer)
   187  	assert.NoError(t, err, "GetX509CertificatesFromPEM failed")
   188  	assert.NotNil(t, certificates)
   189  	assert.Equal(t, 1, len(certificates), "GetX509CertificatesFromPEM should have returned 1 certificate")
   190  
   191  	skiBuffer, skiError := ioutil.ReadFile(getPath("ec-key.ski"))
   192  	if skiError != nil {
   193  		t.Fatalf("SKI File read failed with error : %s", skiError)
   194  	}
   195  
   196  	certificates, err = GetX509CertificatesFromPEM(skiBuffer)
   197  	if err == nil {
   198  		t.Fatal("GetX509CertificatesFromPEM should have failed as bytes passed was not in correct format")
   199  	}
   200  	if certificates != nil {
   201  		t.Fatalf("GetX509CertificatesFromPEM should have failed as bytes passed was not in correct format")
   202  	}
   203  }
   204  
   205  // This test case has been removed temporarily
   206  // as BCCSP does not have support for RSA private key import
   207  /*
   208  func TestRSACreateToken(t *testing.T) {
   209  	cert, _ := ioutil.ReadFile(getPath("rsa.pem"))
   210  	privKey, _ := ioutil.ReadFile(getPath("rsa-key.pem"))
   211  	body := []byte("request byte array")
   212  
   213  	csp := factory.GetDefault()
   214  	RSAtoken, err := CreateToken(csp, cert, privKey, body)
   215  	if err != nil {
   216  		t.Fatalf("CreatToken failed with error : %s", err)
   217  	}
   218  
   219  	_, err = VerifyToken(csp, RSAtoken, body)
   220  	if err != nil {
   221  		t.Fatalf("VerifyToken failed with error : %s", err)
   222  	}
   223  }
   224  */
   225  
   226  func TestCreateTokenDiffKey(t *testing.T) {
   227  	cert, _ := ioutil.ReadFile(getPath("ec.pem"))
   228  	bccsp := GetDefaultBCCSP()
   229  	privKey, _ := ImportBCCSPKeyFromPEM(getPath("rsa-key.pem"), bccsp, true)
   230  	body := []byte("request byte array")
   231  	_, err := CreateToken(bccsp, cert, privKey, "POST", "/enroll", body)
   232  	if err == nil {
   233  		t.Fatalf("TestCreateTokenDiffKey passed but should have failed")
   234  	}
   235  }
   236  
   237  // TestCreateTokenDiffKey2 has been commeted out right now
   238  // As there BCCSP does not have support fot RSA private Key
   239  // import. This will be uncommented when the support is in.
   240  /*
   241  func TestCreateTokenDiffKey2(t *testing.T) {
   242  	cert, _ := ioutil.ReadFile(getPath("rsa.pem"))
   243  	privKey, _ := ioutil.ReadFile(getPath("ec-key.pem"))
   244  	body := []byte("request byte array")
   245  
   246  	csp := factory.GetDefault()
   247  	_, err := CreateToken(csp, cert, privKey, body)
   248  	if err == nil {
   249  		t.Fatalf("TestCreateTokenDiffKey2 passed but should have failed")
   250  	}
   251  }
   252  */
   253  
   254  func TestEmptyToken(t *testing.T) {
   255  	body := []byte("request byte array")
   256  
   257  	csp := factory.GetDefault()
   258  	_, err := VerifyToken(csp, "", "POST", "/enroll", body, true)
   259  	if err == nil {
   260  		t.Fatalf("TestEmptyToken passed but should have failed")
   261  	}
   262  }
   263  
   264  func TestEmptyCert(t *testing.T) {
   265  	cert, _ := ioutil.ReadFile(getPath("ec.pem"))
   266  	body := []byte("request byte array")
   267  
   268  	csp := factory.GetDefault()
   269  	_, err := CreateToken(csp, cert, nil, "POST", "/enroll", body)
   270  	if err == nil {
   271  		t.Fatalf("TestEmptyCert passed but should have failed")
   272  	}
   273  }
   274  
   275  func TestEmptyKey(t *testing.T) {
   276  	bccsp := GetDefaultBCCSP()
   277  	privKey, _ := ImportBCCSPKeyFromPEM(getPath("ec-key.pem"), bccsp, true)
   278  	body := []byte("request byte array")
   279  	_, err := CreateToken(bccsp, []byte(""), privKey, "POST", "/enroll", body)
   280  	if err == nil {
   281  		t.Fatalf("TestEmptyKey passed but should have failed")
   282  	}
   283  }
   284  
   285  func TestEmptyBody(t *testing.T) {
   286  	bccsp := GetDefaultBCCSP()
   287  	privKey, _ := ImportBCCSPKeyFromPEM(getPath("ec-key.pem"), bccsp, true)
   288  	cert, _ := ioutil.ReadFile(getPath("ec.pem"))
   289  	_, err := CreateToken(bccsp, cert, privKey, "POST", "/enroll", []byte(""))
   290  	if err != nil {
   291  		t.Fatalf("CreateToken failed: %s", err)
   292  	}
   293  }
   294  
   295  func TestRandomString(t *testing.T) {
   296  	str := RandomString(10)
   297  	if str == "" {
   298  		t.Fatalf("RandomString failure")
   299  	}
   300  }
   301  
   302  func TestRemoveQuotes(t *testing.T) {
   303  	str := RemoveQuotes(`"a"`)
   304  	if str != "a" {
   305  		t.Fatalf("TestRemoveQuotes failed")
   306  	}
   307  }
   308  
   309  func TestRemoveQuotesNone(t *testing.T) {
   310  	str := RemoveQuotes(`a`)
   311  	if str != "a" {
   312  		t.Fatalf("TestRemoveQuotesNone failed")
   313  	}
   314  }
   315  
   316  func TestCreateHome(t *testing.T) {
   317  	t.Log("Test Creating Home Directory")
   318  	os.Unsetenv("COP_HOME")
   319  	tempDir, err := ioutil.TempDir("", "test")
   320  	if err != nil {
   321  		t.Errorf("Failed to create temp directory [error: %s]", err)
   322  	}
   323  	os.Setenv("HOME", tempDir)
   324  
   325  	dir, err := CreateClientHome()
   326  	if err != nil {
   327  		t.Errorf("Failed to create home directory, error: %s", err)
   328  	}
   329  
   330  	if _, err = os.Stat(dir); err != nil {
   331  		if os.IsNotExist(err) {
   332  			t.Error("Failed to create home directory")
   333  		}
   334  	}
   335  
   336  	os.RemoveAll(dir)
   337  }
   338  
   339  func TestGetDefaultConfigFile(t *testing.T) {
   340  	os.Unsetenv("FABRIC_CA_HOME")
   341  	os.Unsetenv("FABRIC_CA_CLIENT_HOME")
   342  	os.Unsetenv("FABRIC_CA_SERVER_HOME")
   343  	os.Unsetenv("CA_CFG_PATH")
   344  
   345  	const clientConfig = "fabric-ca-client-config.yaml"
   346  	const serverConfig = "fabric-ca-server-config.yaml"
   347  
   348  	os.Setenv("HOME", "/tmp")
   349  
   350  	expected := filepath.Join("/tmp/.fabric-ca-client/", clientConfig)
   351  	real := GetDefaultConfigFile("fabric-ca-client")
   352  	if real != expected {
   353  		t.Errorf("Incorrect default config path retrieved; expected %s but found %s",
   354  			expected, real)
   355  	}
   356  
   357  	os.Setenv("FABRIC_CA_HOME", "/tmp")
   358  	expected = filepath.Join("/tmp", clientConfig)
   359  	real = GetDefaultConfigFile("fabric-ca-client")
   360  	if real != expected {
   361  		t.Errorf("Incorrect default config path retrieved; expected %s but found %s",
   362  			expected, real)
   363  	}
   364  
   365  	expected = filepath.Join("/tmp", serverConfig)
   366  	real = GetDefaultConfigFile("fabric-ca-server")
   367  	if real != expected {
   368  		t.Errorf("Incorrect default config path retrieved; expected %s but found %s",
   369  			expected, real)
   370  	}
   371  
   372  	os.Setenv("FABRIC_CA_CLIENT_HOME", "/tmp/client")
   373  	expected = filepath.Join("/tmp/client", clientConfig)
   374  	real = GetDefaultConfigFile("fabric-ca-client")
   375  	if real != expected {
   376  		t.Errorf("Incorrect default config path retrieved; expected %s but found %s",
   377  			expected, real)
   378  	}
   379  
   380  	os.Setenv("FABRIC_CA_SERVER_HOME", "/tmp/server")
   381  	expected = filepath.Join("/tmp/server", serverConfig)
   382  	real = GetDefaultConfigFile("fabric-ca-server")
   383  	if real != expected {
   384  		t.Errorf("Incorrect default config path retrieved; expected %s but found %s",
   385  			expected, real)
   386  	}
   387  }
   388  
   389  func TestUnmarshal(t *testing.T) {
   390  	byteArray := []byte(`{"text":"foo"}`)
   391  	type test struct {
   392  		text string
   393  	}
   394  	var Test test
   395  	err := Unmarshal(byteArray, &Test, "testing unmarshal")
   396  	if err != nil {
   397  		t.Error("Failed to unmarshal, error: ", err)
   398  	}
   399  }
   400  
   401  func TestMarshal(t *testing.T) {
   402  	var x interface{}
   403  	_, err := Marshal(x, "testing marshal")
   404  	if err != nil {
   405  		t.Error("Failed to marshal, error: ", err)
   406  	}
   407  }
   408  
   409  func TestReadFile(t *testing.T) {
   410  	_, err := ReadFile("../testdata/csr.json")
   411  	if err != nil {
   412  		t.Error("Failed to read file, error: ", err)
   413  	}
   414  }
   415  
   416  func TestWriteFile(t *testing.T) {
   417  	testdir, err := ioutil.TempDir(".", "writefiletest")
   418  	if err != nil {
   419  		t.Fatalf("Failed to create temp directory: %s", err.Error())
   420  	}
   421  	defer os.RemoveAll(testdir)
   422  	testData := []byte("foo")
   423  	err = WriteFile(path.Join(testdir, "test.txt"), testData, 0777)
   424  	assert.NoError(t, err)
   425  	readOnlyDir := path.Join(testdir, "readonlydir")
   426  	err = os.MkdirAll(readOnlyDir, 4444)
   427  	if err != nil {
   428  		t.Fatalf("Failed to create directory: %s", err.Error())
   429  	}
   430  	err = WriteFile(path.Join(readOnlyDir, "test/test.txt"), testData, 0777)
   431  	assert.Error(t, err, "Should fail to create 'test' directory as the parent directory is read only")
   432  }
   433  
   434  func getPath(file string) string {
   435  	return "../testdata/" + file
   436  }
   437  
   438  func TestStrContained(t *testing.T) {
   439  	strs := []string{"one", "two", "three"}
   440  	str := "one"
   441  	result := StrContained(str, strs)
   442  	if result != true {
   443  		t.Error("Should have result in true")
   444  	}
   445  }
   446  
   447  func TestFileExists(t *testing.T) {
   448  	name := "../testdata/csr.json"
   449  	exists := FileExists(name)
   450  	if exists == false {
   451  		t.Error("File does not exist")
   452  	}
   453  	name = "better-not-exist"
   454  	exists = FileExists(name)
   455  	if exists == true {
   456  		t.Error("File 'better-not-exist' should not exist")
   457  	}
   458  }
   459  
   460  func TestMakeFileAbs(t *testing.T) {
   461  	testMakeFileAbs(t, "", "", "")
   462  	testMakeFileAbs(t, "/a/b/c", "", "/a/b/c")
   463  	testMakeFileAbs(t, "c", "/a/b", "/a/b/c")
   464  	testMakeFileAbs(t, "../c", "/a/b", "/a/c")
   465  }
   466  
   467  func TestMakeFilesAbs(t *testing.T) {
   468  	file1 := "a"
   469  	file2 := "a/b"
   470  	file3 := "/a/b"
   471  	files := []*string{&file1, &file2, &file3}
   472  	err := MakeFileNamesAbsolute(files, "/tmp")
   473  	if err != nil {
   474  		t.Fatalf("MakeFilesAbsolute failed: %s", err)
   475  	}
   476  	if file1 != "/tmp/a" {
   477  		t.Errorf("TestMakeFilesAbs failure: expecting /tmp/a but found %s", file1)
   478  	}
   479  	if file2 != "/tmp/a/b" {
   480  		t.Errorf("TestMakeFilesAbs failure: expecting /tmp/a/b but found %s", file2)
   481  	}
   482  	if file3 != "/a/b" {
   483  		t.Errorf("TestMakeFilesAbs failure: expecting /a/b but found %s", file3)
   484  	}
   485  }
   486  
   487  func TestB64(t *testing.T) {
   488  	buf := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
   489  	str := B64Encode(buf)
   490  	buf2, err := B64Decode(str)
   491  	if err != nil {
   492  		t.Errorf("Failed base64 decoding standard: %s", err)
   493  	}
   494  	if !bytes.Equal(buf, buf2) {
   495  		t.Error("Failed base64 decoding standard bytes aren't equal")
   496  	}
   497  }
   498  
   499  func TestGetUser(t *testing.T) {
   500  	os.Unsetenv("FABRIC_CA_CLIENT_URL")
   501  	viper.BindEnv("url", "FABRIC_CA_CLIENT_URL")
   502  	os.Setenv("FABRIC_CA_CLIENT_URL", "http://localhost:7054")
   503  	_, _, err := GetUser(viper.GetViper())
   504  	assert.Error(t, err, "Should have failed no username and password provided")
   505  
   506  	os.Setenv("FABRIC_CA_CLIENT_URL", "http://:pass@localhost:7054")
   507  	_, _, err = GetUser(viper.GetViper())
   508  	assert.Error(t, err, "Should have failed no username provided")
   509  
   510  	os.Setenv("FABRIC_CA_CLIENT_URL", "http://user:@localhost:7054")
   511  	_, _, err = GetUser(viper.GetViper())
   512  	assert.Error(t, err, "Should have failed no password provided")
   513  
   514  	os.Setenv("FABRIC_CA_CLIENT_URL", "http://foo:bar@localhost:7054")
   515  
   516  	user, pass, err := GetUser(viper.GetViper())
   517  	assert.NoError(t, err)
   518  
   519  	if user != "foo" {
   520  		t.Error("Failed to retrieve correct username")
   521  	}
   522  
   523  	if pass != "bar" {
   524  		t.Error("Failed to retrieve correct password")
   525  	}
   526  }
   527  
   528  type configID struct {
   529  	Name string `mask:"username"`
   530  	Addr string `json:"address"`
   531  	Pass string `mask:"password"`
   532  	URL  string `mask:"url"`
   533  	ID   int    `mask:"url"`
   534  }
   535  
   536  func (cc configID) String() string {
   537  	return StructToString(&cc)
   538  }
   539  
   540  func TestStructToString(t *testing.T) {
   541  	var obj configID
   542  	obj.Name = "foo"
   543  	addr := "101, penn ave"
   544  	obj.Addr = addr
   545  	obj.Pass = "bar"
   546  	str := StructToString(&obj)
   547  	if strings.Index(str, "bar") > 0 {
   548  		t.Errorf("Password is not masked by the StructToString function: %s", str)
   549  	}
   550  	if strings.Index(str, "foo") > 0 {
   551  		t.Errorf("Name is not masked by the StructToString function: %s", str)
   552  	}
   553  	if strings.Index(str, addr) < 0 {
   554  		t.Errorf("Addr is masked by the StructToString function: %s", str)
   555  	}
   556  
   557  	type registry struct {
   558  		MaxEnrollments int
   559  		Identities     []configID
   560  	}
   561  	type config struct {
   562  		Registry     registry
   563  		Affiliations map[string]interface{}
   564  	}
   565  	affiliations := map[string]interface{}{"org1": nil}
   566  	caConfig := config{
   567  		Affiliations: affiliations,
   568  		Registry: registry{
   569  			MaxEnrollments: -1,
   570  			Identities: []configID{
   571  				configID{
   572  					Name: "foo",
   573  					Pass: "foopwd",
   574  					Addr: "user",
   575  					URL:  "http://foo:foopwd@localhost:7054",
   576  					ID:   2,
   577  				},
   578  				configID{
   579  					Name: "bar",
   580  					Pass: "barpwd",
   581  					Addr: "user",
   582  					URL:  "ldap://foo:foopwd@localhost:7054",
   583  					ID:   3,
   584  				},
   585  			},
   586  		},
   587  	}
   588  	caConfigStr := fmt.Sprintf("caConfig=%+v", caConfig)
   589  	assert.NotContains(t, caConfigStr, "foopwd", "Identity password is not masked in the output")
   590  	assert.NotContains(t, caConfigStr, "barpwd", "Identity password is not masked in the output")
   591  	idStr := fmt.Sprintf("Identity[0]=%+v", caConfig.Registry.Identities[0])
   592  	assert.NotContains(t, idStr, "foopwd", "Identity password is not masked in the output")
   593  	idStr = fmt.Sprintf("Identity[1]=%+v", &caConfig.Registry.Identities[1])
   594  	assert.NotContains(t, idStr, "barpwd", "Identity password is not masked in the output")
   595  }
   596  
   597  func TestNormalizeStringSlice(t *testing.T) {
   598  	var tests = []struct {
   599  		slice    []string
   600  		expected []string
   601  	}{
   602  		{
   603  			slice:    []string{"string1"},
   604  			expected: []string{"string1"},
   605  		},
   606  		{
   607  			slice:    []string{" string1"},
   608  			expected: []string{"string1"},
   609  		},
   610  		{
   611  			slice:    []string{" string1   "},
   612  			expected: []string{"string1"},
   613  		},
   614  		{
   615  			slice:    []string{" string1   "},
   616  			expected: []string{"string1"},
   617  		},
   618  		{
   619  			slice:    []string{"string1", "string2"},
   620  			expected: []string{"string1", "string2"},
   621  		},
   622  		{
   623  			slice:    []string{"string1", "   string2"},
   624  			expected: []string{"string1", "string2"},
   625  		},
   626  	}
   627  
   628  	for _, test := range tests {
   629  		actual := NormalizeStringSlice(test.slice)
   630  		assert.Equal(t, test.expected, actual)
   631  	}
   632  }
   633  
   634  // Test file list with multiple and single entries both with and without brackets
   635  func TestNormalizeFileList(t *testing.T) {
   636  	slice := []string{"[file0,file1]", "file2,file3", "file4", "[file5]"}
   637  	slice, err := NormalizeFileList(slice, "../testdata")
   638  	if err != nil {
   639  		t.Fatalf("Failed to normalize files list, error: %s", err)
   640  	}
   641  	assert.Equal(t, 6, len(slice), "Invalid slice length")
   642  	for i := range slice {
   643  		if !strings.HasSuffix(slice[i], fmt.Sprintf("file%d", i)) {
   644  			t.Errorf("Failed to normalize files list for element %d; found '%s'", i, slice[i])
   645  		}
   646  	}
   647  }
   648  
   649  func testMakeFileAbs(t *testing.T, file, dir, expect string) {
   650  	path, err := MakeFileAbs(file, dir)
   651  	if err != nil {
   652  		t.Errorf("Failed to make %s absolute: %s", file, err)
   653  	}
   654  	// make expected path platform specific to work on Windows
   655  	if expect != "" {
   656  		expect, _ = filepath.Abs(expect)
   657  	}
   658  	if path != expect {
   659  		t.Errorf("Absolute of file=%s with dir=%s expected %s but was %s", file, dir, expect, path)
   660  	}
   661  }
   662  
   663  func TestRemoveQuotesInvalidArgs(t *testing.T) {
   664  	res := RemoveQuotes("")
   665  	assert.Equal(t, "", res)
   666  }
   667  
   668  func TestUnmarshalInvalidArgs(t *testing.T) {
   669  	err := Unmarshal(nil, nil, "")
   670  	assert.Error(t, err)
   671  	assert.Contains(t, err.Error(), "Failed to unmarshal ")
   672  }
   673  
   674  func TestStrContainedInvalidArgs(t *testing.T) {
   675  	res := StrContained("Hello World", nil)
   676  	assert.False(t, res)
   677  }
   678  
   679  func TestGetSerialAsHex(t *testing.T) {
   680  	res := GetSerialAsHex(big.NewInt(101))
   681  	assert.Equal(t, "65", res)
   682  }
   683  
   684  func TestECPrivateKey(t *testing.T) {
   685  	_, err := GetECPrivateKey(getPEM("../testdata/ec-key.pem", t))
   686  	assert.NoError(t, err)
   687  
   688  	rsaKey, err := rsa.GenerateKey(rand.Reader, 256)
   689  	if err != nil {
   690  		t.Fatalf("Failed to create rsa key: %s", err.Error())
   691  	}
   692  	encodedPK, err := x509.MarshalPKCS8PrivateKey(rsaKey)
   693  	if err != nil {
   694  		t.Fatalf("Failed to marshal RSA private key: %s", err.Error())
   695  	}
   696  
   697  	pemEncodedPK := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: encodedPK})
   698  	_, err = GetECPrivateKey(pemEncodedPK)
   699  	assert.Error(t, err)
   700  
   701  	_, err = GetECPrivateKey([]byte("hello"))
   702  	assert.Error(t, err)
   703  
   704  	_, err = GetECPrivateKey(pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte("hello")}))
   705  	assert.Error(t, err)
   706  }
   707  
   708  func TestPKCS8WrappedECPrivateKey(t *testing.T) {
   709  	_, err := GetECPrivateKey(getPEM("../testdata/pkcs8eckey.pem", t))
   710  	assert.NoError(t, err)
   711  }
   712  
   713  func TestRSAPrivateKey(t *testing.T) {
   714  	_, err := GetRSAPrivateKey([]byte("hello"))
   715  	assert.Error(t, err)
   716  
   717  	_, err = GetRSAPrivateKey(getPEM("../testdata/rsa-key.pem", t))
   718  	assert.NoError(t, err)
   719  
   720  	rsaKey, err := rsa.GenerateKey(rand.Reader, 256)
   721  	if err != nil {
   722  		t.Fatalf("Failed to create rsa key: %s", err.Error())
   723  	}
   724  	encodedPK, err := x509.MarshalPKCS8PrivateKey(rsaKey)
   725  	if err != nil {
   726  		t.Fatalf("Failed to marshal RSA private key: %s", err.Error())
   727  	}
   728  
   729  	pemEncodedPK := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: encodedPK})
   730  	_, err = GetRSAPrivateKey(pemEncodedPK)
   731  	assert.NoError(t, err)
   732  
   733  	_, err = GetRSAPrivateKey(pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte("hello")}))
   734  	assert.Error(t, err)
   735  
   736  	ecdsaKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   737  	if err != nil {
   738  		t.Fatalf("Failed to create rsa key: %s", err.Error())
   739  	}
   740  	encodedPK, err = x509.MarshalPKCS8PrivateKey(ecdsaKey)
   741  	if err != nil {
   742  		t.Fatalf("Failed to marshal RSA private key: %s", err.Error())
   743  	}
   744  
   745  	pemEncodedPK = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: encodedPK})
   746  	_, err = GetRSAPrivateKey(pemEncodedPK)
   747  	assert.Error(t, err)
   748  }
   749  
   750  func TestCheckHostsInCert(t *testing.T) {
   751  	err := CheckHostsInCert("../testdata/doesnotexist.pem", "")
   752  	assert.Error(t, err)
   753  
   754  	err = CheckHostsInCert("../testdata/tls_server-cert.pem", "localhost")
   755  	assert.NoError(t, err, fmt.Sprintf("Failed to find 'localhost' for host in certificate: %s", err))
   756  
   757  	err = CheckHostsInCert("../testdata/tls_server-cert.pem", "localhost", "fakehost")
   758  	assert.Error(t, err, "Certificate does not contain 'fakehost', should have failed")
   759  
   760  	err = CheckHostsInCert("../testdata/root.pem", "x")
   761  	assert.Error(t, err, "Certificate contained no host, should have failed")
   762  }
   763  
   764  func TestCertDuration(t *testing.T) {
   765  	d, err := GetCertificateDurationFromFile("../testdata/ec.pem")
   766  	assert.NoError(t, err)
   767  	assert.True(t, d.Hours() == 43800, "Expected certificate duration of 43800h in ec.pem")
   768  	_, err = GetCertificateDurationFromFile("bogus.pem")
   769  	assert.Error(t, err)
   770  }
   771  
   772  type MyReader struct {
   773  	buf                   []byte
   774  	maxPerRead, bytesRead int
   775  }
   776  
   777  func (r *MyReader) Read(data []byte) (int, error) {
   778  	if r.bytesRead >= len(r.buf) {
   779  		return 0, io.EOF
   780  	}
   781  	buf := r.buf[r.bytesRead:]
   782  	count := 0
   783  	for i, v := range buf {
   784  		if i >= len(data) || count > r.maxPerRead {
   785  			break
   786  		}
   787  		data[i] = v
   788  		count++
   789  	}
   790  	r.bytesRead = r.bytesRead + count
   791  	return count, nil
   792  }
   793  
   794  func TestRead(t *testing.T) {
   795  	myReader := MyReader{
   796  		buf:        []byte("123456789012345"),
   797  		maxPerRead: 6,
   798  	}
   799  
   800  	// Test with a buffer that is too small to fit data
   801  	buf := make([]byte, 10)
   802  	data, err := Read(&myReader, buf)
   803  	assert.Error(t, err, "Should have errored, the data passed is bigger than the buffer")
   804  
   805  	// Test with a buffer that is big enough to fit data
   806  	buf = make([]byte, 25)
   807  	myReader.bytesRead = 0
   808  	data, err = Read(&myReader, buf)
   809  	if assert.NoError(t, err, fmt.Sprintf("Error occured during read: %s", err)) {
   810  		if string(data) != string(myReader.buf) {
   811  			t.Error("The data returned does not match")
   812  		}
   813  	}
   814  
   815  	// Test with a buffer with exact size of data
   816  	buf = make([]byte, len(myReader.buf))
   817  	myReader.bytesRead = 0
   818  	data, err = Read(&myReader, buf)
   819  	if assert.NoError(t, err, fmt.Sprintf("Error occured during exact size read: %s", err)) {
   820  		if string(data) != string(myReader.buf) {
   821  			t.Error("The data returned does not match")
   822  		}
   823  	}
   824  }
   825  
   826  func getPEM(file string, t *testing.T) []byte {
   827  	buf, err := ioutil.ReadFile(file)
   828  	assert.NoError(t, err)
   829  	return buf
   830  }
   831  
   832  func TestIsSubsetOf(t *testing.T) {
   833  	testIsSubsetOf(t, "a,b", "b,a,c", true)
   834  	testIsSubsetOf(t, "a,b", "b,a", true)
   835  	testIsSubsetOf(t, "a,b,c", "a,b", false)
   836  	testIsSubsetOf(t, "a,b,c", "", false)
   837  }
   838  
   839  func testIsSubsetOf(t *testing.T, small, large string, expectToPass bool) {
   840  	err := IsSubsetOf(small, large)
   841  	if expectToPass {
   842  		if err != nil {
   843  			t.Errorf("IsSubsetOf('%s','%s') failed: %s", small, large, err)
   844  		}
   845  	} else {
   846  		if err == nil {
   847  			t.Errorf("IsSubsetOf('%s','%s') expected error but passed", small, large)
   848  		}
   849  	}
   850  }
   851  
   852  func TestHostname(t *testing.T) {
   853  	host := Hostname()
   854  	assert.NotEqual(t, "", host, "Hostname should not be empty")
   855  }
   856  
   857  func TestHTTPRequestToString(t *testing.T) {
   858  	url := "http://localhost:7054"
   859  	reqBody := "Hello"
   860  	req, err := http.NewRequest("POST", url, strings.NewReader(reqBody))
   861  	if err != nil {
   862  		t.Errorf("Failed to create a request: %s", err)
   863  	} else {
   864  		reqStr := HTTPRequestToString(req)
   865  		assert.Contains(t, reqStr, url)
   866  		assert.Contains(t, reqStr, "POST")
   867  		assert.Contains(t, reqStr, reqBody)
   868  	}
   869  }
   870  
   871  func TestValidateAndReturnAbsConf(t *testing.T) {
   872  	var err error
   873  	var filename, homeDir string
   874  
   875  	filename, _, err = ValidateAndReturnAbsConf("/tmp/test.yaml", "/tmp/homeDir", "fabric-ca-client")
   876  	assert.NoError(t, err, "Should not have errored out, this is a valid configuration")
   877  
   878  	if filename != "/tmp/test.yaml" {
   879  		t.Error("Failed to get correct path for configuration file")
   880  	}
   881  
   882  	filename, homeDir, err = ValidateAndReturnAbsConf("", "../testdata/tmp", "fabric-ca-client")
   883  	assert.NoError(t, err, "Should not have errored out, this is a valid configuration")
   884  
   885  	homeDirAbs, err := filepath.Abs("../testdata/tmp")
   886  	if err != nil {
   887  		t.Fatal("Error occured getting absolute path: ", err)
   888  	}
   889  
   890  	if homeDir != homeDirAbs {
   891  		t.Error("Failed to get correct path for home directory")
   892  	}
   893  
   894  	if filename != filepath.Join(homeDirAbs, "fabric-ca-client-config.yaml") {
   895  		t.Error("Failed to get correct path for configuration file")
   896  	}
   897  
   898  	// Test with no home directory set
   899  	filename, _, err = ValidateAndReturnAbsConf("/tmp/test.yaml", "", "fabric-ca-client")
   900  	assert.NoError(t, err, "Should not have errored out, this is a valid configuration")
   901  
   902  	if filename != "/tmp/test.yaml" {
   903  		t.Error("Failed to get correct path for configuration file")
   904  	}
   905  
   906  	filename, homeDir, err = ValidateAndReturnAbsConf("../testdata/tmp/test.yaml", "", "fabric-ca-client")
   907  	assert.NoError(t, err, "Should not have errored out, this is a valid configuration")
   908  
   909  	homeDirAbs, err = filepath.Abs("../testdata/tmp")
   910  	if err != nil {
   911  		t.Fatal("Error occured getting absolute path: ", err)
   912  	}
   913  
   914  	if homeDir != homeDirAbs {
   915  		t.Error("Failed to get correct path for home directory")
   916  	}
   917  
   918  	if filename != filepath.Join(homeDirAbs, "test.yaml") {
   919  		t.Error("Failed to get correct path for configuration file")
   920  	}
   921  }
   922  
   923  func TestListContains(t *testing.T) {
   924  	list := "peer, client,orderer, *"
   925  	found := ListContains(list, "*")
   926  	assert.Equal(t, found, true)
   927  
   928  	list = "peer, client,orderer"
   929  	found = ListContains(list, "*")
   930  	assert.Equal(t, found, false)
   931  }