1367 lines
37 KiB
Go
1367 lines
37 KiB
Go
/*
|
|
Copyright IBM Corp. All Rights Reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package sw
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"crypto/sha512"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/asn1"
|
|
"fmt"
|
|
"hash"
|
|
"io/ioutil"
|
|
"math/big"
|
|
"net"
|
|
"os"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/hyperledger/fabric/bccsp"
|
|
"github.com/hyperledger/fabric/bccsp/signer"
|
|
"github.com/hyperledger/fabric/bccsp/sw/mocks"
|
|
"github.com/hyperledger/fabric/bccsp/utils"
|
|
"github.com/stretchr/testify/require"
|
|
"golang.org/x/crypto/sha3"
|
|
)
|
|
|
|
var (
|
|
currentTestConfig testConfig
|
|
tempDir string
|
|
)
|
|
|
|
type testConfig struct {
|
|
securityLevel int
|
|
hashFamily string
|
|
}
|
|
|
|
func (tc testConfig) Provider(t *testing.T) (bccsp.BCCSP, bccsp.KeyStore, func()) {
|
|
td, err := ioutil.TempDir(tempDir, "test")
|
|
require.NoError(t, err)
|
|
ks, err := NewFileBasedKeyStore(nil, td, false)
|
|
require.NoError(t, err)
|
|
p, err := NewWithParams(tc.securityLevel, tc.hashFamily, ks)
|
|
require.NoError(t, err)
|
|
return p, ks, func() { os.RemoveAll(td) }
|
|
}
|
|
|
|
func TestMain(m *testing.M) {
|
|
code := -1
|
|
defer func() {
|
|
os.Exit(code)
|
|
}()
|
|
tests := []testConfig{
|
|
{256, "SHA2"},
|
|
{256, "SHA3"},
|
|
{384, "SHA2"},
|
|
{384, "SHA3"},
|
|
}
|
|
|
|
var err error
|
|
tempDir, err = ioutil.TempDir("", "bccsp-sw")
|
|
if err != nil {
|
|
fmt.Printf("Failed to create temporary directory: %s\n\n", err)
|
|
return
|
|
}
|
|
defer os.RemoveAll(tempDir)
|
|
|
|
for _, config := range tests {
|
|
currentTestConfig = config
|
|
code = m.Run()
|
|
if code != 0 {
|
|
fmt.Printf("Failed testing at [%d, %s]", config.securityLevel, config.hashFamily)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestInvalidNewParameter(t *testing.T) {
|
|
t.Parallel()
|
|
_, ks, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
r, err := NewWithParams(0, "SHA2", ks)
|
|
if err == nil {
|
|
t.Fatal("Error should be different from nil in this case")
|
|
}
|
|
if r != nil {
|
|
t.Fatal("Return value should be equal to nil in this case")
|
|
}
|
|
|
|
r, err = NewWithParams(256, "SHA8", ks)
|
|
if err == nil {
|
|
t.Fatal("Error should be different from nil in this case")
|
|
}
|
|
if r != nil {
|
|
t.Fatal("Return value should be equal to nil in this case")
|
|
}
|
|
|
|
r, err = NewWithParams(256, "SHA2", nil)
|
|
if err == nil {
|
|
t.Fatal("Error should be different from nil in this case")
|
|
}
|
|
if r != nil {
|
|
t.Fatal("Return value should be equal to nil in this case")
|
|
}
|
|
|
|
r, err = NewWithParams(0, "SHA3", nil)
|
|
if err == nil {
|
|
t.Fatal("Error should be different from nil in this case")
|
|
}
|
|
if r != nil {
|
|
t.Fatal("Return value should be equal to nil in this case")
|
|
}
|
|
|
|
r, err = NewDefaultSecurityLevel("")
|
|
if err == nil {
|
|
t.Fatal("Error should be different from nil in this case")
|
|
}
|
|
if r != nil {
|
|
t.Fatal("Return value should be equal to nil in this case")
|
|
}
|
|
}
|
|
|
|
func TestInvalidSKI(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.GetKey(nil)
|
|
if err == nil {
|
|
t.Fatal("Error should be different from nil in this case")
|
|
}
|
|
if k != nil {
|
|
t.Fatal("Return value should be equal to nil in this case")
|
|
}
|
|
|
|
k, err = provider.GetKey([]byte{0, 1, 2, 3, 4, 5, 6})
|
|
if err == nil {
|
|
t.Fatal("Error should be different from nil in this case")
|
|
}
|
|
if k != nil {
|
|
t.Fatal("Return value should be equal to nil in this case")
|
|
}
|
|
}
|
|
|
|
func TestKeyGenECDSAOpts(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
// Curve P256
|
|
k, err := provider.KeyGen(&bccsp.ECDSAP256KeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA P256 key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed generating ECDSA P256 key. Key must be different from nil")
|
|
}
|
|
if !k.Private() {
|
|
t.Fatal("Failed generating ECDSA P256 key. Key should be private")
|
|
}
|
|
if k.Symmetric() {
|
|
t.Fatal("Failed generating ECDSA P256 key. Key should be asymmetric")
|
|
}
|
|
|
|
ecdsaKey := k.(*ecdsaPrivateKey).privKey
|
|
if !elliptic.P256().IsOnCurve(ecdsaKey.X, ecdsaKey.Y) {
|
|
t.Fatal("P256 generated key in invalid. The public key must be on the P256 curve.")
|
|
}
|
|
if elliptic.P256() != ecdsaKey.Curve {
|
|
t.Fatal("P256 generated key in invalid. The curve must be P256.")
|
|
}
|
|
if ecdsaKey.D.Cmp(big.NewInt(0)) == 0 {
|
|
t.Fatal("P256 generated key in invalid. Private key must be different from 0.")
|
|
}
|
|
|
|
// Curve P384
|
|
k, err = provider.KeyGen(&bccsp.ECDSAP384KeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA P384 key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed generating ECDSA P384 key. Key must be different from nil")
|
|
}
|
|
if !k.Private() {
|
|
t.Fatal("Failed generating ECDSA P384 key. Key should be private")
|
|
}
|
|
if k.Symmetric() {
|
|
t.Fatal("Failed generating ECDSA P384 key. Key should be asymmetric")
|
|
}
|
|
|
|
ecdsaKey = k.(*ecdsaPrivateKey).privKey
|
|
if !elliptic.P384().IsOnCurve(ecdsaKey.X, ecdsaKey.Y) {
|
|
t.Fatal("P256 generated key in invalid. The public key must be on the P384 curve.")
|
|
}
|
|
if elliptic.P384() != ecdsaKey.Curve {
|
|
t.Fatal("P256 generated key in invalid. The curve must be P384.")
|
|
}
|
|
if ecdsaKey.D.Cmp(big.NewInt(0)) == 0 {
|
|
t.Fatal("P256 generated key in invalid. Private key must be different from 0.")
|
|
}
|
|
}
|
|
|
|
func TestKeyGenAESOpts(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
// AES 128
|
|
k, err := provider.KeyGen(&bccsp.AES128KeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating AES 128 key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed generating AES 128 key. Key must be different from nil")
|
|
}
|
|
if !k.Private() {
|
|
t.Fatal("Failed generating AES 128 key. Key should be private")
|
|
}
|
|
if !k.Symmetric() {
|
|
t.Fatal("Failed generating AES 128 key. Key should be symmetric")
|
|
}
|
|
|
|
aesKey := k.(*aesPrivateKey).privKey
|
|
if len(aesKey) != 16 {
|
|
t.Fatal("AES Key generated key in invalid. The key must have length 16.")
|
|
}
|
|
|
|
// AES 192
|
|
k, err = provider.KeyGen(&bccsp.AES192KeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating AES 192 key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed generating AES 192 key. Key must be different from nil")
|
|
}
|
|
if !k.Private() {
|
|
t.Fatal("Failed generating AES 192 key. Key should be private")
|
|
}
|
|
if !k.Symmetric() {
|
|
t.Fatal("Failed generating AES 192 key. Key should be symmetric")
|
|
}
|
|
|
|
aesKey = k.(*aesPrivateKey).privKey
|
|
if len(aesKey) != 24 {
|
|
t.Fatal("AES Key generated key in invalid. The key must have length 16.")
|
|
}
|
|
|
|
// AES 256
|
|
k, err = provider.KeyGen(&bccsp.AES256KeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating AES 256 key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed generating AES 256 key. Key must be different from nil")
|
|
}
|
|
if !k.Private() {
|
|
t.Fatal("Failed generating AES 256 key. Key should be private")
|
|
}
|
|
if !k.Symmetric() {
|
|
t.Fatal("Failed generating AES 256 key. Key should be symmetric")
|
|
}
|
|
|
|
aesKey = k.(*aesPrivateKey).privKey
|
|
if len(aesKey) != 32 {
|
|
t.Fatal("AES Key generated key in invalid. The key must have length 16.")
|
|
}
|
|
}
|
|
|
|
func TestECDSAKeyGenEphemeral(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: true})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed generating ECDSA key. Key must be different from nil")
|
|
}
|
|
if !k.Private() {
|
|
t.Fatal("Failed generating ECDSA key. Key should be private")
|
|
}
|
|
if k.Symmetric() {
|
|
t.Fatal("Failed generating ECDSA key. Key should be asymmetric")
|
|
}
|
|
raw, err := k.Bytes()
|
|
if err == nil {
|
|
t.Fatal("Failed marshalling to bytes. Marshalling must fail.")
|
|
}
|
|
if len(raw) != 0 {
|
|
t.Fatal("Failed marshalling to bytes. Output should be 0 bytes")
|
|
}
|
|
pk, err := k.PublicKey()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting corresponding public key [%s]", err)
|
|
}
|
|
if pk == nil {
|
|
t.Fatal("Public key must be different from nil.")
|
|
}
|
|
}
|
|
|
|
func TestECDSAPrivateKeySKI(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
ski := k.SKI()
|
|
if len(ski) == 0 {
|
|
t.Fatal("SKI not valid. Zero length.")
|
|
}
|
|
}
|
|
|
|
func TestECDSAKeyGenNonEphemeral(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed generating ECDSA key. Key must be different from nil")
|
|
}
|
|
if !k.Private() {
|
|
t.Fatal("Failed generating ECDSA key. Key should be private")
|
|
}
|
|
if k.Symmetric() {
|
|
t.Fatal("Failed generating ECDSA key. Key should be asymmetric")
|
|
}
|
|
}
|
|
|
|
func TestECDSAGetKeyBySKI(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
k2, err := provider.GetKey(k.SKI())
|
|
if err != nil {
|
|
t.Fatalf("Failed getting ECDSA key [%s]", err)
|
|
}
|
|
if k2 == nil {
|
|
t.Fatal("Failed getting ECDSA key. Key must be different from nil")
|
|
}
|
|
if !k2.Private() {
|
|
t.Fatal("Failed getting ECDSA key. Key should be private")
|
|
}
|
|
if k2.Symmetric() {
|
|
t.Fatal("Failed getting ECDSA key. Key should be asymmetric")
|
|
}
|
|
|
|
// Check that the SKIs are the same
|
|
if !bytes.Equal(k.SKI(), k2.SKI()) {
|
|
t.Fatalf("SKIs are different [%x]!=[%x]", k.SKI(), k2.SKI())
|
|
}
|
|
}
|
|
|
|
func TestECDSAPublicKeyFromPrivateKey(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
pk, err := k.PublicKey()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting public key from private ECDSA key [%s]", err)
|
|
}
|
|
if pk == nil {
|
|
t.Fatal("Failed getting public key from private ECDSA key. Key must be different from nil")
|
|
}
|
|
if pk.Private() {
|
|
t.Fatal("Failed generating ECDSA key. Key should be public")
|
|
}
|
|
if pk.Symmetric() {
|
|
t.Fatal("Failed generating ECDSA key. Key should be asymmetric")
|
|
}
|
|
}
|
|
|
|
func TestECDSAPublicKeyBytes(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
pk, err := k.PublicKey()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting public key from private ECDSA key [%s]", err)
|
|
}
|
|
|
|
raw, err := pk.Bytes()
|
|
if err != nil {
|
|
t.Fatalf("Failed marshalling ECDSA public key [%s]", err)
|
|
}
|
|
if len(raw) == 0 {
|
|
t.Fatal("Failed marshalling ECDSA public key. Zero length")
|
|
}
|
|
}
|
|
|
|
func TestECDSAPublicKeySKI(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
pk, err := k.PublicKey()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting public key from private ECDSA key [%s]", err)
|
|
}
|
|
|
|
ski := pk.SKI()
|
|
if len(ski) == 0 {
|
|
t.Fatal("SKI not valid. Zero length.")
|
|
}
|
|
}
|
|
|
|
func TestECDSAKeyReRand(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed re-randomizing ECDSA key. Re-randomized Key must be different from nil")
|
|
}
|
|
|
|
reRandomizedKey, err := provider.KeyDeriv(k, &bccsp.ECDSAReRandKeyOpts{Temporary: false, Expansion: []byte{1}})
|
|
if err != nil {
|
|
t.Fatalf("Failed re-randomizing ECDSA key [%s]", err)
|
|
}
|
|
if !reRandomizedKey.Private() {
|
|
t.Fatal("Failed re-randomizing ECDSA key. Re-randomized Key should be private")
|
|
}
|
|
if reRandomizedKey.Symmetric() {
|
|
t.Fatal("Failed re-randomizing ECDSA key. Re-randomized Key should be asymmetric")
|
|
}
|
|
|
|
k2, err := k.PublicKey()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting public ECDSA key from private [%s]", err)
|
|
}
|
|
if k2 == nil {
|
|
t.Fatal("Failed re-randomizing ECDSA key. Re-randomized Key must be different from nil")
|
|
}
|
|
|
|
reRandomizedKey2, err := provider.KeyDeriv(k2, &bccsp.ECDSAReRandKeyOpts{Temporary: false, Expansion: []byte{1}})
|
|
if err != nil {
|
|
t.Fatalf("Failed re-randomizing ECDSA key [%s]", err)
|
|
}
|
|
|
|
if reRandomizedKey2.Private() {
|
|
t.Fatal("Re-randomized public Key must remain public")
|
|
}
|
|
if reRandomizedKey2.Symmetric() {
|
|
t.Fatal("Re-randomized ECDSA asymmetric key must remain asymmetric")
|
|
}
|
|
|
|
if false == bytes.Equal(reRandomizedKey.SKI(), reRandomizedKey2.SKI()) {
|
|
t.Fatal("Re-randomized ECDSA Private- or Public-Keys must end up having the same SKI")
|
|
}
|
|
}
|
|
|
|
func TestECDSASign(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
msg := []byte("Hello World")
|
|
|
|
digest, err := provider.Hash(msg, &bccsp.SHAOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed computing HASH [%s]", err)
|
|
}
|
|
|
|
signature, err := provider.Sign(k, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA signature [%s]", err)
|
|
}
|
|
if len(signature) == 0 {
|
|
t.Fatal("Failed generating ECDSA key. Signature must be different from nil")
|
|
}
|
|
}
|
|
|
|
func TestECDSAVerify(t *testing.T) {
|
|
t.Parallel()
|
|
provider, ks, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
msg := []byte("Hello World")
|
|
|
|
digest, err := provider.Hash(msg, &bccsp.SHAOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed computing HASH [%s]", err)
|
|
}
|
|
|
|
signature, err := provider.Sign(k, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA signature [%s]", err)
|
|
}
|
|
|
|
valid, err := provider.Verify(k, signature, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed verifying ECDSA signature [%s]", err)
|
|
}
|
|
if !valid {
|
|
t.Fatal("Failed verifying ECDSA signature. Signature not valid.")
|
|
}
|
|
|
|
pk, err := k.PublicKey()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting corresponding public key [%s]", err)
|
|
}
|
|
|
|
valid, err = provider.Verify(pk, signature, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed verifying ECDSA signature [%s]", err)
|
|
}
|
|
if !valid {
|
|
t.Fatal("Failed verifying ECDSA signature. Signature not valid.")
|
|
}
|
|
|
|
// Store public key
|
|
err = ks.StoreKey(pk)
|
|
if err != nil {
|
|
t.Fatalf("Failed storing corresponding public key [%s]", err)
|
|
}
|
|
|
|
pk2, err := ks.GetKey(pk.SKI())
|
|
if err != nil {
|
|
t.Fatalf("Failed retrieving corresponding public key [%s]", err)
|
|
}
|
|
|
|
valid, err = provider.Verify(pk2, signature, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed verifying ECDSA signature [%s]", err)
|
|
}
|
|
if !valid {
|
|
t.Fatal("Failed verifying ECDSA signature. Signature not valid.")
|
|
}
|
|
}
|
|
|
|
func TestECDSAKeyDeriv(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
reRandomizedKey, err := provider.KeyDeriv(k, &bccsp.ECDSAReRandKeyOpts{Temporary: false, Expansion: []byte{1}})
|
|
if err != nil {
|
|
t.Fatalf("Failed re-randomizing ECDSA key [%s]", err)
|
|
}
|
|
|
|
msg := []byte("Hello World")
|
|
|
|
digest, err := provider.Hash(msg, &bccsp.SHAOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed computing HASH [%s]", err)
|
|
}
|
|
|
|
signature, err := provider.Sign(reRandomizedKey, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA signature [%s]", err)
|
|
}
|
|
|
|
valid, err := provider.Verify(reRandomizedKey, signature, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed verifying ECDSA signature [%s]", err)
|
|
}
|
|
if !valid {
|
|
t.Fatal("Failed verifying ECDSA signature. Signature not valid.")
|
|
}
|
|
}
|
|
|
|
func TestECDSAKeyImportFromExportedKey(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
// Generate an ECDSA key
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
// Export the public key
|
|
pk, err := k.PublicKey()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting ECDSA public key [%s]", err)
|
|
}
|
|
|
|
pkRaw, err := pk.Bytes()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting ECDSA raw public key [%s]", err)
|
|
}
|
|
|
|
// Import the exported public key
|
|
pk2, err := provider.KeyImport(pkRaw, &bccsp.ECDSAPKIXPublicKeyImportOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed importing ECDSA public key [%s]", err)
|
|
}
|
|
if pk2 == nil {
|
|
t.Fatal("Failed importing ECDSA public key. Return BCCSP key cannot be nil.")
|
|
}
|
|
|
|
// Sign and verify with the imported public key
|
|
msg := []byte("Hello World")
|
|
|
|
digest, err := provider.Hash(msg, &bccsp.SHAOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed computing HASH [%s]", err)
|
|
}
|
|
|
|
signature, err := provider.Sign(k, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA signature [%s]", err)
|
|
}
|
|
|
|
valid, err := provider.Verify(pk2, signature, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed verifying ECDSA signature [%s]", err)
|
|
}
|
|
if !valid {
|
|
t.Fatal("Failed verifying ECDSA signature. Signature not valid.")
|
|
}
|
|
}
|
|
|
|
func TestECDSAKeyImportFromECDSAPublicKey(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
// Generate an ECDSA key
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
// Export the public key
|
|
pk, err := k.PublicKey()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting ECDSA public key [%s]", err)
|
|
}
|
|
|
|
pkRaw, err := pk.Bytes()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting ECDSA raw public key [%s]", err)
|
|
}
|
|
|
|
pub, err := derToPublicKey(pkRaw)
|
|
if err != nil {
|
|
t.Fatalf("Failed converting raw to ecdsa.PublicKey [%s]", err)
|
|
}
|
|
|
|
// Import the ecdsa.PublicKey
|
|
pk2, err := provider.KeyImport(pub, &bccsp.ECDSAGoPublicKeyImportOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed importing ECDSA public key [%s]", err)
|
|
}
|
|
if pk2 == nil {
|
|
t.Fatal("Failed importing ECDSA public key. Return BCCSP key cannot be nil.")
|
|
}
|
|
|
|
// Sign and verify with the imported public key
|
|
msg := []byte("Hello World")
|
|
|
|
digest, err := provider.Hash(msg, &bccsp.SHAOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed computing HASH [%s]", err)
|
|
}
|
|
|
|
signature, err := provider.Sign(k, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA signature [%s]", err)
|
|
}
|
|
|
|
valid, err := provider.Verify(pk2, signature, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed verifying ECDSA signature [%s]", err)
|
|
}
|
|
if !valid {
|
|
t.Fatal("Failed verifying ECDSA signature. Signature not valid.")
|
|
}
|
|
}
|
|
|
|
func TestECDSAKeyImportFromECDSAPrivateKey(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
// Generate an ECDSA key, default is P256
|
|
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
// Import the ecdsa.PrivateKey
|
|
priv, err := privateKeyToDER(key)
|
|
if err != nil {
|
|
t.Fatalf("Failed converting raw to ecdsa.PrivateKey [%s]", err)
|
|
}
|
|
|
|
sk, err := provider.KeyImport(priv, &bccsp.ECDSAPrivateKeyImportOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed importing ECDSA private key [%s]", err)
|
|
}
|
|
if sk == nil {
|
|
t.Fatal("Failed importing ECDSA private key. Return BCCSP key cannot be nil.")
|
|
}
|
|
|
|
// Import the ecdsa.PublicKey
|
|
pub, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed converting raw to ecdsa.PublicKey [%s]", err)
|
|
}
|
|
|
|
pk, err := provider.KeyImport(pub, &bccsp.ECDSAPKIXPublicKeyImportOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed importing ECDSA public key [%s]", err)
|
|
}
|
|
if pk == nil {
|
|
t.Fatal("Failed importing ECDSA public key. Return BCCSP key cannot be nil.")
|
|
}
|
|
|
|
// Sign and verify with the imported public key
|
|
msg := []byte("Hello World")
|
|
|
|
digest, err := provider.Hash(msg, &bccsp.SHAOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed computing HASH [%s]", err)
|
|
}
|
|
|
|
signature, err := provider.Sign(sk, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA signature [%s]", err)
|
|
}
|
|
|
|
valid, err := provider.Verify(pk, signature, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed verifying ECDSA signature [%s]", err)
|
|
}
|
|
if !valid {
|
|
t.Fatal("Failed verifying ECDSA signature. Signature not valid.")
|
|
}
|
|
}
|
|
|
|
func TestKeyImportFromX509ECDSAPublicKey(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
// Generate an ECDSA key
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
// Generate a self-signed certificate
|
|
testExtKeyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}
|
|
testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}}
|
|
extraExtensionData := []byte("extra extension")
|
|
commonName := "test.example.com"
|
|
template := x509.Certificate{
|
|
SerialNumber: big.NewInt(1),
|
|
Subject: pkix.Name{
|
|
CommonName: commonName,
|
|
Organization: []string{"Σ Acme Co"},
|
|
Country: []string{"US"},
|
|
ExtraNames: []pkix.AttributeTypeAndValue{
|
|
{
|
|
Type: []int{2, 5, 4, 42},
|
|
Value: "Gopher",
|
|
},
|
|
// This should override the Country, above.
|
|
{
|
|
Type: []int{2, 5, 4, 6},
|
|
Value: "NL",
|
|
},
|
|
},
|
|
},
|
|
NotBefore: time.Now().Add(-1 * time.Hour),
|
|
NotAfter: time.Now().Add(1 * time.Hour),
|
|
|
|
SignatureAlgorithm: x509.ECDSAWithSHA256,
|
|
|
|
SubjectKeyId: []byte{1, 2, 3, 4},
|
|
KeyUsage: x509.KeyUsageCertSign,
|
|
|
|
ExtKeyUsage: testExtKeyUsage,
|
|
UnknownExtKeyUsage: testUnknownExtKeyUsage,
|
|
|
|
BasicConstraintsValid: true,
|
|
IsCA: true,
|
|
|
|
OCSPServer: []string{"http://ocurrentBCCSP.example.com"},
|
|
IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"},
|
|
|
|
DNSNames: []string{"test.example.com"},
|
|
EmailAddresses: []string{"gopher@golang.org"},
|
|
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
|
|
|
|
PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}},
|
|
PermittedDNSDomains: []string{".example.com", "example.com"},
|
|
|
|
CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"},
|
|
|
|
ExtraExtensions: []pkix.Extension{
|
|
{
|
|
Id: []int{1, 2, 3, 4},
|
|
Value: extraExtensionData,
|
|
},
|
|
},
|
|
}
|
|
|
|
cryptoSigner, err := signer.New(provider, k)
|
|
if err != nil {
|
|
t.Fatalf("Failed initializing CyrptoSigner [%s]", err)
|
|
}
|
|
|
|
// Export the public key
|
|
pk, err := k.PublicKey()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting ECDSA public key [%s]", err)
|
|
}
|
|
|
|
pkRaw, err := pk.Bytes()
|
|
if err != nil {
|
|
t.Fatalf("Failed getting ECDSA raw public key [%s]", err)
|
|
}
|
|
|
|
pub, err := derToPublicKey(pkRaw)
|
|
if err != nil {
|
|
t.Fatalf("Failed converting raw to ECDSA.PublicKey [%s]", err)
|
|
}
|
|
|
|
certRaw, err := x509.CreateCertificate(rand.Reader, &template, &template, pub, cryptoSigner)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating self-signed certificate [%s]", err)
|
|
}
|
|
|
|
cert, err := x509.ParseCertificate(certRaw)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating X509 certificate object from raw [%s]", err)
|
|
}
|
|
|
|
// Import the certificate's public key
|
|
pk2, err := provider.KeyImport(cert, &bccsp.X509PublicKeyImportOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed importing ECDSA public key [%s]", err)
|
|
}
|
|
if pk2 == nil {
|
|
t.Fatal("Failed importing ECDSA public key. Return BCCSP key cannot be nil.")
|
|
}
|
|
|
|
// Sign and verify with the imported public key
|
|
msg := []byte("Hello World")
|
|
|
|
digest, err := provider.Hash(msg, &bccsp.SHAOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed computing HASH [%s]", err)
|
|
}
|
|
|
|
signature, err := provider.Sign(k, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA signature [%s]", err)
|
|
}
|
|
|
|
valid, err := provider.Verify(pk2, signature, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed verifying ECDSA signature [%s]", err)
|
|
}
|
|
if !valid {
|
|
t.Fatal("Failed verifying ECDSA signature. Signature not valid.")
|
|
}
|
|
}
|
|
|
|
func TestECDSASignatureEncoding(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
v := []byte{0x30, 0x07, 0x02, 0x01, 0x8F, 0x02, 0x02, 0xff, 0xf1}
|
|
_, err := asn1.Unmarshal(v, &utils.ECDSASignature{})
|
|
if err == nil {
|
|
t.Fatalf("Unmarshalling should fail for [% x]", v)
|
|
}
|
|
t.Logf("Unmarshalling correctly failed for [% x] [%s]", v, err)
|
|
|
|
v = []byte{0x30, 0x07, 0x02, 0x01, 0x8F, 0x02, 0x02, 0x00, 0x01}
|
|
_, err = asn1.Unmarshal(v, &utils.ECDSASignature{})
|
|
if err == nil {
|
|
t.Fatalf("Unmarshalling should fail for [% x]", v)
|
|
}
|
|
t.Logf("Unmarshalling correctly failed for [% x] [%s]", v, err)
|
|
|
|
v = []byte{0x30, 0x07, 0x02, 0x01, 0x8F, 0x02, 0x81, 0x01, 0x01}
|
|
_, err = asn1.Unmarshal(v, &utils.ECDSASignature{})
|
|
if err == nil {
|
|
t.Fatalf("Unmarshalling should fail for [% x]", v)
|
|
}
|
|
t.Logf("Unmarshalling correctly failed for [% x] [%s]", v, err)
|
|
|
|
v = []byte{0x30, 0x07, 0x02, 0x01, 0x8F, 0x02, 0x81, 0x01, 0x8F}
|
|
_, err = asn1.Unmarshal(v, &utils.ECDSASignature{})
|
|
if err == nil {
|
|
t.Fatalf("Unmarshalling should fail for [% x]", v)
|
|
}
|
|
t.Logf("Unmarshalling correctly failed for [% x] [%s]", v, err)
|
|
|
|
v = []byte{0x30, 0x0A, 0x02, 0x01, 0x8F, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x8F}
|
|
_, err = asn1.Unmarshal(v, &utils.ECDSASignature{})
|
|
if err == nil {
|
|
t.Fatalf("Unmarshalling should fail for [% x]", v)
|
|
}
|
|
t.Logf("Unmarshalling correctly failed for [% x] [%s]", v, err)
|
|
}
|
|
|
|
func TestECDSALowS(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
// Ensure that signature with low-S are generated
|
|
k, err := provider.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA key [%s]", err)
|
|
}
|
|
|
|
msg := []byte("Hello World")
|
|
|
|
digest, err := provider.Hash(msg, &bccsp.SHAOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed computing HASH [%s]", err)
|
|
}
|
|
|
|
signature, err := provider.Sign(k, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating ECDSA signature [%s]", err)
|
|
}
|
|
|
|
_, S, err := utils.UnmarshalECDSASignature(signature)
|
|
if err != nil {
|
|
t.Fatalf("Failed unmarshalling signature [%s]", err)
|
|
}
|
|
|
|
if S.Cmp(utils.GetCurveHalfOrdersAt(k.(*ecdsaPrivateKey).privKey.Curve)) >= 0 {
|
|
t.Fatal("Invalid signature. It must have low-S")
|
|
}
|
|
|
|
valid, err := provider.Verify(k, signature, digest, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed verifying ECDSA signature [%s]", err)
|
|
}
|
|
if !valid {
|
|
t.Fatal("Failed verifying ECDSA signature. Signature not valid.")
|
|
}
|
|
|
|
// Ensure that signature with high-S are rejected.
|
|
var R *big.Int
|
|
for {
|
|
R, S, err = ecdsa.Sign(rand.Reader, k.(*ecdsaPrivateKey).privKey, digest)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating signature [%s]", err)
|
|
}
|
|
|
|
if S.Cmp(utils.GetCurveHalfOrdersAt(k.(*ecdsaPrivateKey).privKey.Curve)) > 0 {
|
|
break
|
|
}
|
|
}
|
|
|
|
sig, err := utils.MarshalECDSASignature(R, S)
|
|
if err != nil {
|
|
t.Fatalf("Failing unmarshalling signature [%s]", err)
|
|
}
|
|
|
|
valid, err = provider.Verify(k, sig, digest, nil)
|
|
if err == nil {
|
|
t.Fatal("Failed verifying ECDSA signature. It must fail for a signature with high-S")
|
|
}
|
|
if valid {
|
|
t.Fatal("Failed verifying ECDSA signature. It must fail for a signature with high-S")
|
|
}
|
|
}
|
|
|
|
func TestAESKeyGen(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.AESKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating AES_256 key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed generating AES_256 key. Key must be different from nil")
|
|
}
|
|
if !k.Private() {
|
|
t.Fatal("Failed generating AES_256 key. Key should be private")
|
|
}
|
|
if !k.Symmetric() {
|
|
t.Fatal("Failed generating AES_256 key. Key should be symmetric")
|
|
}
|
|
|
|
pk, err := k.PublicKey()
|
|
if err == nil {
|
|
t.Fatal("Error should be different from nil in this case")
|
|
}
|
|
if pk != nil {
|
|
t.Fatal("Return value should be equal to nil in this case")
|
|
}
|
|
}
|
|
|
|
func TestAESEncrypt(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.AESKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating AES_256 key [%s]", err)
|
|
}
|
|
|
|
ct, err := provider.Encrypt(k, []byte("Hello World"), &bccsp.AESCBCPKCS7ModeOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed encrypting [%s]", err)
|
|
}
|
|
if len(ct) == 0 {
|
|
t.Fatal("Failed encrypting. Nil ciphertext")
|
|
}
|
|
}
|
|
|
|
func TestAESDecrypt(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.AESKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating AES_256 key [%s]", err)
|
|
}
|
|
|
|
msg := []byte("Hello World")
|
|
|
|
ct, err := provider.Encrypt(k, msg, &bccsp.AESCBCPKCS7ModeOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed encrypting [%s]", err)
|
|
}
|
|
|
|
pt, err := provider.Decrypt(k, ct, bccsp.AESCBCPKCS7ModeOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed decrypting [%s]", err)
|
|
}
|
|
if len(ct) == 0 {
|
|
t.Fatal("Failed decrypting. Nil plaintext")
|
|
}
|
|
|
|
if !bytes.Equal(msg, pt) {
|
|
t.Fatalf("Failed decrypting. Decrypted plaintext is different from the original. [%x][%x]", msg, pt)
|
|
}
|
|
}
|
|
|
|
func TestHMACTruncated256KeyDerivOverAES256Key(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.AESKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating AES_256 key [%s]", err)
|
|
}
|
|
|
|
hmcaedKey, err := provider.KeyDeriv(k, &bccsp.HMACTruncated256AESDeriveKeyOpts{Temporary: false, Arg: []byte{1}})
|
|
if err != nil {
|
|
t.Fatalf("Failed HMACing AES_256 key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed HMACing AES_256 key. HMACed Key must be different from nil")
|
|
}
|
|
if !hmcaedKey.Private() {
|
|
t.Fatal("Failed HMACing AES_256 key. HMACed Key should be private")
|
|
}
|
|
if !hmcaedKey.Symmetric() {
|
|
t.Fatal("Failed HMACing AES_256 key. HMACed Key should be asymmetric")
|
|
}
|
|
raw, err := hmcaedKey.Bytes()
|
|
if err == nil {
|
|
t.Fatal("Failed marshalling to bytes. Operation must be forbidden")
|
|
}
|
|
if len(raw) != 0 {
|
|
t.Fatal("Failed marshalling to bytes. Operation must return 0 bytes")
|
|
}
|
|
|
|
msg := []byte("Hello World")
|
|
|
|
ct, err := provider.Encrypt(hmcaedKey, msg, &bccsp.AESCBCPKCS7ModeOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed encrypting [%s]", err)
|
|
}
|
|
|
|
pt, err := provider.Decrypt(hmcaedKey, ct, bccsp.AESCBCPKCS7ModeOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed decrypting [%s]", err)
|
|
}
|
|
if len(ct) == 0 {
|
|
t.Fatal("Failed decrypting. Nil plaintext")
|
|
}
|
|
|
|
if !bytes.Equal(msg, pt) {
|
|
t.Fatalf("Failed decrypting. Decrypted plaintext is different from the original. [%x][%x]", msg, pt)
|
|
}
|
|
}
|
|
|
|
func TestHMACKeyDerivOverAES256Key(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.AESKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating AES_256 key [%s]", err)
|
|
}
|
|
|
|
hmcaedKey, err := provider.KeyDeriv(k, &bccsp.HMACDeriveKeyOpts{Temporary: false, Arg: []byte{1}})
|
|
if err != nil {
|
|
t.Fatalf("Failed HMACing AES_256 key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed HMACing AES_256 key. HMACed Key must be different from nil")
|
|
}
|
|
if !hmcaedKey.Private() {
|
|
t.Fatal("Failed HMACing AES_256 key. HMACed Key should be private")
|
|
}
|
|
if !hmcaedKey.Symmetric() {
|
|
t.Fatal("Failed HMACing AES_256 key. HMACed Key should be asymmetric")
|
|
}
|
|
raw, err := hmcaedKey.Bytes()
|
|
if err != nil {
|
|
t.Fatalf("Failed marshalling to bytes [%s]", err)
|
|
}
|
|
if len(raw) == 0 {
|
|
t.Fatal("Failed marshalling to bytes. 0 bytes")
|
|
}
|
|
}
|
|
|
|
func TestAES256KeyImport(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
raw, err := GetRandomBytes(32)
|
|
if err != nil {
|
|
t.Fatalf("Failed generating AES key [%s]", err)
|
|
}
|
|
|
|
k, err := provider.KeyImport(raw, &bccsp.AES256ImportKeyOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed importing AES_256 key [%s]", err)
|
|
}
|
|
if k == nil {
|
|
t.Fatal("Failed importing AES_256 key. Imported Key must be different from nil")
|
|
}
|
|
if !k.Private() {
|
|
t.Fatal("Failed HMACing AES_256 key. Imported Key should be private")
|
|
}
|
|
if !k.Symmetric() {
|
|
t.Fatal("Failed HMACing AES_256 key. Imported Key should be asymmetric")
|
|
}
|
|
raw, err = k.Bytes()
|
|
if err == nil {
|
|
t.Fatal("Failed marshalling to bytes. Marshalling must fail.")
|
|
}
|
|
if len(raw) != 0 {
|
|
t.Fatal("Failed marshalling to bytes. Output should be 0 bytes")
|
|
}
|
|
|
|
msg := []byte("Hello World")
|
|
|
|
ct, err := provider.Encrypt(k, msg, &bccsp.AESCBCPKCS7ModeOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed encrypting [%s]", err)
|
|
}
|
|
|
|
pt, err := provider.Decrypt(k, ct, bccsp.AESCBCPKCS7ModeOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed decrypting [%s]", err)
|
|
}
|
|
if len(ct) == 0 {
|
|
t.Fatal("Failed decrypting. Nil plaintext")
|
|
}
|
|
|
|
if !bytes.Equal(msg, pt) {
|
|
t.Fatalf("Failed decrypting. Decrypted plaintext is different from the original. [%x][%x]", msg, pt)
|
|
}
|
|
}
|
|
|
|
func TestAES256KeyImportBadPaths(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
_, err := provider.KeyImport(nil, &bccsp.AES256ImportKeyOpts{Temporary: false})
|
|
if err == nil {
|
|
t.Fatal("Failed importing key. Must fail on importing nil key")
|
|
}
|
|
|
|
_, err = provider.KeyImport([]byte{1}, &bccsp.AES256ImportKeyOpts{Temporary: false})
|
|
if err == nil {
|
|
t.Fatal("Failed importing key. Must fail on importing a key with an invalid length")
|
|
}
|
|
}
|
|
|
|
func TestAES256KeyGenSKI(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
k, err := provider.KeyGen(&bccsp.AESKeyGenOpts{Temporary: false})
|
|
if err != nil {
|
|
t.Fatalf("Failed generating AES_256 key [%s]", err)
|
|
}
|
|
|
|
k2, err := provider.GetKey(k.SKI())
|
|
if err != nil {
|
|
t.Fatalf("Failed getting AES_256 key [%s]", err)
|
|
}
|
|
if k2 == nil {
|
|
t.Fatal("Failed getting AES_256 key. Key must be different from nil")
|
|
}
|
|
if !k2.Private() {
|
|
t.Fatal("Failed getting AES_256 key. Key should be private")
|
|
}
|
|
if !k2.Symmetric() {
|
|
t.Fatal("Failed getting AES_256 key. Key should be symmetric")
|
|
}
|
|
|
|
// Check that the SKIs are the same
|
|
if !bytes.Equal(k.SKI(), k2.SKI()) {
|
|
t.Fatalf("SKIs are different [%x]!=[%x]", k.SKI(), k2.SKI())
|
|
}
|
|
}
|
|
|
|
func TestSHA(t *testing.T) {
|
|
t.Parallel()
|
|
provider, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
for i := 0; i < 100; i++ {
|
|
b, err := GetRandomBytes(i)
|
|
if err != nil {
|
|
t.Fatalf("Failed getting random bytes [%s]", err)
|
|
}
|
|
|
|
h1, err := provider.Hash(b, &bccsp.SHAOpts{})
|
|
if err != nil {
|
|
t.Fatalf("Failed computing SHA [%s]", err)
|
|
}
|
|
|
|
var h hash.Hash
|
|
switch currentTestConfig.hashFamily {
|
|
case "SHA2":
|
|
switch currentTestConfig.securityLevel {
|
|
case 256:
|
|
h = sha256.New()
|
|
case 384:
|
|
h = sha512.New384()
|
|
default:
|
|
t.Fatalf("Invalid security level [%d]", currentTestConfig.securityLevel)
|
|
}
|
|
case "SHA3":
|
|
switch currentTestConfig.securityLevel {
|
|
case 256:
|
|
h = sha3.New256()
|
|
case 384:
|
|
h = sha3.New384()
|
|
default:
|
|
t.Fatalf("Invalid security level [%d]", currentTestConfig.securityLevel)
|
|
}
|
|
default:
|
|
t.Fatalf("Invalid hash family [%s]", currentTestConfig.hashFamily)
|
|
}
|
|
|
|
h.Write(b)
|
|
h2 := h.Sum(nil)
|
|
if !bytes.Equal(h1, h2) {
|
|
t.Fatalf("Discrempancy found in HASH result [%x], [%x]!=[%x]", b, h1, h2)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAddWrapper(t *testing.T) {
|
|
t.Parallel()
|
|
p, _, cleanup := currentTestConfig.Provider(t)
|
|
defer cleanup()
|
|
|
|
sw, ok := p.(*CSP)
|
|
require.True(t, ok)
|
|
|
|
tester := func(o interface{}, getter func(t reflect.Type) (interface{}, bool)) {
|
|
tt := reflect.TypeOf(o)
|
|
err := sw.AddWrapper(tt, o)
|
|
require.NoError(t, err)
|
|
o2, ok := getter(tt)
|
|
require.True(t, ok)
|
|
require.Equal(t, o, o2)
|
|
}
|
|
|
|
tester(&mocks.KeyGenerator{}, func(t reflect.Type) (interface{}, bool) { o, ok := sw.KeyGenerators[t]; return o, ok })
|
|
tester(&mocks.KeyDeriver{}, func(t reflect.Type) (interface{}, bool) { o, ok := sw.KeyDerivers[t]; return o, ok })
|
|
tester(&mocks.KeyImporter{}, func(t reflect.Type) (interface{}, bool) { o, ok := sw.KeyImporters[t]; return o, ok })
|
|
tester(&mocks.Encryptor{}, func(t reflect.Type) (interface{}, bool) { o, ok := sw.Encryptors[t]; return o, ok })
|
|
tester(&mocks.Decryptor{}, func(t reflect.Type) (interface{}, bool) { o, ok := sw.Decryptors[t]; return o, ok })
|
|
tester(&mocks.Signer{}, func(t reflect.Type) (interface{}, bool) { o, ok := sw.Signers[t]; return o, ok })
|
|
tester(&mocks.Verifier{}, func(t reflect.Type) (interface{}, bool) { o, ok := sw.Verifiers[t]; return o, ok })
|
|
tester(&mocks.Hasher{}, func(t reflect.Type) (interface{}, bool) { o, ok := sw.Hashers[t]; return o, ok })
|
|
|
|
// Add invalid wrapper
|
|
err := sw.AddWrapper(reflect.TypeOf(cleanup), cleanup)
|
|
require.Error(t, err)
|
|
require.Equal(t, err.Error(), "wrapper type not valid, must be on of: KeyGenerator, KeyDeriver, KeyImporter, Encryptor, Decryptor, Signer, Verifier, Hasher")
|
|
}
|