github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/bccsp/pkcs11/pkcs11_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 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  package pkcs11
    17  
    18  import (
    19  	"crypto/ecdsa"
    20  	"crypto/elliptic"
    21  	"crypto/rand"
    22  	"encoding/asn1"
    23  	"encoding/hex"
    24  	"testing"
    25  
    26  	"github.com/hyperledger/fabric/bccsp"
    27  	"github.com/miekg/pkcs11"
    28  	"github.com/stretchr/testify/assert"
    29  )
    30  
    31  func TestPKCS11GetSession(t *testing.T) {
    32  	var sessions []pkcs11.SessionHandle
    33  	for i := 0; i < 3*sessionCacheSize; i++ {
    34  		sessions = append(sessions, currentBCCSP.(*impl).getSession())
    35  	}
    36  
    37  	// Return all sessions, should leave sessionCacheSize cached
    38  	for _, session := range sessions {
    39  		currentBCCSP.(*impl).returnSession(session)
    40  	}
    41  	sessions = nil
    42  
    43  	// Lets break OpenSession, so non-cached session cannot be opened
    44  	oldSlot := currentBCCSP.(*impl).slot
    45  	currentBCCSP.(*impl).slot = ^uint(0)
    46  
    47  	// Should be able to get sessionCacheSize cached sessions
    48  	for i := 0; i < sessionCacheSize; i++ {
    49  		sessions = append(sessions, currentBCCSP.(*impl).getSession())
    50  	}
    51  
    52  	// This one should fail
    53  	assert.Panics(t, func() {
    54  		currentBCCSP.(*impl).getSession()
    55  	}, "Should not been able to create another session")
    56  
    57  	// Cleanup
    58  	for _, session := range sessions {
    59  		currentBCCSP.(*impl).returnSession(session)
    60  	}
    61  	currentBCCSP.(*impl).slot = oldSlot
    62  }
    63  
    64  func TestPKCS11ECKeySignVerify(t *testing.T) {
    65  	if currentBCCSP.(*impl).noPrivImport {
    66  		t.Skip("Key import turned off. Skipping Derivation tests as they currently require Key Import.")
    67  	}
    68  
    69  	msg1 := []byte("This is my very authentic message")
    70  	msg2 := []byte("This is my very unauthentic message")
    71  	hash1, _ := currentBCCSP.Hash(msg1, &bccsp.SHAOpts{})
    72  	hash2, _ := currentBCCSP.Hash(msg2, &bccsp.SHAOpts{})
    73  
    74  	var oid asn1.ObjectIdentifier
    75  	if currentTestConfig.securityLevel == 256 {
    76  		oid = oidNamedCurveP256
    77  	} else if currentTestConfig.securityLevel == 384 {
    78  		oid = oidNamedCurveP384
    79  	}
    80  
    81  	key, pubKey, err := currentBCCSP.(*impl).generateECKey(oid, true)
    82  	if err != nil {
    83  		t.Fatalf("Failed generating Key [%s]", err)
    84  	}
    85  
    86  	R, S, err := currentBCCSP.(*impl).signP11ECDSA(key, hash1)
    87  
    88  	if err != nil {
    89  		t.Fatalf("Failed signing message [%s]", err)
    90  	}
    91  
    92  	pass, err := currentBCCSP.(*impl).verifyP11ECDSA(key, hash1, R, S, currentTestConfig.securityLevel/8)
    93  	if err != nil {
    94  		t.Fatalf("Error verifying message 1 [%s]", err)
    95  	}
    96  	if pass == false {
    97  		t.Fatal("Signature should match!")
    98  	}
    99  
   100  	pass = ecdsa.Verify(pubKey, hash1, R, S)
   101  	if pass == false {
   102  		t.Fatal("Signature should match with software verification!")
   103  	}
   104  
   105  	pass, err = currentBCCSP.(*impl).verifyP11ECDSA(key, hash2, R, S, currentTestConfig.securityLevel/8)
   106  	if err != nil {
   107  		t.Fatalf("Error verifying message 2 [%s]", err)
   108  	}
   109  
   110  	if pass != false {
   111  		t.Fatal("Signature should not match!")
   112  	}
   113  
   114  	pass = ecdsa.Verify(pubKey, hash2, R, S)
   115  	if pass != false {
   116  		t.Fatal("Signature should not match with software verification!")
   117  	}
   118  }
   119  
   120  func TestPKCS11ECKeyImportSignVerify(t *testing.T) {
   121  	if currentBCCSP.(*impl).noPrivImport {
   122  		t.Skip("Key import turned off. Skipping Derivation tests as they currently require Key Import.")
   123  	}
   124  
   125  	msg1 := []byte("This is my very authentic message")
   126  	msg2 := []byte("This is my very unauthentic message")
   127  	hash1, _ := currentBCCSP.Hash(msg1, &bccsp.SHAOpts{})
   128  	hash2, err := currentBCCSP.Hash(msg2, &bccsp.SHAOpts{})
   129  
   130  	var oid asn1.ObjectIdentifier
   131  	var key *ecdsa.PrivateKey
   132  	if currentTestConfig.securityLevel == 256 {
   133  		oid = oidNamedCurveP256
   134  		key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   135  		if err != nil {
   136  			t.Fatalf("Failed generating ECDSA key [%s]", err)
   137  		}
   138  	} else if currentTestConfig.securityLevel == 384 {
   139  		oid = oidNamedCurveP384
   140  		key, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
   141  		if err != nil {
   142  			t.Fatalf("Failed generating ECDSA key [%s]", err)
   143  		}
   144  	}
   145  
   146  	ecPt := elliptic.Marshal(key.Curve, key.X, key.Y)
   147  	ski, err := currentBCCSP.(*impl).importECKey(oid, key.D.Bytes(), ecPt, false, privateKeyFlag)
   148  	if err != nil {
   149  		t.Fatalf("Failed getting importing EC Public Key [%s]", err)
   150  	}
   151  
   152  	R, S, err := currentBCCSP.(*impl).signP11ECDSA(ski, hash1)
   153  
   154  	if err != nil {
   155  		t.Fatalf("Failed signing message [%s]", err)
   156  	}
   157  
   158  	pass, err := currentBCCSP.(*impl).verifyP11ECDSA(ski, hash1, R, S, currentTestConfig.securityLevel/8)
   159  	if err != nil {
   160  		t.Fatalf("Error verifying message 1 [%s]\n%s\n\n%s", err, hex.Dump(R.Bytes()), hex.Dump(S.Bytes()))
   161  	}
   162  	if pass == false {
   163  		t.Fatalf("Signature should match!\n%s\n\n%s", hex.Dump(R.Bytes()), hex.Dump(S.Bytes()))
   164  	}
   165  
   166  	pass = ecdsa.Verify(&key.PublicKey, hash1, R, S)
   167  	if pass == false {
   168  		t.Fatal("Signature should match with software verification!")
   169  	}
   170  
   171  	pass, err = currentBCCSP.(*impl).verifyP11ECDSA(ski, hash2, R, S, currentTestConfig.securityLevel/8)
   172  	if err != nil {
   173  		t.Fatalf("Error verifying message 2 [%s]", err)
   174  	}
   175  
   176  	if pass != false {
   177  		t.Fatal("Signature should not match!")
   178  	}
   179  
   180  	pass = ecdsa.Verify(&key.PublicKey, hash2, R, S)
   181  	if pass != false {
   182  		t.Fatal("Signature should not match with software verification!")
   183  	}
   184  }
   185  
   186  func TestPKCS11ECKeyExport(t *testing.T) {
   187  	if currentBCCSP.(*impl).noPrivImport {
   188  		t.Skip("Key import turned off. Skipping Derivation tests as they currently require Key Import.")
   189  	}
   190  
   191  	msg1 := []byte("This is my very authentic message")
   192  	msg2 := []byte("This is my very unauthentic message")
   193  	hash1, _ := currentBCCSP.Hash(msg1, &bccsp.SHAOpts{})
   194  	hash2, err := currentBCCSP.Hash(msg2, &bccsp.SHAOpts{})
   195  
   196  	var oid asn1.ObjectIdentifier
   197  	if currentTestConfig.securityLevel == 256 {
   198  		oid = oidNamedCurveP256
   199  	} else if currentTestConfig.securityLevel == 384 {
   200  		oid = oidNamedCurveP384
   201  	}
   202  
   203  	key, pubKey, err := currentBCCSP.(*impl).generateECKey(oid, false)
   204  	if err != nil {
   205  		t.Fatalf("Failed generating Key [%s]", err)
   206  	}
   207  
   208  	secret := currentBCCSP.(*impl).getSecretValue(key)
   209  	x, y := pubKey.ScalarBaseMult(secret)
   210  
   211  	if 0 != x.Cmp(pubKey.X) {
   212  		t.Fatal("X does not match")
   213  	}
   214  
   215  	if 0 != y.Cmp(pubKey.Y) {
   216  		t.Fatal("Y does not match")
   217  	}
   218  
   219  	ecPt := elliptic.Marshal(pubKey.Curve, x, y)
   220  	key2, err := currentBCCSP.(*impl).importECKey(oid, secret, ecPt, false, privateKeyFlag)
   221  
   222  	R, S, err := currentBCCSP.(*impl).signP11ECDSA(key2, hash1)
   223  	if err != nil {
   224  		t.Fatalf("Failed signing message [%s]", err)
   225  	}
   226  
   227  	pass, err := currentBCCSP.(*impl).verifyP11ECDSA(key2, hash1, R, S, currentTestConfig.securityLevel/8)
   228  	if err != nil {
   229  		t.Fatalf("Error verifying message 1 [%s]", err)
   230  	}
   231  	if pass == false {
   232  		t.Fatal("Signature should match! [1]")
   233  	}
   234  
   235  	pass, err = currentBCCSP.(*impl).verifyP11ECDSA(key, hash1, R, S, currentTestConfig.securityLevel/8)
   236  	if err != nil {
   237  		t.Fatalf("Error verifying message 2 [%s]", err)
   238  	}
   239  	if pass == false {
   240  		t.Fatal("Signature should match! [2]")
   241  	}
   242  
   243  	pass = ecdsa.Verify(pubKey, hash1, R, S)
   244  	if pass == false {
   245  		t.Fatal("Signature should match with software verification!")
   246  	}
   247  
   248  	pass, err = currentBCCSP.(*impl).verifyP11ECDSA(key, hash2, R, S, currentTestConfig.securityLevel/8)
   249  	if err != nil {
   250  		t.Fatalf("Error verifying message 3 [%s]", err)
   251  	}
   252  
   253  	if pass != false {
   254  		t.Fatal("Signature should not match! [3]")
   255  	}
   256  
   257  	pass = ecdsa.Verify(pubKey, hash2, R, S)
   258  	if pass != false {
   259  		t.Fatal("Signature should not match with software verification!")
   260  	}
   261  }