go_study/fabric-main/bccsp/sw/keys_test.go

371 lines
9.5 KiB
Go

/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package sw
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/asn1"
"encoding/pem"
"testing"
"github.com/stretchr/testify/require"
)
func TestOidFromNamedCurve(t *testing.T) {
var (
oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
)
type result struct {
oid asn1.ObjectIdentifier
ok bool
}
tests := []struct {
name string
curve elliptic.Curve
expected result
}{
{
name: "P224",
curve: elliptic.P224(),
expected: result{
oid: oidNamedCurveP224,
ok: true,
},
},
{
name: "P256",
curve: elliptic.P256(),
expected: result{
oid: oidNamedCurveP256,
ok: true,
},
},
{
name: "P384",
curve: elliptic.P384(),
expected: result{
oid: oidNamedCurveP384,
ok: true,
},
},
{
name: "P521",
curve: elliptic.P521(),
expected: result{
oid: oidNamedCurveP521,
ok: true,
},
},
{
name: "T-1000",
curve: &elliptic.CurveParams{Name: "T-1000"},
expected: result{
oid: nil,
ok: false,
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
oid, ok := oidFromNamedCurve(test.curve)
require.Equal(t, oid, test.expected.oid)
require.Equal(t, ok, test.expected.ok)
})
}
}
func TestECDSAKeys(t *testing.T) {
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatalf("Failed generating ECDSA key [%s]", err)
}
// Private Key DER format
der, err := privateKeyToDER(key)
if err != nil {
t.Fatalf("Failed converting private key to DER [%s]", err)
}
keyFromDER, err := derToPrivateKey(der)
if err != nil {
t.Fatalf("Failed converting DER to private key [%s]", err)
}
ecdsaKeyFromDer := keyFromDER.(*ecdsa.PrivateKey)
// TODO: check the curve
if key.D.Cmp(ecdsaKeyFromDer.D) != 0 {
t.Fatal("Failed converting DER to private key. Invalid D.")
}
if key.X.Cmp(ecdsaKeyFromDer.X) != 0 {
t.Fatal("Failed converting DER to private key. Invalid X coordinate.")
}
if key.Y.Cmp(ecdsaKeyFromDer.Y) != 0 {
t.Fatal("Failed converting DER to private key. Invalid Y coordinate.")
}
// Private Key PEM format
rawPEM, err := privateKeyToPEM(key, nil)
if err != nil {
t.Fatalf("Failed converting private key to PEM [%s]", err)
}
pemBlock, _ := pem.Decode(rawPEM)
if pemBlock.Type != "PRIVATE KEY" {
t.Fatalf("Expected type 'PRIVATE KEY' but found '%s'", pemBlock.Type)
}
_, err = x509.ParsePKCS8PrivateKey(pemBlock.Bytes)
if err != nil {
t.Fatalf("Failed to parse PKCS#8 private key [%s]", err)
}
keyFromPEM, err := pemToPrivateKey(rawPEM, nil)
if err != nil {
t.Fatalf("Failed converting DER to private key [%s]", err)
}
ecdsaKeyFromPEM := keyFromPEM.(*ecdsa.PrivateKey)
// TODO: check the curve
if key.D.Cmp(ecdsaKeyFromPEM.D) != 0 {
t.Fatal("Failed converting PEM to private key. Invalid D.")
}
if key.X.Cmp(ecdsaKeyFromPEM.X) != 0 {
t.Fatal("Failed converting PEM to private key. Invalid X coordinate.")
}
if key.Y.Cmp(ecdsaKeyFromPEM.Y) != 0 {
t.Fatal("Failed converting PEM to private key. Invalid Y coordinate.")
}
// Nil Private Key <-> PEM
_, err = privateKeyToPEM(nil, nil)
if err == nil {
t.Fatal("PublicKeyToPEM should fail on nil")
}
_, err = privateKeyToPEM((*ecdsa.PrivateKey)(nil), nil)
if err == nil {
t.Fatal("PrivateKeyToPEM should fail on nil")
}
_, err = pemToPrivateKey(nil, nil)
if err == nil {
t.Fatal("PEMtoPublicKey should fail on nil")
}
_, err = pemToPrivateKey([]byte{0, 1, 3, 4}, nil)
if err == nil {
t.Fatal("PEMtoPublicKey should fail invalid PEM")
}
_, err = derToPrivateKey(nil)
if err == nil {
t.Fatal("DERToPrivateKey should fail on nil")
}
_, err = derToPrivateKey([]byte{0, 1, 3, 4})
if err == nil {
t.Fatal("DERToPrivateKey should fail on invalid DER")
}
_, err = privateKeyToDER(nil)
if err == nil {
t.Fatal("DERToPrivateKey should fail on nil")
}
// Private Key Encrypted PEM format
encPEM, err := privateKeyToPEM(key, []byte("passwd"))
if err != nil {
t.Fatalf("Failed converting private key to encrypted PEM [%s]", err)
}
_, err = pemToPrivateKey(encPEM, nil)
require.Error(t, err)
encKeyFromPEM, err := pemToPrivateKey(encPEM, []byte("passwd"))
if err != nil {
t.Fatalf("Failed converting DER to private key [%s]", err)
}
ecdsaKeyFromEncPEM := encKeyFromPEM.(*ecdsa.PrivateKey)
// TODO: check the curve
if key.D.Cmp(ecdsaKeyFromEncPEM.D) != 0 {
t.Fatal("Failed converting encrypted PEM to private key. Invalid D.")
}
if key.X.Cmp(ecdsaKeyFromEncPEM.X) != 0 {
t.Fatal("Failed converting encrypted PEM to private key. Invalid X coordinate.")
}
if key.Y.Cmp(ecdsaKeyFromEncPEM.Y) != 0 {
t.Fatal("Failed converting encrypted PEM to private key. Invalid Y coordinate.")
}
// Public Key PEM format
rawPEM, err = publicKeyToPEM(&key.PublicKey, nil)
if err != nil {
t.Fatalf("Failed converting public key to PEM [%s]", err)
}
pemBlock, _ = pem.Decode(rawPEM)
if pemBlock.Type != "PUBLIC KEY" {
t.Fatalf("Expected type 'PUBLIC KEY' but found '%s'", pemBlock.Type)
}
keyFromPEM, err = pemToPublicKey(rawPEM, nil)
if err != nil {
t.Fatalf("Failed converting DER to public key [%s]", err)
}
ecdsaPkFromPEM := keyFromPEM.(*ecdsa.PublicKey)
// TODO: check the curve
if key.X.Cmp(ecdsaPkFromPEM.X) != 0 {
t.Fatal("Failed converting PEM to private key. Invalid X coordinate.")
}
if key.Y.Cmp(ecdsaPkFromPEM.Y) != 0 {
t.Fatal("Failed converting PEM to private key. Invalid Y coordinate.")
}
// Nil Public Key <-> PEM
_, err = publicKeyToPEM(nil, nil)
if err == nil {
t.Fatal("PublicKeyToPEM should fail on nil")
}
_, err = pemToPublicKey(nil, nil)
if err == nil {
t.Fatal("PEMtoPublicKey should fail on nil")
}
_, err = pemToPublicKey([]byte{0, 1, 3, 4}, nil)
if err == nil {
t.Fatal("PEMtoPublicKey should fail on invalid PEM")
}
// Public Key Encrypted PEM format
encPEM, err = publicKeyToPEM(&key.PublicKey, []byte("passwd"))
if err != nil {
t.Fatalf("Failed converting private key to encrypted PEM [%s]", err)
}
_, err = pemToPublicKey(encPEM, nil)
require.Error(t, err)
pkFromEncPEM, err := pemToPublicKey(encPEM, []byte("passwd"))
if err != nil {
t.Fatalf("Failed converting DER to private key [%s]", err)
}
ecdsaPkFromEncPEM := pkFromEncPEM.(*ecdsa.PublicKey)
// TODO: check the curve
if key.X.Cmp(ecdsaPkFromEncPEM.X) != 0 {
t.Fatal("Failed converting encrypted PEM to private key. Invalid X coordinate.")
}
if key.Y.Cmp(ecdsaPkFromEncPEM.Y) != 0 {
t.Fatal("Failed converting encrypted PEM to private key. Invalid Y coordinate.")
}
_, err = pemToPublicKey(encPEM, []byte("passw"))
if err == nil {
t.Fatal("PEMtoPublicKey should fail on wrong password")
}
_, err = pemToPublicKey(encPEM, []byte("passw"))
if err == nil {
t.Fatal("PEMtoPublicKey should fail on nil password")
}
_, err = pemToPublicKey(nil, []byte("passwd"))
if err == nil {
t.Fatal("PEMtoPublicKey should fail on nil PEM")
}
_, err = pemToPublicKey([]byte{0, 1, 3, 4}, []byte("passwd"))
if err == nil {
t.Fatal("PEMtoPublicKey should fail on invalid PEM")
}
_, err = pemToPublicKey(nil, []byte("passw"))
if err == nil {
t.Fatal("PEMtoPublicKey should fail on nil PEM and wrong password")
}
// Public Key DER format
der, err = x509.MarshalPKIXPublicKey(&key.PublicKey)
require.NoError(t, err)
keyFromDER, err = derToPublicKey(der)
require.NoError(t, err)
ecdsaPkFromPEM = keyFromDER.(*ecdsa.PublicKey)
// TODO: check the curve
if key.X.Cmp(ecdsaPkFromPEM.X) != 0 {
t.Fatal("Failed converting PEM to private key. Invalid X coordinate.")
}
if key.Y.Cmp(ecdsaPkFromPEM.Y) != 0 {
t.Fatal("Failed converting PEM to private key. Invalid Y coordinate.")
}
}
func TestAESKey(t *testing.T) {
k := []byte{0, 1, 2, 3, 4, 5}
pem := aesToPEM(k)
k2, err := pemToAES(pem, nil)
require.NoError(t, err)
require.Equal(t, k, k2)
pem, err = aesToEncryptedPEM(k, k)
require.NoError(t, err)
k2, err = pemToAES(pem, k)
require.NoError(t, err)
require.Equal(t, k, k2)
_, err = pemToAES(pem, nil)
require.Error(t, err)
_, err = aesToEncryptedPEM(k, nil)
require.NoError(t, err)
k2, err = pemToAES(pem, k)
require.NoError(t, err)
require.Equal(t, k, k2)
}
func TestDERToPublicKey(t *testing.T) {
_, err := derToPublicKey(nil)
require.Error(t, err)
}
func TestNil(t *testing.T) {
_, err := privateKeyToEncryptedPEM(nil, nil)
require.Error(t, err)
_, err = privateKeyToEncryptedPEM((*ecdsa.PrivateKey)(nil), nil)
require.Error(t, err)
_, err = privateKeyToEncryptedPEM("Hello World", nil)
require.Error(t, err)
_, err = pemToAES(nil, nil)
require.Error(t, err)
_, err = aesToEncryptedPEM(nil, nil)
require.Error(t, err)
_, err = publicKeyToPEM(nil, nil)
require.Error(t, err)
_, err = publicKeyToPEM((*ecdsa.PublicKey)(nil), nil)
require.Error(t, err)
_, err = publicKeyToPEM(nil, []byte("hello world"))
require.Error(t, err)
_, err = publicKeyToPEM("hello world", nil)
require.Error(t, err)
_, err = publicKeyToPEM("hello world", []byte("hello world"))
require.Error(t, err)
_, err = publicKeyToEncryptedPEM(nil, nil)
require.Error(t, err)
_, err = publicKeyToEncryptedPEM((*ecdsa.PublicKey)(nil), nil)
require.Error(t, err)
_, err = publicKeyToEncryptedPEM("hello world", nil)
require.Error(t, err)
_, err = publicKeyToEncryptedPEM("hello world", []byte("Hello world"))
require.Error(t, err)
}