go_study/fabric-main/msp/msp_test.go

1610 lines
48 KiB
Go

/*
Copyright IBM Corp. 2017 All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package msp
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/hex"
"encoding/pem"
"errors"
"fmt"
"math/big"
"os"
"path/filepath"
"reflect"
"testing"
"time"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/msp"
"github.com/hyperledger/fabric/bccsp"
"github.com/hyperledger/fabric/bccsp/factory"
"github.com/hyperledger/fabric/bccsp/sw"
"github.com/hyperledger/fabric/bccsp/utils"
"github.com/hyperledger/fabric/core/config/configtest"
"github.com/hyperledger/fabric/protoutil"
"github.com/stretchr/testify/require"
)
var notACert = `-----BEGIN X509 CRL-----
MIIBYzCCAQgCAQEwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxEzARBgNVBAgT
CkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xHzAdBgNVBAoTFklu
dGVybmV0IFdpZGdldHMsIEluYy4xDDAKBgNVBAsTA1dXVzEUMBIGA1UEAxMLZXhh
bXBsZS5jb20XDTE3MDEyMzIwNTYyMFoXDTE3MDEyNjIwNTYyMFowJzAlAhQERXCx
LHROap1vM3CV40EHOghPTBcNMTcwMTIzMjA0NzMxWqAvMC0wHwYDVR0jBBgwFoAU
F2dCPaqegj/ExR2fW8OZ0bWcSBAwCgYDVR0UBAMCAQgwCgYIKoZIzj0EAwIDSQAw
RgIhAOTTpQYkGO+gwVe1LQOcNMD5fzFViOwBUraMrk6dRMlmAiEA8z2dpXKGwHrj
FRBbKkDnSpaVcZgjns+mLdHV2JkF0gk=
-----END X509 CRL-----`
func TestMSPParsers(t *testing.T) {
_, _, err := localMsp.(*bccspmsp).getIdentityFromConf(nil)
require.Error(t, err)
_, _, err = localMsp.(*bccspmsp).getIdentityFromConf([]byte("barf"))
require.Error(t, err)
_, _, err = localMsp.(*bccspmsp).getIdentityFromConf([]byte(notACert))
require.Error(t, err)
_, err = localMsp.(*bccspmsp).getSigningIdentityFromConf(nil)
require.Error(t, err)
sigid := &msp.SigningIdentityInfo{PublicSigner: []byte("barf"), PrivateSigner: nil}
_, err = localMsp.(*bccspmsp).getSigningIdentityFromConf(sigid)
require.Error(t, err)
keyinfo := &msp.KeyInfo{KeyIdentifier: "PEER", KeyMaterial: nil}
sigid = &msp.SigningIdentityInfo{PublicSigner: []byte("barf"), PrivateSigner: keyinfo}
_, err = localMsp.(*bccspmsp).getSigningIdentityFromConf(sigid)
require.Error(t, err)
}
func TestGetSigningIdentityFromConfWithWrongPrivateCert(t *testing.T) {
// Temporary Replace root certs
oldRoots := localMsp.(*bccspmsp).opts.Roots
defer func() {
// Restore original root certs
localMsp.(*bccspmsp).opts.Roots = oldRoots
}()
_, cert := generateSelfSignedCert(t, time.Now())
localMsp.(*bccspmsp).opts.Roots = x509.NewCertPool()
localMsp.(*bccspmsp).opts.Roots.AddCert(cert)
// Use self signed cert as public key. Convert DER to PEM format
pem := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
// Use wrong formatted private cert
keyinfo := &msp.KeyInfo{
KeyMaterial: []byte("wrong encoding"),
KeyIdentifier: "MyPrivateKey",
}
sigid := &msp.SigningIdentityInfo{PublicSigner: pem, PrivateSigner: keyinfo}
_, err := localMsp.(*bccspmsp).getSigningIdentityFromConf(sigid)
require.EqualError(t, err, "MyPrivateKey: wrong PEM encoding")
}
func TestMSPSetupNoCryptoConf(t *testing.T) {
mspDir := configtest.GetDevMspDir()
conf, err := GetLocalMspConfig(mspDir, nil, "SampleOrg")
if err != nil {
fmt.Printf("Setup should have succeeded, got err %s instead", err)
os.Exit(-1)
}
mspconf := &msp.FabricMSPConfig{}
err = proto.Unmarshal(conf.Config, mspconf)
require.NoError(t, err)
// here we test the case of an MSP configuration
// where the hash function to be used to obtain
// the identity identifier is unspecified - a
// sane default should be picked
mspconf.CryptoConfig.IdentityIdentifierHashFunction = ""
b, err := proto.Marshal(mspconf)
require.NoError(t, err)
conf.Config = b
newmsp, err := newBccspMsp(MSPv1_0, factory.GetDefault())
require.NoError(t, err)
err = newmsp.Setup(conf)
require.NoError(t, err)
// here we test the case of an MSP configuration
// where the hash function to be used to compute
// signatures is unspecified - a sane default
// should be picked
mspconf.CryptoConfig.SignatureHashFamily = ""
b, err = proto.Marshal(mspconf)
require.NoError(t, err)
conf.Config = b
newmsp, err = newBccspMsp(MSPv1_0, factory.GetDefault())
require.NoError(t, err)
err = newmsp.Setup(conf)
require.NoError(t, err)
// here we test the case of an MSP configuration
// that has NO crypto configuration specified;
// the code will use appropriate defaults
mspconf.CryptoConfig = nil
b, err = proto.Marshal(mspconf)
require.NoError(t, err)
conf.Config = b
newmsp, err = newBccspMsp(MSPv1_0, factory.GetDefault())
require.NoError(t, err)
err = newmsp.Setup(conf)
require.NoError(t, err)
}
func TestGetters(t *testing.T) {
typ := localMsp.GetType()
require.Equal(t, typ, FABRIC)
require.NotNil(t, localMsp.GetTLSRootCerts())
require.NotNil(t, localMsp.GetTLSIntermediateCerts())
}
func TestMSPSetupBad(t *testing.T) {
_, err := GetLocalMspConfig("barf", nil, "SampleOrg")
if err == nil {
t.Fatalf("Setup should have failed on an invalid config file")
return
}
mgr := NewMSPManager()
err = mgr.Setup(nil)
require.NoError(t, err)
err = mgr.Setup([]MSP{})
require.NoError(t, err)
}
func TestDoubleSetup(t *testing.T) {
// note that we've already called setup once on this
err := mspMgr.Setup(nil)
require.NoError(t, err)
}
type bccspNoKeyLookupKS struct {
bccsp.BCCSP
}
func (*bccspNoKeyLookupKS) GetKey(ski []byte) (k bccsp.Key, err error) {
return nil, errors.New("not found")
}
func TestNotFoundInBCCSP(t *testing.T) {
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
require.NoError(t, err)
dir := configtest.GetDevMspDir()
conf, err := GetLocalMspConfig(dir, nil, "SampleOrg")
require.NoError(t, err)
thisMSP, err := newBccspMsp(MSPv1_0, cryptoProvider)
require.NoError(t, err)
ks, err := sw.NewFileBasedKeyStore(nil, filepath.Join(dir, "keystore"), true)
require.NoError(t, err)
csp, err := sw.NewWithParams(256, "SHA2", ks)
require.NoError(t, err)
thisMSP.(*bccspmsp).bccsp = &bccspNoKeyLookupKS{csp}
err = thisMSP.Setup(conf)
require.Error(t, err)
require.Contains(t, "KeyMaterial not found in SigningIdentityInfo", err.Error())
}
func TestGetIdentities(t *testing.T) {
_, err := localMsp.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity failed with err %s", err)
return
}
}
func TestDeserializeIdentityFails(t *testing.T) {
_, err := localMsp.DeserializeIdentity([]byte("barf"))
require.Error(t, err)
id := &msp.SerializedIdentity{Mspid: "SampleOrg", IdBytes: []byte("barfr")}
b, err := proto.Marshal(id)
require.NoError(t, err)
_, err = localMsp.DeserializeIdentity(b)
require.Error(t, err)
id = &msp.SerializedIdentity{Mspid: "SampleOrg", IdBytes: []byte(notACert)}
b, err = proto.Marshal(id)
require.NoError(t, err)
_, err = localMsp.DeserializeIdentity(b)
require.Error(t, err)
}
func TestGetSigningIdentityFromVerifyingMSP(t *testing.T) {
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
require.NoError(t, err)
mspDir := configtest.GetDevMspDir()
conf, err = GetVerifyingMspConfig(mspDir, "SampleOrg", ProviderTypeToString(FABRIC))
if err != nil {
fmt.Printf("Setup should have succeeded, got err %s instead", err)
os.Exit(-1)
}
newmsp, err := newBccspMsp(MSPv1_0, cryptoProvider)
require.NoError(t, err)
err = newmsp.Setup(conf)
require.NoError(t, err)
_, err = newmsp.GetDefaultSigningIdentity()
require.Error(t, err)
}
func TestValidateDefaultSigningIdentity(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
err = localMsp.Validate(id.GetPublicVersion())
require.NoError(t, err)
}
func TestSerializeIdentities(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity should have succeeded, got err %s", err)
return
}
serializedID, err := id.Serialize()
if err != nil {
t.Fatalf("Serialize should have succeeded, got err %s", err)
return
}
idBack, err := localMsp.DeserializeIdentity(serializedID)
if err != nil {
t.Fatalf("DeserializeIdentity should have succeeded, got err %s", err)
return
}
err = localMsp.Validate(idBack)
if err != nil {
t.Fatalf("The identity should be valid, got err %s", err)
return
}
if !reflect.DeepEqual(id.GetPublicVersion(), idBack) {
t.Fatalf("Identities should be equal (%s) (%s)", id, idBack)
return
}
}
func computeSKI(key *ecdsa.PublicKey) []byte {
raw := elliptic.Marshal(key.Curve, key.X, key.Y)
hash := sha256.Sum256(raw)
return hash[:]
}
func TestValidHostname(t *testing.T) {
tests := []struct {
name string
valid bool
}{
{"", false},
{".", false},
{"example.com", true},
{"example.com.", true},
{"*.example.com", true},
{".example.com", false},
{"host.*.example.com", false},
{"localhost", true},
{"-localhost", false},
{"Not_Quite.example.com", true},
{"weird:colon.example.com", true},
{"1-2-3.example.com", true},
}
for _, tt := range tests {
if tt.valid {
require.True(t, validHostname(tt.name), "expected %s to be a valid hostname", tt.name)
} else {
require.False(t, validHostname(tt.name), "expected %s to be an invalid hostname", tt.name)
}
}
}
func TestValidateCANameConstraintsMitigation(t *testing.T) {
// Prior to Go 1.15, if a signing certificate contains a name constraint, the
// leaf certificate does not include a SAN, and the leaf common name looks
// like a valid hostname, the certificate chain would fail to validate.
// (This behavior may have been introduced with Go 1.10.)
//
// In Go 1.15, the behavior has changed and, by default, the same structure
// will validate. This test asserts on the old behavior.
caKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)
leafKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)
caKeyUsage := x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign | x509.KeyUsageCRLSign
caTemplate := x509.Certificate{
Subject: pkix.Name{CommonName: "TestCA"},
SerialNumber: big.NewInt(1),
NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().Add(2 * time.Hour),
ExcludedDNSDomains: []string{"example.com"},
PermittedDNSDomainsCritical: true,
IsCA: true,
BasicConstraintsValid: true,
KeyUsage: caKeyUsage,
SubjectKeyId: computeSKI(caKey.Public().(*ecdsa.PublicKey)),
}
caCertBytes, err := x509.CreateCertificate(rand.Reader, &caTemplate, &caTemplate, caKey.Public(), caKey)
require.NoError(t, err)
ca, err := x509.ParseCertificate(caCertBytes)
require.NoError(t, err)
leafTemplate := x509.Certificate{
Subject: pkix.Name{CommonName: "localhost"},
SerialNumber: big.NewInt(2),
NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().Add(2 * time.Hour),
KeyUsage: x509.KeyUsageDigitalSignature,
SubjectKeyId: computeSKI(leafKey.Public().(*ecdsa.PublicKey)),
}
leafCertBytes, err := x509.CreateCertificate(rand.Reader, &leafTemplate, ca, leafKey.Public(), caKey)
require.NoError(t, err)
keyBytes, err := x509.MarshalPKCS8PrivateKey(leafKey)
require.NoError(t, err)
caCertPem := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: caCertBytes})
leafCertPem := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: leafCertBytes})
leafKeyPem := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: keyBytes})
t.Run("VerifyNameConstraintsSingleCert", func(t *testing.T) {
for _, der := range [][]byte{caCertBytes, leafCertBytes} {
cert, err := x509.ParseCertificate(der)
require.NoError(t, err, "failed to parse certificate")
err = verifyLegacyNameConstraints([]*x509.Certificate{cert})
require.NoError(t, err, "single certificate should not trigger legacy constraints")
}
})
t.Run("VerifyNameConstraints", func(t *testing.T) {
var certs []*x509.Certificate
for _, der := range [][]byte{leafCertBytes, caCertBytes} {
cert, err := x509.ParseCertificate(der)
require.NoError(t, err, "failed to parse certificate")
certs = append(certs, cert)
}
err = verifyLegacyNameConstraints(certs)
require.Error(t, err, "certificate chain should trigger legacy constraints")
var cie x509.CertificateInvalidError
require.True(t, errors.As(err, &cie))
require.Equal(t, x509.NameConstraintsWithoutSANs, cie.Reason)
})
t.Run("VerifyNameConstraintsWithSAN", func(t *testing.T) {
caCert, err := x509.ParseCertificate(caCertBytes)
require.NoError(t, err)
leafTemplate := leafTemplate
leafTemplate.DNSNames = []string{"localhost"}
leafCertBytes, err := x509.CreateCertificate(rand.Reader, &leafTemplate, caCert, leafKey.Public(), caKey)
require.NoError(t, err)
leafCert, err := x509.ParseCertificate(leafCertBytes)
require.NoError(t, err)
err = verifyLegacyNameConstraints([]*x509.Certificate{leafCert, caCert})
require.NoError(t, err, "signer with name constraints and leaf with SANs should be valid")
})
t.Run("ValidationAtSetup", func(t *testing.T) {
fabricMSPConfig := &msp.FabricMSPConfig{
Name: "ConstraintsMSP",
RootCerts: [][]byte{caCertPem},
SigningIdentity: &msp.SigningIdentityInfo{
PublicSigner: leafCertPem,
PrivateSigner: &msp.KeyInfo{
KeyIdentifier: "Certificate Without SAN",
KeyMaterial: leafKeyPem,
},
},
}
mspConfig := &msp.MSPConfig{
Config: protoutil.MarshalOrPanic(fabricMSPConfig),
}
ks, err := sw.NewFileBasedKeyStore(nil, filepath.Join(configtest.GetDevMspDir(), "keystore"), true)
require.NoError(t, err)
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(ks)
require.NoError(t, err)
testMSP, err := NewBccspMspWithKeyStore(MSPv1_0, ks, cryptoProvider)
require.NoError(t, err)
err = testMSP.Setup(mspConfig)
require.Error(t, err)
var cie x509.CertificateInvalidError
require.True(t, errors.As(err, &cie))
require.Equal(t, x509.NameConstraintsWithoutSANs, cie.Reason)
})
}
func TestIsWellFormed(t *testing.T) {
mspMgr := NewMSPManager()
id, err := localMsp.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity should have succeeded, got err %s", err)
return
}
serializedID, err := id.Serialize()
if err != nil {
t.Fatalf("Serialize should have succeeded, got err %s", err)
return
}
sId := &msp.SerializedIdentity{}
err = proto.Unmarshal(serializedID, sId)
require.NoError(t, err)
// An MSP Manager without any MSPs should not recognize the identity since
// not providers are registered
err = mspMgr.IsWellFormed(sId)
require.Error(t, err)
require.Equal(t, "no MSP provider recognizes the identity", err.Error())
// Add the MSP to the MSP Manager
mspMgr.Setup([]MSP{localMsp})
err = localMsp.IsWellFormed(sId)
require.NoError(t, err)
err = mspMgr.IsWellFormed(sId)
require.NoError(t, err)
bl, _ := pem.Decode(sId.IdBytes)
require.Equal(t, "CERTIFICATE", bl.Type)
// Now, strip off the type from the PEM block. It should still be valid
bl.Type = ""
sId.IdBytes = pem.EncodeToMemory(bl)
err = localMsp.IsWellFormed(sId)
require.NoError(t, err)
// Now, corrupt the type of the PEM block.
// make sure it isn't considered well formed by both an MSP and an MSP Manager
bl.Type = "foo"
sId.IdBytes = pem.EncodeToMemory(bl)
err = localMsp.IsWellFormed(sId)
require.Error(t, err)
require.Contains(t, err.Error(), "pem type is")
require.Contains(t, err.Error(), "should be 'CERTIFICATE' or missing")
err = mspMgr.IsWellFormed(sId)
require.Error(t, err)
require.Equal(t, "no MSP provider recognizes the identity", err.Error())
// Restore the identity to what it was
sId = &msp.SerializedIdentity{}
err = proto.Unmarshal(serializedID, sId)
require.NoError(t, err)
// Append some trailing junk at the end
sId.IdBytes = append(sId.IdBytes, []byte{1, 2, 3}...)
// And ensure it is deemed invalid
err = localMsp.IsWellFormed(sId)
require.Error(t, err)
require.Contains(t, err.Error(), "for MSP SampleOrg has trailing bytes")
// Parse the certificate of the identity
cert, err := x509.ParseCertificate(bl.Bytes)
require.NoError(t, err)
// Obtain the ECDSA signature
r, s, err := utils.UnmarshalECDSASignature(cert.Signature)
require.NoError(t, err)
// Modify it by appending some bytes to its end.
modifiedSig, err := asn1.Marshal(rst{
R: r,
S: s,
T: big.NewInt(100),
})
require.NoError(t, err)
newCert, err := certFromX509Cert(cert)
require.NoError(t, err)
newCert.SignatureValue.Bytes = modifiedSig
newCert.SignatureValue.BitLength = len(newCert.SignatureValue.Bytes) * 8
newCert.Raw = nil
// Pour it back into the identity
rawCert, err := asn1.Marshal(newCert)
require.NoError(t, err)
sId.IdBytes = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: rawCert})
// Ensure it is invalid now and the signature modification is detected
err = localMsp.IsWellFormed(sId)
require.Error(t, err)
require.Contains(t, err.Error(), "for MSP SampleOrg has a non canonical signature")
}
type rst struct {
R, S, T *big.Int
}
func TestValidateCAIdentity(t *testing.T) {
caID := getIdentity(t, cacerts)
err := localMsp.Validate(caID)
require.Error(t, err)
}
func TestBadAdminIdentity(t *testing.T) {
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
require.NoError(t, err)
conf, err := GetLocalMspConfig("testdata/badadmin", nil, "SampleOrg")
require.NoError(t, err)
thisMSP, err := newBccspMsp(MSPv1_0, cryptoProvider)
require.NoError(t, err)
ks, err := sw.NewFileBasedKeyStore(nil, filepath.Join("testdata/badadmin", "keystore"), true)
require.NoError(t, err)
csp, err := sw.NewWithParams(256, "SHA2", ks)
require.NoError(t, err)
thisMSP.(*bccspmsp).bccsp = csp
err = thisMSP.Setup(conf)
require.Error(t, err)
}
func TestValidateAdminIdentity(t *testing.T) {
caID := getIdentity(t, admincerts)
err := localMsp.Validate(caID)
require.NoError(t, err)
}
func TestSerializeIdentitiesWithWrongMSP(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity should have succeeded, got err %s", err)
return
}
serializedID, err := id.Serialize()
if err != nil {
t.Fatalf("Serialize should have succeeded, got err %s", err)
return
}
sid := &msp.SerializedIdentity{}
err = proto.Unmarshal(serializedID, sid)
require.NoError(t, err)
sid.Mspid += "BARF"
serializedID, err = proto.Marshal(sid)
require.NoError(t, err)
_, err = localMsp.DeserializeIdentity(serializedID)
require.Error(t, err)
}
func TestSerializeIdentitiesWithMSPManager(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity should have succeeded, got err %s", err)
return
}
serializedID, err := id.Serialize()
if err != nil {
t.Fatalf("Serialize should have succeeded, got err %s", err)
return
}
_, err = mspMgr.DeserializeIdentity(serializedID)
require.NoError(t, err)
sid := &msp.SerializedIdentity{}
err = proto.Unmarshal(serializedID, sid)
require.NoError(t, err)
sid.Mspid += "BARF"
serializedID, err = proto.Marshal(sid)
require.NoError(t, err)
_, err = mspMgr.DeserializeIdentity(serializedID)
require.Error(t, err)
require.Contains(t, err.Error(), fmt.Sprintf("MSP %s is not defined on channel", sid.Mspid))
_, err = mspMgr.DeserializeIdentity([]byte("barf"))
require.Error(t, err)
require.Contains(t, err.Error(), "could not deserialize")
}
func TestIdentitiesGetters(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity should have succeeded, got err %s", err)
return
}
idid := id.GetIdentifier()
require.NotNil(t, idid)
mspid := id.GetMSPIdentifier()
require.NotNil(t, mspid)
require.False(t, id.Anonymous())
}
func TestSignAndVerify(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity should have succeeded")
return
}
serializedID, err := id.Serialize()
if err != nil {
t.Fatalf("Serialize should have succeeded")
return
}
idBack, err := localMsp.DeserializeIdentity(serializedID)
if err != nil {
t.Fatalf("DeserializeIdentity should have succeeded")
return
}
msg := []byte("foo")
sig, err := id.Sign(msg)
if err != nil {
t.Fatalf("Sign should have succeeded")
return
}
err = id.Verify(msg, sig)
if err != nil {
t.Fatalf("The signature should be valid")
return
}
err = idBack.Verify(msg, sig)
if err != nil {
t.Fatalf("The signature should be valid")
return
}
err = id.Verify(msg[1:], sig)
require.Error(t, err)
err = id.Verify(msg, sig[1:])
require.Error(t, err)
}
func TestSignAndVerifyFailures(t *testing.T) {
msg := []byte("foo")
id, err := localMspBad.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity should have succeeded")
return
}
hash := id.(*signingidentity).msp.cryptoConfig.SignatureHashFamily
id.(*signingidentity).msp.cryptoConfig.SignatureHashFamily = "barf"
_, err = id.Sign(msg)
require.Error(t, err)
id.(*signingidentity).msp.cryptoConfig.SignatureHashFamily = hash
sig, err := id.Sign(msg)
if err != nil {
t.Fatalf("Sign should have succeeded")
return
}
id.(*signingidentity).msp.cryptoConfig.SignatureHashFamily = "barf"
err = id.Verify(msg, sig)
require.Error(t, err)
id.(*signingidentity).msp.cryptoConfig.SignatureHashFamily = hash
}
func TestSignAndVerifyOtherHash(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity should have succeeded")
return
}
hash := id.(*signingidentity).msp.cryptoConfig.SignatureHashFamily
id.(*signingidentity).msp.cryptoConfig.SignatureHashFamily = bccsp.SHA3
msg := []byte("foo")
sig, err := id.Sign(msg)
if err != nil {
t.Fatalf("Sign should have succeeded")
return
}
err = id.Verify(msg, sig)
require.NoError(t, err)
id.(*signingidentity).msp.cryptoConfig.SignatureHashFamily = hash
}
func TestSignAndVerify_longMessage(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity should have succeeded")
return
}
serializedID, err := id.Serialize()
if err != nil {
t.Fatalf("Serialize should have succeeded")
return
}
idBack, err := localMsp.DeserializeIdentity(serializedID)
if err != nil {
t.Fatalf("DeserializeIdentity should have succeeded")
return
}
msg := []byte("ABCDEFGABCDEFGABCDEFGABCDEFGABCDEFGABCDEFGABCDEFGABCDEFGABCDEFGABCDEFGABCDEFGABCDEFGABCDEFGABCDEFG")
sig, err := id.Sign(msg)
if err != nil {
t.Fatalf("Sign should have succeeded")
return
}
err = id.Verify(msg, sig)
if err != nil {
t.Fatalf("The signature should be valid")
return
}
err = idBack.Verify(msg, sig)
if err != nil {
t.Fatalf("The signature should be valid")
return
}
}
func TestGetOU(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity should have succeeded")
return
}
require.Equal(t, "COP", id.GetOrganizationalUnits()[0].OrganizationalUnitIdentifier)
}
func TestGetOUFail(t *testing.T) {
id, err := localMspBad.GetDefaultSigningIdentity()
if err != nil {
t.Fatalf("GetDefaultSigningIdentity should have succeeded")
return
}
certTmp := id.(*signingidentity).cert
id.(*signingidentity).cert = nil
ou := id.GetOrganizationalUnits()
require.Nil(t, ou)
id.(*signingidentity).cert = certTmp
opts := id.(*signingidentity).msp.opts
id.(*signingidentity).msp.opts = nil
ou = id.GetOrganizationalUnits()
require.Nil(t, ou)
id.(*signingidentity).msp.opts = opts
}
func TestCertificationIdentifierComputation(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
chain, err := localMsp.(*bccspmsp).getCertificationChain(id.GetPublicVersion())
require.NoError(t, err)
// Hash the chain
// Use the hash of the identity's certificate as id in the IdentityIdentifier
hashOpt, err := bccsp.GetHashOpt(localMsp.(*bccspmsp).cryptoConfig.IdentityIdentifierHashFunction)
require.NoError(t, err)
hf, err := localMsp.(*bccspmsp).bccsp.GetHash(hashOpt)
require.NoError(t, err)
// Skipping first cert because it belongs to the identity
for i := 1; i < len(chain); i++ {
hf.Write(chain[i].Raw)
}
sum := hf.Sum(nil)
require.Equal(t, sum, id.GetOrganizationalUnits()[0].CertifiersIdentifier)
}
func TestOUPolicyPrincipal(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
cid, err := localMsp.(*bccspmsp).getCertificationChainIdentifier(id.GetPublicVersion())
require.NoError(t, err)
ou := &msp.OrganizationUnit{
OrganizationalUnitIdentifier: "COP",
MspIdentifier: "SampleOrg",
CertifiersIdentifier: cid,
}
bytes, err := proto.Marshal(ou)
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ORGANIZATION_UNIT,
Principal: bytes,
}
err = id.SatisfiesPrincipal(principal)
require.NoError(t, err)
}
func TestOUPolicyPrincipalBadPrincipal(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ORGANIZATION_UNIT,
Principal: []byte("barf"),
}
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
}
func TestOUPolicyPrincipalBadMSPID(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
cid, err := localMsp.(*bccspmsp).getCertificationChainIdentifier(id.GetPublicVersion())
require.NoError(t, err)
ou := &msp.OrganizationUnit{
OrganizationalUnitIdentifier: "COP",
MspIdentifier: "SampleOrgbarfbarf",
CertifiersIdentifier: cid,
}
bytes, err := proto.Marshal(ou)
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ORGANIZATION_UNIT,
Principal: bytes,
}
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
}
func TestOUPolicyPrincipalBadPath(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
ou := &msp.OrganizationUnit{
OrganizationalUnitIdentifier: "COP",
MspIdentifier: "SampleOrg",
CertifiersIdentifier: nil,
}
bytes, err := proto.Marshal(ou)
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ORGANIZATION_UNIT,
Principal: bytes,
}
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
ou = &msp.OrganizationUnit{
OrganizationalUnitIdentifier: "COP",
MspIdentifier: "SampleOrg",
CertifiersIdentifier: []byte{0, 1, 2, 3, 4},
}
bytes, err = proto.Marshal(ou)
require.NoError(t, err)
principal = &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ORGANIZATION_UNIT,
Principal: bytes,
}
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
}
func TestPolicyPrincipalBogusType(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
principalBytes, err := proto.Marshal(&msp.MSPRole{Role: 35, MspIdentifier: "SampleOrg"})
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: 35,
Principal: principalBytes,
}
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
}
func TestPolicyPrincipalBogusRole(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
principalBytes, err := proto.Marshal(&msp.MSPRole{Role: 35, MspIdentifier: "SampleOrg"})
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
Principal: principalBytes,
}
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
}
func TestPolicyPrincipalWrongMSPID(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
principalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "SampleOrgBARFBARF"})
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
Principal: principalBytes,
}
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
}
func TestMemberPolicyPrincipal(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
principalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "SampleOrg"})
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
Principal: principalBytes,
}
err = id.SatisfiesPrincipal(principal)
require.NoError(t, err)
}
func TestAdminPolicyPrincipal(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
principalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_ADMIN, MspIdentifier: "SampleOrg"})
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
Principal: principalBytes,
}
err = id.SatisfiesPrincipal(principal)
require.NoError(t, err)
}
// Combine one or more MSPPrincipals into a MSPPrincipal of type
// MSPPrincipal_COMBINED.
func createCombinedPrincipal(principals ...*msp.MSPPrincipal) (*msp.MSPPrincipal, error) {
if len(principals) == 0 {
return nil, errors.New("no principals in CombinedPrincipal")
}
principalsArray := append([]*msp.MSPPrincipal(nil), principals...)
combinedPrincipal := &msp.CombinedPrincipal{Principals: principalsArray}
combinedPrincipalBytes, err := proto.Marshal(combinedPrincipal)
if err != nil {
return nil, err
}
principalsCombined := &msp.MSPPrincipal{PrincipalClassification: msp.MSPPrincipal_COMBINED, Principal: combinedPrincipalBytes}
return principalsCombined, nil
}
func TestMultilevelAdminAndMemberPolicyPrincipal(t *testing.T) {
id, err := localMspV13.GetDefaultSigningIdentity()
require.NoError(t, err)
adminPrincipalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_ADMIN, MspIdentifier: "SampleOrg"})
require.NoError(t, err)
memberPrincipalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "SampleOrg"})
require.NoError(t, err)
adminPrincipal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
Principal: adminPrincipalBytes,
}
memberPrincipal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
Principal: memberPrincipalBytes,
}
// CombinedPrincipal with Admin and Member principals
levelOneCombinedPrincipal, err := createCombinedPrincipal(adminPrincipal, memberPrincipal)
require.NoError(t, err)
err = id.SatisfiesPrincipal(levelOneCombinedPrincipal)
require.NoError(t, err)
// Nested CombinedPrincipal
levelTwoCombinedPrincipal, err := createCombinedPrincipal(levelOneCombinedPrincipal)
require.NoError(t, err)
err = id.SatisfiesPrincipal(levelTwoCombinedPrincipal)
require.NoError(t, err)
// Double nested CombinedPrincipal
levelThreeCombinedPrincipal, err := createCombinedPrincipal(levelTwoCombinedPrincipal)
require.NoError(t, err)
err = id.SatisfiesPrincipal(levelThreeCombinedPrincipal)
require.NoError(t, err)
}
func TestMultilevelAdminAndMemberPolicyPrincipalPreV12(t *testing.T) {
id, err := localMspV11.GetDefaultSigningIdentity()
require.NoError(t, err)
adminPrincipalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_ADMIN, MspIdentifier: "SampleOrg"})
require.NoError(t, err)
memberPrincipalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "SampleOrg"})
require.NoError(t, err)
adminPrincipal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
Principal: adminPrincipalBytes,
}
memberPrincipal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
Principal: memberPrincipalBytes,
}
// CombinedPrincipal with Admin and Member principals
levelOneCombinedPrincipal, err := createCombinedPrincipal(adminPrincipal, memberPrincipal)
require.NoError(t, err)
err = id.SatisfiesPrincipal(levelOneCombinedPrincipal)
require.Error(t, err)
// Nested CombinedPrincipal
levelTwoCombinedPrincipal, err := createCombinedPrincipal(levelOneCombinedPrincipal)
require.NoError(t, err)
err = id.SatisfiesPrincipal(levelTwoCombinedPrincipal)
require.Error(t, err)
// Double nested CombinedPrincipal
levelThreeCombinedPrincipal, err := createCombinedPrincipal(levelTwoCombinedPrincipal)
require.NoError(t, err)
err = id.SatisfiesPrincipal(levelThreeCombinedPrincipal)
require.Error(t, err)
}
func TestAdminPolicyPrincipalFails(t *testing.T) {
id, err := localMspV13.GetDefaultSigningIdentity()
require.NoError(t, err)
principalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_ADMIN, MspIdentifier: "SampleOrg"})
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
Principal: principalBytes,
}
// remove the admin so validation will fail
localMspV13.(*bccspmsp).admins = make([]Identity, 0)
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
}
func TestMultilevelAdminAndMemberPolicyPrincipalFails(t *testing.T) {
id, err := localMspV13.GetDefaultSigningIdentity()
require.NoError(t, err)
adminPrincipalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_ADMIN, MspIdentifier: "SampleOrg"})
require.NoError(t, err)
memberPrincipalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "SampleOrg"})
require.NoError(t, err)
adminPrincipal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
Principal: adminPrincipalBytes,
}
memberPrincipal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
Principal: memberPrincipalBytes,
}
// remove the admin so validation will fail
localMspV13.(*bccspmsp).admins = make([]Identity, 0)
// CombinedPrincipal with Admin and Member principals
levelOneCombinedPrincipal, err := createCombinedPrincipal(adminPrincipal, memberPrincipal)
require.NoError(t, err)
err = id.SatisfiesPrincipal(levelOneCombinedPrincipal)
require.Error(t, err)
// Nested CombinedPrincipal
levelTwoCombinedPrincipal, err := createCombinedPrincipal(levelOneCombinedPrincipal)
require.NoError(t, err)
err = id.SatisfiesPrincipal(levelTwoCombinedPrincipal)
require.Error(t, err)
// Double nested CombinedPrincipal
levelThreeCombinedPrincipal, err := createCombinedPrincipal(levelTwoCombinedPrincipal)
require.NoError(t, err)
err = id.SatisfiesPrincipal(levelThreeCombinedPrincipal)
require.Error(t, err)
}
func TestIdentityExpiresAt(t *testing.T) {
thisMSP := getLocalMSP(t, "testdata/expiration")
require.NotNil(t, thisMSP)
si, err := thisMSP.GetDefaultSigningIdentity()
require.NoError(t, err)
expirationDate := si.GetPublicVersion().ExpiresAt()
require.Equal(t, time.Date(2027, 8, 17, 12, 19, 48, 0, time.UTC), expirationDate)
}
func TestIdentityExpired(t *testing.T) {
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
require.NoError(t, err)
expiredCertsDir := "testdata/expired"
conf, err := GetLocalMspConfig(expiredCertsDir, nil, "SampleOrg")
require.NoError(t, err)
thisMSP, err := newBccspMsp(MSPv1_0, cryptoProvider)
require.NoError(t, err)
ks, err := sw.NewFileBasedKeyStore(nil, filepath.Join(expiredCertsDir, "keystore"), true)
require.NoError(t, err)
csp, err := sw.NewWithParams(256, "SHA2", ks)
require.NoError(t, err)
thisMSP.(*bccspmsp).bccsp = csp
err = thisMSP.Setup(conf)
if err != nil {
require.Contains(t, err.Error(), "signing identity expired")
} else {
t.Fatal("Should have failed when loading expired certs")
}
}
func TestIdentityPolicyPrincipal(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
idSerialized, err := id.Serialize()
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_IDENTITY,
Principal: idSerialized,
}
err = id.SatisfiesPrincipal(principal)
require.NoError(t, err)
}
func TestIdentityPolicyPrincipalBadBytes(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_IDENTITY,
Principal: []byte("barf"),
}
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
}
func TestMSPOus(t *testing.T) {
// Set the OUIdentifiers
backup := localMsp.(*bccspmsp).ouIdentifiers
defer func() { localMsp.(*bccspmsp).ouIdentifiers = backup }()
sid, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
sidBytes, err := sid.Serialize()
require.NoError(t, err)
id, err := localMsp.DeserializeIdentity(sidBytes)
require.NoError(t, err)
localMsp.(*bccspmsp).ouIdentifiers = map[string][][]byte{
"COP": {id.GetOrganizationalUnits()[0].CertifiersIdentifier},
}
require.NoError(t, localMsp.Validate(id))
id, err = localMsp.DeserializeIdentity(sidBytes)
require.NoError(t, err)
localMsp.(*bccspmsp).ouIdentifiers = map[string][][]byte{
"COP2": {id.GetOrganizationalUnits()[0].CertifiersIdentifier},
}
require.Error(t, localMsp.Validate(id))
id, err = localMsp.DeserializeIdentity(sidBytes)
require.NoError(t, err)
localMsp.(*bccspmsp).ouIdentifiers = map[string][][]byte{
"COP": {{0, 1, 2, 3, 4}},
}
require.Error(t, localMsp.Validate(id))
}
const othercert = `-----BEGIN CERTIFICATE-----
MIIDAzCCAqigAwIBAgIBAjAKBggqhkjOPQQDAjBsMQswCQYDVQQGEwJHQjEQMA4G
A1UECAwHRW5nbGFuZDEOMAwGA1UECgwFQmFyMTkxDjAMBgNVBAsMBUJhcjE5MQ4w
DAYDVQQDDAVCYXIxOTEbMBkGCSqGSIb3DQEJARYMQmFyMTktY2xpZW50MB4XDTE3
MDIwOTE2MDcxMFoXDTE4MDIxOTE2MDcxMFowfDELMAkGA1UEBhMCR0IxEDAOBgNV
BAgMB0VuZ2xhbmQxEDAOBgNVBAcMB0lwc3dpY2gxDjAMBgNVBAoMBUJhcjE5MQ4w
DAYDVQQLDAVCYXIxOTEOMAwGA1UEAwwFQmFyMTkxGTAXBgkqhkiG9w0BCQEWCkJh
cjE5LXBlZXIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQlRSnAyD+ND6qmaRV7
AS/BPJKX5dZt3gBe1v/RewOpc1zJeXQNWACAk0ae3mv5u9l0HxI6TXJIAQSwJACu
Rqsyo4IBKTCCASUwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZI
AYb4QgENBCYWJE9wZW5TU0wgR2VuZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAd
BgNVHQ4EFgQUwHzbLJQMaWd1cpHdkSaEFxdKB1owgYsGA1UdIwSBgzCBgIAUYxFe
+cXOD5iQ223bZNdOuKCRiTKhZaRjMGExCzAJBgNVBAYTAkdCMRAwDgYDVQQIDAdF
bmdsYW5kMRAwDgYDVQQHDAdJcHN3aWNoMQ4wDAYDVQQKDAVCYXIxOTEOMAwGA1UE
CwwFQmFyMTkxDjAMBgNVBAMMBUJhcjE5ggEBMA4GA1UdDwEB/wQEAwIFoDATBgNV
HSUEDDAKBggrBgEFBQcDATAKBggqhkjOPQQDAgNJADBGAiEAuMq65lOaie4705Ol
Ow52DjbaO2YuIxK2auBCqNIu0gECIQCDoKdUQ/sa+9Ah1mzneE6iz/f/YFVWo4EP
HeamPGiDTQ==
-----END CERTIFICATE-----
`
func TestIdentityPolicyPrincipalFails(t *testing.T) {
id, err := localMsp.GetDefaultSigningIdentity()
require.NoError(t, err)
sid, err := NewSerializedIdentity("SampleOrg", []byte(othercert))
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_IDENTITY,
Principal: sid,
}
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
}
var (
conf *msp.MSPConfig
localMsp MSP
localMspV11 MSP
localMspV13 MSP
)
// Required because deleting the cert or msp options from localMsp causes parallel tests to fail
var (
localMspBad MSP
mspMgr MSPManager
)
func TestMain(m *testing.M) {
var err error
mspDir := configtest.GetDevMspDir()
conf, err = GetLocalMspConfig(mspDir, nil, "SampleOrg")
if err != nil {
fmt.Printf("Setup should have succeeded, got err %s instead", err)
os.Exit(-1)
}
localMsp, err = newBccspMsp(MSPv1_0, factory.GetDefault())
if err != nil {
fmt.Printf("Constructor for msp should have succeeded, got err %s instead", err)
os.Exit(-1)
}
localMspBad, err = newBccspMsp(MSPv1_0, factory.GetDefault())
if err != nil {
fmt.Printf("Constructor for msp should have succeeded, got err %s instead", err)
os.Exit(-1)
}
localMspV13, err = newBccspMsp(MSPv1_3, factory.GetDefault())
if err != nil {
fmt.Printf("Constructor for V1.3 msp should have succeeded, got err %s instead", err)
os.Exit(-1)
}
localMspV11, err = newBccspMsp(MSPv1_1, factory.GetDefault())
if err != nil {
fmt.Printf("Constructor for V1.1 msp should have succeeded, got err %s instead", err)
os.Exit(-1)
}
err = localMspV11.Setup(conf)
if err != nil {
fmt.Printf("Setup for V1.1 msp should have succeeded, got err %s instead", err)
os.Exit(-1)
}
err = localMspV13.Setup(conf)
if err != nil {
fmt.Printf("Setup for V1.3 msp should have succeeded, got err %s instead", err)
os.Exit(-1)
}
err = localMsp.Setup(conf)
if err != nil {
fmt.Printf("Setup for msp should have succeeded, got err %s instead", err)
os.Exit(-1)
}
err = localMspBad.Setup(conf)
if err != nil {
fmt.Printf("Setup for msp should have succeeded, got err %s instead", err)
os.Exit(-1)
}
mspMgr = NewMSPManager()
err = mspMgr.Setup([]MSP{localMsp})
if err != nil {
fmt.Printf("Setup for msp manager should have succeeded, got err %s instead", err)
os.Exit(-1)
}
id, err := localMsp.GetIdentifier()
if err != nil {
fmt.Println("Failed obtaining identifier for localMSP")
os.Exit(-1)
}
msps, err := mspMgr.GetMSPs()
if err != nil {
fmt.Println("Failed obtaining MSPs from MSP manager")
os.Exit(-1)
}
if msps[id] == nil {
fmt.Println("Couldn't find localMSP in MSP manager")
os.Exit(-1)
}
retVal := m.Run()
os.Exit(retVal)
}
func getIdentity(t *testing.T, path string) Identity {
mspDir := configtest.GetDevMspDir()
pems, err := getPemMaterialFromDir(filepath.Join(mspDir, path))
require.NoError(t, err)
id, _, err := localMsp.(*bccspmsp).getIdentityFromConf(pems[0])
require.NoError(t, err)
return id
}
func getLocalMSPWithVersionAndError(t *testing.T, dir string, version MSPVersion) (MSP, error) {
conf, err := GetLocalMspConfig(dir, nil, "SampleOrg")
require.NoError(t, err)
ks, err := sw.NewFileBasedKeyStore(nil, filepath.Join(dir, "keystore"), true)
require.NoError(t, err)
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
require.NoError(t, err)
thisMSP, err := NewBccspMspWithKeyStore(version, ks, cryptoProvider)
require.NoError(t, err)
return thisMSP, thisMSP.Setup(conf)
}
func getLocalMSP(t *testing.T, dir string) MSP {
conf, err := GetLocalMspConfig(dir, nil, "SampleOrg")
require.NoError(t, err)
ks, err := sw.NewFileBasedKeyStore(nil, filepath.Join(dir, "keystore"), true)
require.NoError(t, err)
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
require.NoError(t, err)
thisMSP, err := NewBccspMspWithKeyStore(MSPv1_0, ks, cryptoProvider)
require.NoError(t, err)
err = thisMSP.Setup(conf)
require.NoError(t, err)
return thisMSP
}
func getLocalMSPWithVersion(t *testing.T, dir string, version MSPVersion) MSP {
conf, err := GetLocalMspConfig(dir, nil, "SampleOrg")
require.NoError(t, err)
ks, err := sw.NewFileBasedKeyStore(nil, filepath.Join(dir, "keystore"), true)
require.NoError(t, err)
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
require.NoError(t, err)
thisMSP, err := NewBccspMspWithKeyStore(version, ks, cryptoProvider)
require.NoError(t, err)
err = thisMSP.Setup(conf)
require.NoError(t, err)
return thisMSP
}
func TestCollectEmptyCombinedPrincipal(t *testing.T) {
var principalsArray []*msp.MSPPrincipal
combinedPrincipal := &msp.CombinedPrincipal{Principals: principalsArray}
combinedPrincipalBytes, err := proto.Marshal(combinedPrincipal)
require.NoError(t, err, "Error marshalling empty combined principal")
principalsCombined := &msp.MSPPrincipal{PrincipalClassification: msp.MSPPrincipal_COMBINED, Principal: combinedPrincipalBytes}
_, err = collectPrincipals(principalsCombined, MSPv1_3)
require.Error(t, err)
}
func TestCollectPrincipalContainingEmptyCombinedPrincipal(t *testing.T) {
var principalsArray []*msp.MSPPrincipal
combinedPrincipal := &msp.CombinedPrincipal{Principals: principalsArray}
combinedPrincipalBytes, err := proto.Marshal(combinedPrincipal)
require.NoError(t, err, "Error marshalling empty combined principal")
emptyPrincipal := &msp.MSPPrincipal{PrincipalClassification: msp.MSPPrincipal_COMBINED, Principal: combinedPrincipalBytes}
levelOneCombinedPrincipal, err := createCombinedPrincipal(emptyPrincipal)
require.NoError(t, err)
_, err = collectPrincipals(levelOneCombinedPrincipal, MSPv1_3)
require.Error(t, err)
}
func TestMSPIdentityIdentifier(t *testing.T) {
// testdata/mspid
// 1) a key and a signcert (used to populate the default signing identity) with the cert having a HighS signature
thisMSP := getLocalMSP(t, "testdata/mspid")
id, err := thisMSP.GetDefaultSigningIdentity()
require.NoError(t, err)
err = id.Validate()
require.NoError(t, err)
// Check that the identity identifier is computed with the respect to the lowS signature
idid := id.GetIdentifier()
require.NotNil(t, idid)
// Load and parse cacaert and signcert from folder
pems, err := getPemMaterialFromDir("testdata/mspid/cacerts")
require.NoError(t, err)
bl, _ := pem.Decode(pems[0])
require.NotNil(t, bl)
caCertFromFile, err := x509.ParseCertificate(bl.Bytes)
require.NoError(t, err)
pems, err = getPemMaterialFromDir("testdata/mspid/signcerts")
require.NoError(t, err)
bl, _ = pem.Decode(pems[0])
require.NotNil(t, bl)
certFromFile, err := x509.ParseCertificate(bl.Bytes)
require.NoError(t, err)
// Check that the certificates' raws are different, meaning that the identity has been sanitised
require.NotEqual(t, certFromFile.Raw, id.(*signingidentity).cert)
// Check that certFromFile is in HighS
_, S, err := utils.UnmarshalECDSASignature(certFromFile.Signature)
require.NoError(t, err)
lowS, err := utils.IsLowS(caCertFromFile.PublicKey.(*ecdsa.PublicKey), S)
require.NoError(t, err)
require.False(t, lowS)
// Check that id.(*signingidentity).cert is in LoswS
_, S, err = utils.UnmarshalECDSASignature(id.(*signingidentity).cert.Signature)
require.NoError(t, err)
lowS, err = utils.IsLowS(caCertFromFile.PublicKey.(*ecdsa.PublicKey), S)
require.NoError(t, err)
require.True(t, lowS)
// Compute the digest for certFromFile
thisBCCSPMsp := thisMSP.(*bccspmsp)
hashOpt, err := bccsp.GetHashOpt(thisBCCSPMsp.cryptoConfig.IdentityIdentifierHashFunction)
require.NoError(t, err)
digest, err := thisBCCSPMsp.bccsp.Hash(certFromFile.Raw, hashOpt)
require.NoError(t, err)
// Compare with the digest computed from the sanitised cert
require.NotEqual(t, idid.Id, hex.EncodeToString(digest))
}
func TestAnonymityIdentity(t *testing.T) {
id, err := localMspV13.GetDefaultSigningIdentity()
require.NoError(t, err)
principalBytes, err := proto.Marshal(&msp.MSPIdentityAnonymity{AnonymityType: msp.MSPIdentityAnonymity_NOMINAL})
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ANONYMITY,
Principal: principalBytes,
}
err = id.SatisfiesPrincipal(principal)
require.NoError(t, err)
}
func TestAnonymityIdentityPreV12Fail(t *testing.T) {
id, err := localMspV11.GetDefaultSigningIdentity()
require.NoError(t, err)
principalBytes, err := proto.Marshal(&msp.MSPIdentityAnonymity{AnonymityType: msp.MSPIdentityAnonymity_NOMINAL})
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ANONYMITY,
Principal: principalBytes,
}
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
}
func TestAnonymityIdentityFail(t *testing.T) {
id, err := localMspV13.GetDefaultSigningIdentity()
require.NoError(t, err)
principalBytes, err := proto.Marshal(&msp.MSPIdentityAnonymity{AnonymityType: msp.MSPIdentityAnonymity_ANONYMOUS})
require.NoError(t, err)
principal := &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ANONYMITY,
Principal: principalBytes,
}
err = id.SatisfiesPrincipal(principal)
require.Error(t, err)
}
func TestProviderTypeToString(t *testing.T) {
// Check that the provider type is found for FABRIC
pt := ProviderTypeToString(FABRIC)
require.Equal(t, "bccsp", pt)
// Check that the provider type is found for IDEMIX
pt = ProviderTypeToString(IDEMIX)
require.Equal(t, "idemix", pt)
// Check that the provider type is not found
pt = ProviderTypeToString(OTHER)
require.Equal(t, "", pt)
}