github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/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 TestKeyGenFailures(t *testing.T) { 32 var testOpts bccsp.KeyGenOpts 33 ki := currentBCCSP 34 _, err := ki.KeyGen(testOpts) 35 assert.Error(t, err) 36 assert.Contains(t, err.Error(), "Invalid Opts parameter. It must not be nil.") 37 } 38 39 func TestLoadLib(t *testing.T) { 40 // Setup PKCS11 library and provide initial set of values 41 lib, pin, label := FindPKCS11Lib() 42 43 // Test for no specified PKCS11 library 44 _, _, _, err := loadLib("", pin, label) 45 assert.Error(t, err) 46 assert.Contains(t, err.Error(), "No PKCS11 library default") 47 48 // Test for invalid PKCS11 library 49 _, _, _, err = loadLib("badLib", pin, label) 50 assert.Error(t, err) 51 assert.Contains(t, err.Error(), "Instantiate failed") 52 53 // Test for invalid label 54 _, _, _, err = loadLib(lib, pin, "badLabel") 55 assert.Error(t, err) 56 assert.Contains(t, err.Error(), "Could not find token with label") 57 58 // Test for no pin 59 _, _, _, err = loadLib(lib, "", label) 60 assert.Error(t, err) 61 assert.Contains(t, err.Error(), "No PIN set") 62 } 63 64 func TestOIDFromNamedCurve(t *testing.T) { 65 // Test for valid OID for P224 66 testOID, boolValue := oidFromNamedCurve(elliptic.P224()) 67 assert.Equal(t, oidNamedCurveP224, testOID, "Did not receive expected OID for elliptic.P224") 68 assert.Equal(t, true, boolValue, "Did not receive a true value when acquiring OID for elliptic.P224") 69 70 // Test for valid OID for P256 71 testOID, boolValue = oidFromNamedCurve(elliptic.P256()) 72 assert.Equal(t, oidNamedCurveP256, testOID, "Did not receive expected OID for elliptic.P256") 73 assert.Equal(t, true, boolValue, "Did not receive a true value when acquiring OID for elliptic.P256") 74 75 // Test for valid OID for P384 76 testOID, boolValue = oidFromNamedCurve(elliptic.P384()) 77 assert.Equal(t, oidNamedCurveP384, testOID, "Did not receive expected OID for elliptic.P384") 78 assert.Equal(t, true, boolValue, "Did not receive a true value when acquiring OID for elliptic.P384") 79 80 // Test for valid OID for P521 81 testOID, boolValue = oidFromNamedCurve(elliptic.P521()) 82 assert.Equal(t, oidNamedCurveP521, testOID, "Did not receive expected OID for elliptic.P521") 83 assert.Equal(t, true, boolValue, "Did not receive a true value when acquiring OID for elliptic.P521") 84 85 var testCurve elliptic.Curve 86 testOID, boolValue = oidFromNamedCurve(testCurve) 87 if testOID != nil { 88 t.Fatal("Expected nil to be returned.") 89 } 90 } 91 92 func TestNamedCurveFromOID(t *testing.T) { 93 // Test for valid P224 elliptic curve 94 namedCurve := namedCurveFromOID(oidNamedCurveP224) 95 assert.Equal(t, elliptic.P224(), namedCurve, "Did not receive expected named curve for oidNamedCurveP224") 96 97 // Test for valid P256 elliptic curve 98 namedCurve = namedCurveFromOID(oidNamedCurveP256) 99 assert.Equal(t, elliptic.P256(), namedCurve, "Did not receive expected named curve for oidNamedCurveP256") 100 101 // Test for valid P256 elliptic curve 102 namedCurve = namedCurveFromOID(oidNamedCurveP384) 103 assert.Equal(t, elliptic.P384(), namedCurve, "Did not receive expected named curve for oidNamedCurveP384") 104 105 // Test for valid P521 elliptic curve 106 namedCurve = namedCurveFromOID(oidNamedCurveP521) 107 assert.Equal(t, elliptic.P521(), namedCurve, "Did not receive expected named curved for oidNamedCurveP521") 108 109 testAsn1Value := asn1.ObjectIdentifier{4, 9, 15, 1} 110 namedCurve = namedCurveFromOID(testAsn1Value) 111 if namedCurve != nil { 112 t.Fatal("Expected nil to be returned.") 113 } 114 } 115 116 func TestPKCS11GetSession(t *testing.T) { 117 var sessions []pkcs11.SessionHandle 118 for i := 0; i < 3*sessionCacheSize; i++ { 119 sessions = append(sessions, currentBCCSP.(*impl).getSession()) 120 } 121 122 // Return all sessions, should leave sessionCacheSize cached 123 for _, session := range sessions { 124 currentBCCSP.(*impl).returnSession(session) 125 } 126 sessions = nil 127 128 // Lets break OpenSession, so non-cached session cannot be opened 129 oldSlot := currentBCCSP.(*impl).slot 130 currentBCCSP.(*impl).slot = ^uint(0) 131 132 // Should be able to get sessionCacheSize cached sessions 133 for i := 0; i < sessionCacheSize; i++ { 134 sessions = append(sessions, currentBCCSP.(*impl).getSession()) 135 } 136 137 // This one should fail 138 assert.Panics(t, func() { 139 currentBCCSP.(*impl).getSession() 140 }, "Should not been able to create another session") 141 142 // Cleanup 143 for _, session := range sessions { 144 currentBCCSP.(*impl).returnSession(session) 145 } 146 currentBCCSP.(*impl).slot = oldSlot 147 } 148 149 func TestPKCS11ECKeySignVerify(t *testing.T) { 150 if currentBCCSP.(*impl).noPrivImport { 151 t.Skip("Key import turned off. Skipping Derivation tests as they currently require Key Import.") 152 } 153 154 msg1 := []byte("This is my very authentic message") 155 msg2 := []byte("This is my very unauthentic message") 156 hash1, _ := currentBCCSP.Hash(msg1, &bccsp.SHAOpts{}) 157 hash2, _ := currentBCCSP.Hash(msg2, &bccsp.SHAOpts{}) 158 159 var oid asn1.ObjectIdentifier 160 if currentTestConfig.securityLevel == 256 { 161 oid = oidNamedCurveP256 162 } else if currentTestConfig.securityLevel == 384 { 163 oid = oidNamedCurveP384 164 } 165 166 key, pubKey, err := currentBCCSP.(*impl).generateECKey(oid, true) 167 if err != nil { 168 t.Fatalf("Failed generating Key [%s]", err) 169 } 170 171 R, S, err := currentBCCSP.(*impl).signP11ECDSA(key, hash1) 172 173 if err != nil { 174 t.Fatalf("Failed signing message [%s]", err) 175 } 176 177 _, _, err = currentBCCSP.(*impl).signP11ECDSA(nil, hash1) 178 assert.Error(t, err) 179 assert.Contains(t, err.Error(), "Private key not found") 180 181 pass, err := currentBCCSP.(*impl).verifyP11ECDSA(key, hash1, R, S, currentTestConfig.securityLevel/8) 182 if err != nil { 183 t.Fatalf("Error verifying message 1 [%s]", err) 184 } 185 if pass == false { 186 t.Fatal("Signature should match!") 187 } 188 189 pass = ecdsa.Verify(pubKey, hash1, R, S) 190 if pass == false { 191 t.Fatal("Signature should match with software verification!") 192 } 193 194 pass, err = currentBCCSP.(*impl).verifyP11ECDSA(key, hash2, R, S, currentTestConfig.securityLevel/8) 195 if err != nil { 196 t.Fatalf("Error verifying message 2 [%s]", err) 197 } 198 199 if pass != false { 200 t.Fatal("Signature should not match!") 201 } 202 203 pass = ecdsa.Verify(pubKey, hash2, R, S) 204 if pass != false { 205 t.Fatal("Signature should not match with software verification!") 206 } 207 } 208 209 func TestPKCS11ECKeyImportSignVerify(t *testing.T) { 210 if currentBCCSP.(*impl).noPrivImport { 211 t.Skip("Key import turned off. Skipping Derivation tests as they currently require Key Import.") 212 } 213 214 msg1 := []byte("This is my very authentic message") 215 msg2 := []byte("This is my very unauthentic message") 216 hash1, _ := currentBCCSP.Hash(msg1, &bccsp.SHAOpts{}) 217 hash2, err := currentBCCSP.Hash(msg2, &bccsp.SHAOpts{}) 218 219 var oid asn1.ObjectIdentifier 220 var key *ecdsa.PrivateKey 221 if currentTestConfig.securityLevel == 256 { 222 oid = oidNamedCurveP256 223 key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 224 if err != nil { 225 t.Fatalf("Failed generating ECDSA key [%s]", err) 226 } 227 } else if currentTestConfig.securityLevel == 384 { 228 oid = oidNamedCurveP384 229 key, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) 230 if err != nil { 231 t.Fatalf("Failed generating ECDSA key [%s]", err) 232 } 233 } 234 235 ecPt := elliptic.Marshal(key.Curve, key.X, key.Y) 236 ski, err := currentBCCSP.(*impl).importECKey(oid, key.D.Bytes(), ecPt, false, privateKeyFlag) 237 if err != nil { 238 t.Fatalf("Failed getting importing EC Public Key [%s]", err) 239 } 240 241 R, S, err := currentBCCSP.(*impl).signP11ECDSA(ski, hash1) 242 243 if err != nil { 244 t.Fatalf("Failed signing message [%s]", err) 245 } 246 247 pass, err := currentBCCSP.(*impl).verifyP11ECDSA(ski, hash1, R, S, currentTestConfig.securityLevel/8) 248 if err != nil { 249 t.Fatalf("Error verifying message 1 [%s]\n%s\n\n%s", err, hex.Dump(R.Bytes()), hex.Dump(S.Bytes())) 250 } 251 if pass == false { 252 t.Fatalf("Signature should match!\n%s\n\n%s", hex.Dump(R.Bytes()), hex.Dump(S.Bytes())) 253 } 254 255 pass = ecdsa.Verify(&key.PublicKey, hash1, R, S) 256 if pass == false { 257 t.Fatal("Signature should match with software verification!") 258 } 259 260 pass, err = currentBCCSP.(*impl).verifyP11ECDSA(ski, hash2, R, S, currentTestConfig.securityLevel/8) 261 if err != nil { 262 t.Fatalf("Error verifying message 2 [%s]", err) 263 } 264 265 if pass != false { 266 t.Fatal("Signature should not match!") 267 } 268 269 pass = ecdsa.Verify(&key.PublicKey, hash2, R, S) 270 if pass != false { 271 t.Fatal("Signature should not match with software verification!") 272 } 273 } 274 275 func TestPKCS11ECKeyExport(t *testing.T) { 276 if currentBCCSP.(*impl).noPrivImport { 277 t.Skip("Key import turned off. Skipping Derivation tests as they currently require Key Import.") 278 } 279 280 msg1 := []byte("This is my very authentic message") 281 msg2 := []byte("This is my very unauthentic message") 282 hash1, _ := currentBCCSP.Hash(msg1, &bccsp.SHAOpts{}) 283 hash2, err := currentBCCSP.Hash(msg2, &bccsp.SHAOpts{}) 284 285 var oid asn1.ObjectIdentifier 286 if currentTestConfig.securityLevel == 256 { 287 oid = oidNamedCurveP256 288 } else if currentTestConfig.securityLevel == 384 { 289 oid = oidNamedCurveP384 290 } 291 292 key, pubKey, err := currentBCCSP.(*impl).generateECKey(oid, false) 293 if err != nil { 294 t.Fatalf("Failed generating Key [%s]", err) 295 } 296 297 secret := currentBCCSP.(*impl).getSecretValue(key) 298 x, y := pubKey.ScalarBaseMult(secret) 299 300 if 0 != x.Cmp(pubKey.X) { 301 t.Fatal("X does not match") 302 } 303 304 if 0 != y.Cmp(pubKey.Y) { 305 t.Fatal("Y does not match") 306 } 307 308 ecPt := elliptic.Marshal(pubKey.Curve, x, y) 309 key2, err := currentBCCSP.(*impl).importECKey(oid, secret, ecPt, false, privateKeyFlag) 310 311 R, S, err := currentBCCSP.(*impl).signP11ECDSA(key2, hash1) 312 if err != nil { 313 t.Fatalf("Failed signing message [%s]", err) 314 } 315 316 pass, err := currentBCCSP.(*impl).verifyP11ECDSA(key2, hash1, R, S, currentTestConfig.securityLevel/8) 317 if err != nil { 318 t.Fatalf("Error verifying message 1 [%s]", err) 319 } 320 if pass == false { 321 t.Fatal("Signature should match! [1]") 322 } 323 324 pass, err = currentBCCSP.(*impl).verifyP11ECDSA(key, hash1, R, S, currentTestConfig.securityLevel/8) 325 if err != nil { 326 t.Fatalf("Error verifying message 2 [%s]", err) 327 } 328 if pass == false { 329 t.Fatal("Signature should match! [2]") 330 } 331 332 pass = ecdsa.Verify(pubKey, hash1, R, S) 333 if pass == false { 334 t.Fatal("Signature should match with software verification!") 335 } 336 337 pass, err = currentBCCSP.(*impl).verifyP11ECDSA(key, hash2, R, S, currentTestConfig.securityLevel/8) 338 if err != nil { 339 t.Fatalf("Error verifying message 3 [%s]", err) 340 } 341 342 if pass != false { 343 t.Fatal("Signature should not match! [3]") 344 } 345 346 pass = ecdsa.Verify(pubKey, hash2, R, S) 347 if pass != false { 348 t.Fatal("Signature should not match with software verification!") 349 } 350 }