github.com/defanghe/fabric@v2.1.1+incompatible/internal/cryptogen/csp/csp_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 package csp_test 7 8 import ( 9 "crypto/ecdsa" 10 "crypto/elliptic" 11 "crypto/rand" 12 "crypto/rsa" 13 "crypto/x509" 14 "encoding/asn1" 15 "encoding/pem" 16 "fmt" 17 "io/ioutil" 18 "math/big" 19 "os" 20 "path/filepath" 21 "testing" 22 23 "github.com/hyperledger/fabric/internal/cryptogen/csp" 24 "github.com/stretchr/testify/assert" 25 ) 26 27 func TestLoadPrivateKey(t *testing.T) { 28 testDir, err := ioutil.TempDir("", "csp-test") 29 if err != nil { 30 t.Fatalf("Failed to create test directory: %s", err) 31 } 32 defer os.RemoveAll(testDir) 33 priv, err := csp.GeneratePrivateKey(testDir) 34 if err != nil { 35 t.Fatalf("Failed to generate private key: %s", err) 36 } 37 pkFile := filepath.Join(testDir, "priv_sk") 38 assert.Equal(t, true, checkForFile(pkFile), 39 "Expected to find private key file") 40 loadedPriv, err := csp.LoadPrivateKey(testDir) 41 assert.NoError(t, err, "Failed to load private key") 42 assert.NotNil(t, loadedPriv, "Should have returned an *ecdsa.PrivateKey") 43 assert.Equal(t, priv, loadedPriv, "Expected private keys to match") 44 } 45 46 func TestLoadPrivateKey_BadPEM(t *testing.T) { 47 testDir, err := ioutil.TempDir("", "csp-test") 48 if err != nil { 49 t.Fatalf("Failed to create test directory: %s", err) 50 } 51 defer os.RemoveAll(testDir) 52 53 badPEMFile := filepath.Join(testDir, "badpem_sk") 54 55 rsaKey, err := rsa.GenerateKey(rand.Reader, 1024) 56 if err != nil { 57 t.Fatalf("Failed to generate RSA key: %s", err) 58 } 59 60 pkcs8Encoded, err := x509.MarshalPKCS8PrivateKey(rsaKey) 61 if err != nil { 62 t.Fatalf("Failed to PKCS8 encode RSA private key: %s", err) 63 } 64 pkcs8RSAPem := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: pkcs8Encoded}) 65 66 pkcs1Encoded := x509.MarshalPKCS1PrivateKey(rsaKey) 67 if pkcs1Encoded == nil { 68 t.Fatalf("Failed to PKCS1 encode RSA private key: %s", err) 69 } 70 pkcs1RSAPem := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: pkcs1Encoded}) 71 72 for _, test := range []struct { 73 name string 74 data []byte 75 errMsg string 76 }{ 77 { 78 name: "not pem encoded", 79 data: []byte("wrong_encoding"), 80 errMsg: fmt.Sprintf("%s: bytes are not PEM encoded", badPEMFile), 81 }, 82 { 83 name: "not EC key", 84 data: pkcs8RSAPem, 85 errMsg: fmt.Sprintf("%s: pem bytes do not contain an EC private key", badPEMFile), 86 }, 87 { 88 name: "not PKCS8 encoded", 89 data: pkcs1RSAPem, 90 errMsg: fmt.Sprintf("%s: pem bytes are not PKCS8 encoded", badPEMFile), 91 }, 92 } { 93 t.Run(test.name, func(t *testing.T) { 94 err := ioutil.WriteFile( 95 badPEMFile, 96 test.data, 97 0755, 98 ) 99 if err != nil { 100 t.Fatalf("failed to write to wrong encoding file: %s", err) 101 } 102 _, err = csp.LoadPrivateKey(badPEMFile) 103 assert.Contains(t, err.Error(), test.errMsg) 104 os.Remove(badPEMFile) 105 }) 106 } 107 } 108 109 func TestGeneratePrivateKey(t *testing.T) { 110 testDir, err := ioutil.TempDir("", "csp-test") 111 if err != nil { 112 t.Fatalf("Failed to create test directory: %s", err) 113 } 114 defer os.RemoveAll(testDir) 115 116 expectedFile := filepath.Join(testDir, "priv_sk") 117 priv, err := csp.GeneratePrivateKey(testDir) 118 assert.NoError(t, err, "Failed to generate private key") 119 assert.NotNil(t, priv, "Should have returned an *ecdsa.Key") 120 assert.Equal(t, true, checkForFile(expectedFile), 121 "Expected to find private key file") 122 123 priv, err = csp.GeneratePrivateKey("notExist") 124 assert.Contains(t, err.Error(), "no such file or directory") 125 } 126 127 func TestECDSASigner(t *testing.T) { 128 priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 129 if err != nil { 130 t.Fatalf("Failed to generate private key: %s", err) 131 } 132 133 signer := csp.ECDSASigner{ 134 PrivateKey: priv, 135 } 136 assert.Equal(t, priv.Public(), signer.Public().(*ecdsa.PublicKey)) 137 digest := []byte{1} 138 sig, err := signer.Sign(rand.Reader, digest, nil) 139 if err != nil { 140 t.Fatalf("Failed to create signature: %s", err) 141 } 142 143 // unmarshal signature 144 ecdsaSig := &csp.ECDSASignature{} 145 _, err = asn1.Unmarshal(sig, ecdsaSig) 146 if err != nil { 147 t.Fatalf("Failed to unmarshal signature: %s", err) 148 } 149 // s should not be greater than half order of curve 150 halfOrder := new(big.Int).Div(priv.PublicKey.Curve.Params().N, big.NewInt(2)) 151 152 if ecdsaSig.S.Cmp(halfOrder) == 1 { 153 t.Error("Expected signature with Low S") 154 } 155 156 // ensure signature is valid by using standard verify function 157 ok := ecdsa.Verify(&priv.PublicKey, digest, ecdsaSig.R, ecdsaSig.S) 158 assert.True(t, ok, "Expected valid signature") 159 } 160 161 func checkForFile(file string) bool { 162 if _, err := os.Stat(file); os.IsNotExist(err) { 163 return false 164 } 165 return true 166 }