github.com/hyperledger/fabric-ca@v2.0.0-alpha.0.20201120210307-7b4f34729db1+incompatible/internal/pkg/util/csp_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_test
    18  
    19  import (
    20  	"crypto/x509"
    21  	"errors"
    22  	"fmt"
    23  	"io/ioutil"
    24  	"os"
    25  	"path/filepath"
    26  	"testing"
    27  
    28  	"github.com/cloudflare/cfssl/csr"
    29  	. "github.com/hyperledger/fabric-ca/internal/pkg/util"
    30  	"github.com/hyperledger/fabric-ca/internal/pkg/util/mocks"
    31  	"github.com/hyperledger/fabric/bccsp"
    32  	"github.com/hyperledger/fabric/bccsp/factory"
    33  	"github.com/stretchr/testify/assert"
    34  )
    35  
    36  var csp bccsp.BCCSP
    37  
    38  func TestMain(m *testing.M) {
    39  	os.Exit(testMain(m))
    40  }
    41  
    42  func testMain(m *testing.M) int {
    43  	err := factory.InitFactories(nil)
    44  	if err != nil {
    45  		fmt.Printf("Could not initialize BCCSP factory interfaces [%s]", err)
    46  		return -1
    47  	}
    48  
    49  	tmpDir, err := ioutil.TempDir("", "keystore")
    50  	if err != nil {
    51  		fmt.Printf("Could not create keystore directory [%s]", err)
    52  		return -1
    53  	}
    54  	defer os.RemoveAll(tmpDir)
    55  
    56  	opts := factory.GetDefaultOpts()
    57  	opts.SwOpts.FileKeystore = &factory.FileKeystoreOpts{KeyStorePath: tmpDir}
    58  	opts.SwOpts.Ephemeral = false
    59  	csp, err = factory.GetBCCSPFromOpts(opts)
    60  	if err != nil {
    61  		fmt.Printf("Could not initialize BCCSP Factories [%s]", err)
    62  		return -1
    63  	}
    64  
    65  	return m.Run()
    66  }
    67  
    68  func testKeyGenerate(t *testing.T, kr *csr.KeyRequest, mustFail bool) {
    69  	req := csr.CertificateRequest{
    70  		KeyRequest: kr,
    71  	}
    72  
    73  	key, cspSigner, err := BCCSPKeyRequestGenerate(&req, csp)
    74  	if mustFail {
    75  		if err == nil {
    76  			t.Fatalf("BCCSPKeyRequestGenerate should had failed")
    77  		}
    78  	} else {
    79  		if err != nil {
    80  			t.Fatalf("BCCSPKeyRequestGenerate failed: %s", err)
    81  		}
    82  		if key == nil {
    83  			t.Fatalf("BCCSPKeyRequestGenerate key cannot be nil")
    84  		}
    85  		if cspSigner == nil {
    86  			t.Fatalf("BCCSPKeyRequestGenerate cspSigner cannot be nil")
    87  		}
    88  	}
    89  }
    90  
    91  func TestGetDefaultBCCSP(t *testing.T) {
    92  	csp := GetDefaultBCCSP()
    93  	if csp == nil {
    94  		t.Fatal("Failed to get default BCCSP")
    95  	}
    96  }
    97  
    98  func TestInitBCCSP(t *testing.T) {
    99  	mspDir := "msp"
   100  	var opts *factory.FactoryOpts
   101  	_, err := InitBCCSP(&opts, "", mspDir)
   102  	if err != nil {
   103  		t.Fatalf("Failed initialization 1 of BCCSP: %s", err)
   104  	}
   105  	cfg := &factory.FactoryOpts{ProviderName: "SW"}
   106  	_, err = InitBCCSP(&cfg, "msp2", mspDir)
   107  	if err != nil {
   108  		t.Fatalf("Failed initialization 2 of BCCSP: %s", err)
   109  	}
   110  	_, err = InitBCCSP(nil, "", mspDir)
   111  	if err == nil {
   112  		t.Fatalf("Initialization 3 of BCCSP should have failed but did not")
   113  	}
   114  }
   115  
   116  func TestKeyGenerate(t *testing.T) {
   117  	t.Run("256", func(t *testing.T) { testKeyGenerate(t, csr.NewKeyRequest(), false) })
   118  	t.Run("384", func(t *testing.T) { testKeyGenerate(t, &csr.KeyRequest{A: "ecdsa", S: 384}, false) })
   119  	t.Run("521", func(t *testing.T) { testKeyGenerate(t, &csr.KeyRequest{A: "ecdsa", S: 521}, true) })
   120  	t.Run("521", func(t *testing.T) { testKeyGenerate(t, &csr.KeyRequest{A: "ecdsa", S: 224}, true) })
   121  	t.Run("512", func(t *testing.T) { testKeyGenerate(t, &csr.KeyRequest{A: "rsa", S: 512}, true) })
   122  	t.Run("1024", func(t *testing.T) { testKeyGenerate(t, &csr.KeyRequest{A: "rsa", S: 1024}, true) })
   123  	t.Run("2048", func(t *testing.T) { testKeyGenerate(t, &csr.KeyRequest{A: "rsa", S: 2048}, false) })
   124  	t.Run("3072", func(t *testing.T) { testKeyGenerate(t, &csr.KeyRequest{A: "rsa", S: 3072}, false) })
   125  	t.Run("4096", func(t *testing.T) { testKeyGenerate(t, &csr.KeyRequest{A: "rsa", S: 4096}, false) })
   126  	t.Run("4097", func(t *testing.T) { testKeyGenerate(t, &csr.KeyRequest{A: "rsa", S: 4097}, true) })
   127  	t.Run("10000", func(t *testing.T) { testKeyGenerate(t, &csr.KeyRequest{A: "rsa", S: 10000}, true) })
   128  	t.Run("empty", func(t *testing.T) { testKeyGenerate(t, &csr.KeyRequest{}, true) })
   129  	t.Run("nil", func(t *testing.T) { testKeyGenerate(t, nil, false) })
   130  }
   131  
   132  func testGetSignerFromCertFile(t *testing.T, keyFile, certFile string, mustFail int) {
   133  	key, err := ImportBCCSPKeyFromPEM(keyFile, csp, false)
   134  	if mustFail == 1 {
   135  		if err == nil {
   136  			t.Fatalf("ImportBCCSPKeyFromPEM should had failed")
   137  		}
   138  		return
   139  	}
   140  
   141  	if err != nil {
   142  		t.Fatalf("ImportBCCSPKeyFromPEM failed: %s", err)
   143  	}
   144  	if key == nil {
   145  		t.Fatalf("ImportBCCSPKeyFromPEM key cannot be nil")
   146  	}
   147  
   148  	key, signer, cert, err := GetSignerFromCertFile(certFile, csp)
   149  	if mustFail == 2 {
   150  		if err == nil {
   151  			t.Fatalf("ImportBCCSPKeyFromPEM should had failed")
   152  		}
   153  	} else {
   154  		if err != nil {
   155  			t.Fatalf("GetSignerFromCertFile failed: %s", err)
   156  		}
   157  		if key == nil {
   158  			t.Fatalf("GetSignerFromCertFile key cannot be nil")
   159  		}
   160  		if signer == nil {
   161  			t.Fatalf("GetSignerFromCertFile signer cannot be nil")
   162  		}
   163  		if cert == nil {
   164  			t.Fatalf("GetSignerFromCertFile cert cannot be nil")
   165  		}
   166  	}
   167  
   168  	cer, err := LoadX509KeyPair(certFile, keyFile, csp)
   169  	if mustFail == 2 {
   170  		if err == nil {
   171  			t.Fatalf("LoadX509KeyPair should had failed")
   172  		}
   173  	} else {
   174  		if err != nil {
   175  			t.Fatalf("LoadX509KeyPair failed: %s", err)
   176  		}
   177  		if cer.Certificate[0] == nil {
   178  			t.Fatalf("LoadX509KeyPair cert cannot be nil")
   179  		}
   180  	}
   181  }
   182  
   183  func TestGetSignerFromCertFile(t *testing.T) {
   184  	t.Run("ec", func(t *testing.T) {
   185  		testGetSignerFromCertFile(t, filepath.Join("testdata", "ec-key.pem"), filepath.Join("testdata", "ec.pem"), 0)
   186  	})
   187  	t.Run("nokey", func(t *testing.T) {
   188  		testGetSignerFromCertFile(t, "doesnotexist.pem", filepath.Join("testdata", "ec.pem"), 1)
   189  	})
   190  	t.Run("nocert", func(t *testing.T) {
   191  		testGetSignerFromCertFile(t, filepath.Join("testdata", "ec-key.pem"), "doesnotexist.pem", 2)
   192  	})
   193  	t.Run("cert4key", func(t *testing.T) {
   194  		testGetSignerFromCertFile(t, filepath.Join("testdata", "ec.pem"), filepath.Join("testdata", "ec.pem"), 1)
   195  	})
   196  	t.Run("rsa", func(t *testing.T) {
   197  		testGetSignerFromCertFile(t, filepath.Join("testdata", "rsa-key.pem"), filepath.Join("testdata", "rsa.pem"), 1)
   198  	})
   199  	t.Run("wrongcert", func(t *testing.T) {
   200  		testGetSignerFromCertFile(t, filepath.Join("testdata", "ec-key.pem"), filepath.Join("testdata", "test.pem"), 2)
   201  	})
   202  }
   203  
   204  func TestBccspBackedSigner(t *testing.T) {
   205  	signer, err := BccspBackedSigner("", "", nil, csp)
   206  	if signer != nil {
   207  		t.Fatalf("BccspBackedSigner should not be valid for empty cert: %s", err)
   208  	}
   209  
   210  	signer, err = BccspBackedSigner("doesnotexist.pem", "", nil, csp)
   211  	if err == nil {
   212  		t.Fatal("BccspBackedSigner should had failed to load cert")
   213  	}
   214  	if signer != nil {
   215  		t.Fatal("BccspBackedSigner should not be valid for non-existent cert")
   216  	}
   217  
   218  	signer, err = BccspBackedSigner(filepath.Join("testdata", "ec.pem"), filepath.Join("testdata", "ec-key.pem"), nil, csp)
   219  	if signer == nil {
   220  		t.Fatalf("BccspBackedSigner should had found cert: %s", err)
   221  	}
   222  }
   223  
   224  func TestGetSignerFromCertInvalidArgs(t *testing.T) {
   225  	_, _, err := GetSignerFromCert(nil, nil)
   226  	assert.Error(t, err)
   227  	assert.Contains(t, err.Error(), "CSP was not initialized")
   228  
   229  	csp := &mocks.BCCSP{}
   230  	csp.On("KeyImport", (*x509.Certificate)(nil), &bccsp.X509PublicKeyImportOpts{Temporary: true}).Return(bccsp.Key(nil), errors.New("mock key import error"))
   231  	_, _, err = GetSignerFromCert(nil, csp)
   232  	assert.Error(t, err)
   233  	assert.Contains(t, err.Error(), "Failed to import certificate's public key: mock key import error")
   234  }
   235  
   236  func TestClean(t *testing.T) {
   237  	os.RemoveAll("csp")
   238  }