diff --git a/Makefile b/Makefile index 340bbf748..1c20afdc8 100644 --- a/Makefile +++ b/Makefile @@ -123,9 +123,13 @@ clean: docker network prune -f docker container prune -f rm -rf ./integration/token/fungible/dlog/cmd/ + rm -rf ./integration/token/fungible/dlog/testdata/ rm -rf ./integration/token/fungible/dloghsm/cmd/ + rm -rf ./integration/token/fungible/dloghsm/testdata/ rm -rf ./integration/token/fungible/dlogstress/cmd/ + rm -rf ./integration/token/fungible/dlogstress/testdata/ rm -rf ./integration/token/fungible/fabtoken/cmd/ + rm -rf ./integration/token/fungible/fabtoken/testdata/ rm -rf ./integration/token/fungible/odlog/cmd/ rm -rf ./integration/token/fungible/ofabtoken/cmd/ rm -rf ./integration/token/fungible/mixed/cmd/ diff --git a/ci/scripts/cleanup_softhsm.sh b/ci/scripts/cleanup_softhsm.sh new file mode 100755 index 000000000..0b083b9fe --- /dev/null +++ b/ci/scripts/cleanup_softhsm.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +LABEL_TO_DELETE="ForFSC" + +# Get all slot numbers +slots=$(softhsm2-util --show-slots | grep "Slot " | awk '{print $2}') + +for slot in $slots +do + # Check if the token in this slot has the label we want to delete + label=$(softhsm2-util --show-slots | grep -A 2 "Slot $slot" | grep "Label:" | awk '{print $2}') + if [ "$label" == "$LABEL_TO_DELETE" ]; then + echo "Deleting token in slot $slot with label $LABEL_TO_DELETE" + softhsm2-util --delete-token --token "$LABEL_TO_DELETE" + fi +done \ No newline at end of file diff --git a/ci/scripts/setup_softhsm.sh b/ci/scripts/setup_softhsm.sh index 692e4a948..59e67b778 100755 --- a/ci/scripts/setup_softhsm.sh +++ b/ci/scripts/setup_softhsm.sh @@ -16,9 +16,6 @@ if [[ "$OSTYPE" == "darwin"* ]]; then # Create tokens inside tmp folder echo directories.tokendir = /tmp > $CONFIGPATH/softhsm2.conf - #Delete existing token - # softhsm2-util --delete-token --token "ForFSC" || true - echo "Initializing tokens..." softhsm2-util --init-token --free --label "ForFSC" --so-pin 1234 --pin 98765432 @@ -26,8 +23,6 @@ else #Create directory to store hsm tokens sudo mkdir -p /var/lib/softhsm/tokens - #Delete existing token - softhsm2-util --delete-token --token "ForFSC" || true echo "Initializing tokens..." sudo softhsm2-util --init-token --slot 0 --label "ForFSC" --so-pin 1234 --pin 98765432 diff --git a/docs/core-token.md b/docs/core-token.md index ab0e5f7ba..4f4abeace 100644 --- a/docs/core-token.md +++ b/docs/core-token.md @@ -68,7 +68,7 @@ token: # Therefore, also FSC nodes equipped with proper endorsement keys can perform the same function. # This section is dedicated to the configuration of the endorsement of the token chaincode by # other FSC nodes. - endorsement: + fsc_endorsement: # Is this node an endorser?: true/false endorser: true # If this node is an endorser, which Fabric identity should be used to sign the endorsement? diff --git a/go.mod b/go.mod index 0dcd1f4be..691d72cb7 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/IBM/mathlib v0.0.3-0.20231011094432-44ee0eb539da github.com/gin-gonic/gin v1.10.0 github.com/hashicorp/go-uuid v1.0.3 - github.com/hyperledger-labs/fabric-smart-client v0.3.1-0.20241005130302-4dc84b0086d5 + github.com/hyperledger-labs/fabric-smart-client v0.3.1-0.20241021061520-9b09a4cb3756 github.com/hyperledger-labs/orion-sdk-go v0.2.10 github.com/hyperledger-labs/orion-server v0.2.10 github.com/hyperledger/fabric v1.4.0-rc1.0.20230405174026-695dd57e01c2 diff --git a/go.sum b/go.sum index d053db44e..207f696ac 100644 --- a/go.sum +++ b/go.sum @@ -1067,8 +1067,8 @@ github.com/hidal-go/hidalgo v0.0.0-20201109092204-05749a6d73df/go.mod h1:bPkrxDl github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/hyperledger-labs/fabric-smart-client v0.3.1-0.20241005130302-4dc84b0086d5 h1:wth+4n2Ej29MHwywtJkKWnlsEuFhFd+qSKhYLUDYlYY= -github.com/hyperledger-labs/fabric-smart-client v0.3.1-0.20241005130302-4dc84b0086d5/go.mod h1:vZLAiVznnEdHyx1OV5nIqf34apnfdhonwJL+qEYniIQ= +github.com/hyperledger-labs/fabric-smart-client v0.3.1-0.20241021061520-9b09a4cb3756 h1:kJqTELZpGmccM32uLEHdqASOUODOM6J6yjNPiIWvGhg= +github.com/hyperledger-labs/fabric-smart-client v0.3.1-0.20241021061520-9b09a4cb3756/go.mod h1:vZLAiVznnEdHyx1OV5nIqf34apnfdhonwJL+qEYniIQ= github.com/hyperledger-labs/orion-sdk-go v0.2.10 h1:lFgWgxyvngIhWnIqymYGBmtmq9D6uC5d0uLG9cbyh5s= github.com/hyperledger-labs/orion-sdk-go v0.2.10/go.mod h1:iN2xZB964AqwVJwL+EnwPOs8z1EkMEbbIg/qYeC7gDY= github.com/hyperledger-labs/orion-server v0.2.10 h1:G4zbQEL5Egk0Oj+TwHCZWdTOLDBHOjaAEvYOT4G7ozw= diff --git a/integration/nwo/token/common/ppmgen.go b/integration/nwo/token/common/ppmgen.go index 49b74561a..f5bd7be6e 100644 --- a/integration/nwo/token/common/ppmgen.go +++ b/integration/nwo/token/common/ppmgen.go @@ -54,7 +54,7 @@ func (f *FabTokenPublicParamsGenerator) Generate(tms *topology.TMS, wallets *gen } for _, auditor := range wallets.Auditors { // Build an MSP Identity - provider, _, err := x509.NewProvider(auditor.Path, "", msp2.AuditorMSPID, nil, auditor.Opts) + provider, _, err := x509.NewKeyManager(auditor.Path, "", msp2.AuditorMSPID, nil, auditor.Opts) if err != nil { return nil, errors.WithMessage(err, "failed to create x509 provider") } @@ -74,7 +74,7 @@ func (f *FabTokenPublicParamsGenerator) Generate(tms *topology.TMS, wallets *gen } for _, issuer := range wallets.Issuers { // Build an MSP Identity - provider, _, err := x509.NewProvider(issuer.Path, "", msp2.AuditorMSPID, nil, issuer.Opts) + provider, _, err := x509.NewKeyManager(issuer.Path, "", msp2.AuditorMSPID, nil, issuer.Opts) if err != nil { return nil, errors.WithMessage(err, "failed to create x509 provider") } @@ -148,7 +148,7 @@ func (d *DLogPublicParamsGenerator) Generate(tms *topology.TMS, wallets *generat } for _, auditor := range wallets.Auditors { // Build an MSP Identity - provider, _, err := x509.NewProvider(auditor.Path, "", msp2.AuditorMSPID, nil, auditor.Opts) + provider, _, err := x509.NewKeyManager(auditor.Path, "", msp2.AuditorMSPID, nil, auditor.Opts) if err != nil { return nil, errors.WithMessage(err, "failed to create x509 provider") } @@ -168,7 +168,7 @@ func (d *DLogPublicParamsGenerator) Generate(tms *topology.TMS, wallets *generat } for _, issuer := range wallets.Issuers { // Build an MSP Identity - provider, _, err := x509.NewProvider(issuer.Path, "", msp2.AuditorMSPID, nil, issuer.Opts) + provider, _, err := x509.NewKeyManager(issuer.Path, "", msp2.AuditorMSPID, nil, issuer.Opts) if err != nil { return nil, errors.WithMessage(err, "failed to create x509 provider") } diff --git a/integration/token/fungible/dlog/dlog_test.go b/integration/token/fungible/dlog/dlog_test.go index 798d7a2ae..53597af43 100644 --- a/integration/token/fungible/dlog/dlog_test.go +++ b/integration/token/fungible/dlog/dlog_test.go @@ -138,7 +138,7 @@ func newTestSuite(commType fsc.P2PCommunicationType, mask int, factor int, token Monitoring: false, ReplicationOpts: opts, FSCBasedEndorsement: mask&WithEndorsers > 0, - //FSCLogSpec: "token-sdk=debug:fabric-sdk=debug:info", + // FSCLogSpec: "token-sdk=debug:fabric-sdk=debug:info", OnlyUnity: true, TokenSelector: tokenSelector, }, diff --git a/integration/token/fungible/dloghsm/dlog_test.go b/integration/token/fungible/dloghsm/dlog_test.go index a9b2b95bd..18fb9d502 100644 --- a/integration/token/fungible/dloghsm/dlog_test.go +++ b/integration/token/fungible/dloghsm/dlog_test.go @@ -57,6 +57,7 @@ func newTestSuite(commType fsc.P2PCommunicationType, mask int, factor int, names HSM: mask&HSM > 0, WebEnabled: mask&WebEnabled > 0, SDKs: []api.SDK{&fdlog.SDK{}}, + // FSCLogSpec: "token-sdk=debug:fabric-sdk=debug:info", ReplicationOpts: opts, OnlyUnity: true, }, diff --git a/integration/token/fungible/fabtoken/fabtoken_test.go b/integration/token/fungible/fabtoken/fabtoken_test.go index 7f26297da..0cb2aff08 100644 --- a/integration/token/fungible/fabtoken/fabtoken_test.go +++ b/integration/token/fungible/fabtoken/fabtoken_test.go @@ -24,7 +24,7 @@ import ( ) var _ = Describe("EndToEnd", func() { - for _, t := range integration2.WebSocketNoReplicationOnly { + for _, t := range integration2.AllTestTypes { Describe("Fungible", t.Label, func() { ts, selector := newTestSuite(t.CommType, t.ReplicationFactor, "alice", "bob", "charlie") BeforeEach(ts.Setup) @@ -65,7 +65,7 @@ func newTestSuite(commType fsc.P2PCommunicationType, factor int, names ...string SDKs: []api.SDK{&ffabtoken.SDK{}}, ReplicationOpts: opts, WebEnabled: true, // Needed for the Remote Wallet with websockets - //FSCLogSpec: "token-sdk=debug:fabric-sdk=debug:info", + // FSCLogSpec: "token-sdk=debug:fabric-sdk=debug:info", OnlyUnity: true, }, )) diff --git a/integration/token/fungible/support.go b/integration/token/fungible/support.go index f071a794d..cdb418623 100644 --- a/integration/token/fungible/support.go +++ b/integration/token/fungible/support.go @@ -60,6 +60,7 @@ func RegisterAuditorForTMSID(network *integration.Infrastructure, auditor *token func getTmsId(network *integration.Infrastructure, namespace string) *token2.TMSID { fabricTopology := getFabricTopology(network) + Expect(fabricTopology).NotTo(BeNil()) return &token2.TMSID{ Network: fabricTopology.Name(), Channel: fabricTopology.Channels[0].Name, @@ -73,7 +74,7 @@ func getFabricTopology(network *integration.Infrastructure) *topology2.Topology return t.(*topology2.Topology) } } - panic("no fabric topology found") + return nil } func IssueCash(network *integration.Infrastructure, wallet string, typ string, amount uint64, receiver *token3.NodeReference, auditor *token3.NodeReference, anonymous bool, issuer *token3.NodeReference, expectedErrorMsgs ...string) string { @@ -112,8 +113,11 @@ func issueCashForTMSID(network *integration.Infrastructure, wallet string, typ s for _, n := range []*token3.NodeReference{receiver, auditor} { common2.CheckFinality(network, n, txID, tmsId, false) } - for _, n := range endorsers { - common2.CheckEndorserFinality(network, n, txID, tmsId, false) + // Perform this check only if there is a fabric network + if getFabricTopology(network) != nil { + for _, n := range endorsers { + common2.CheckEndorserFinality(network, n, txID, tmsId, false) + } } return common.JSONUnmarshalString(txIDBoxed) } @@ -1023,7 +1027,8 @@ func Restart(network *integration.Infrastructure, deleteVault bool, ids ...*toke if on != nil { on.DeleteVault(id.Id()) } else { - Expect(false).To(BeTrue(), "neither fabric nor orion network found") + // TODO: handle additional platforms + logger.Warnf("neither fabric nor orion network found") } } diff --git a/token/core/common/authrorization.go b/token/core/common/authrorization.go index 062a25f2e..cfe5b2d79 100644 --- a/token/core/common/authrorization.go +++ b/token/core/common/authrorization.go @@ -10,7 +10,9 @@ import ( "github.com/hyperledger-labs/fabric-token-sdk/token" "github.com/hyperledger-labs/fabric-token-sdk/token/driver" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging" token2 "github.com/hyperledger-labs/fabric-token-sdk/token/token" + "github.com/pkg/errors" ) type Authorization interface { @@ -27,20 +29,25 @@ type Authorization interface { // WalletBasedAuthorization is a wallet-based authorization implementation type WalletBasedAuthorization struct { + Logger logging.Logger PublicParameters driver.PublicParameters WalletService driver.WalletService amIAnAuditor bool } -func NewTMSAuthorization(publicParameters driver.PublicParameters, walletService driver.WalletService) *WalletBasedAuthorization { +func NewTMSAuthorization(logger logging.Logger, publicParameters driver.PublicParameters, walletService driver.WalletService) *WalletBasedAuthorization { amIAnAuditor := false + var errs []error for _, identity := range publicParameters.Auditors() { - if _, err := walletService.AuditorWallet(identity); err == nil { + _, err := walletService.AuditorWallet(identity) + if err == nil { amIAnAuditor = true break } + errs = append(errs, errors.Wrapf(err, "I'm not this auditor identity [%s]", identity)) } - return &WalletBasedAuthorization{PublicParameters: publicParameters, WalletService: walletService, amIAnAuditor: amIAnAuditor} + logger.Debugf("am I an auditor? [%v], with errs [%v]", amIAnAuditor, errs) + return &WalletBasedAuthorization{Logger: logger, PublicParameters: publicParameters, WalletService: walletService, amIAnAuditor: amIAnAuditor} } // IsMine returns true if the passed token is owned by an owner wallet. diff --git a/token/core/common/validator.go b/token/core/common/validator.go index 0933d80a4..20f20b3ef 100644 --- a/token/core/common/validator.go +++ b/token/core/common/validator.go @@ -20,10 +20,10 @@ const ( TokenRequestToSign driver.ValidationAttributeID = "trs" ) -type Context[P driver.PublicParameters, T any, TA driver.TransferAction, IA driver.IssueAction] struct { +type Context[P driver.PublicParameters, T any, TA driver.TransferAction, IA driver.IssueAction, DS driver.Deserializer] struct { Logger logging.Logger PP P - Deserializer driver.Deserializer + Deserializer DS SignatureProvider driver.SignatureProvider Signatures [][]byte InputTokens []T @@ -34,38 +34,38 @@ type Context[P driver.PublicParameters, T any, TA driver.TransferAction, IA driv Attributes driver.ValidationAttributes } -func (c *Context[P, T, TA, IA]) CountMetadataKey(key string) { +func (c *Context[P, T, TA, IA, DS]) CountMetadataKey(key string) { c.MetadataCounter[key] = c.MetadataCounter[key] + 1 } -type ValidateTransferFunc[P driver.PublicParameters, T any, TA driver.TransferAction, IA driver.IssueAction] func(ctx *Context[P, T, TA, IA]) error +type ValidateTransferFunc[P driver.PublicParameters, T any, TA driver.TransferAction, IA driver.IssueAction, DS driver.Deserializer] func(ctx *Context[P, T, TA, IA, DS]) error -type ValidateIssueFunc[P driver.PublicParameters, T any, TA driver.TransferAction, IA driver.IssueAction] func(ctx *Context[P, T, TA, IA]) error +type ValidateIssueFunc[P driver.PublicParameters, T any, TA driver.TransferAction, IA driver.IssueAction, DS driver.Deserializer] func(ctx *Context[P, T, TA, IA, DS]) error type ActionDeserializer[TA driver.TransferAction, IA driver.IssueAction] interface { DeserializeActions(tr *driver.TokenRequest) ([]IA, []TA, error) } -type Validator[P driver.PublicParameters, T any, TA driver.TransferAction, IA driver.IssueAction] struct { +type Validator[P driver.PublicParameters, T any, TA driver.TransferAction, IA driver.IssueAction, DS driver.Deserializer] struct { Logger logging.Logger PublicParams P - Deserializer driver.Deserializer + Deserializer DS ActionDeserializer ActionDeserializer[TA, IA] - TransferValidators []ValidateTransferFunc[P, T, TA, IA] - IssueValidators []ValidateIssueFunc[P, T, TA, IA] + TransferValidators []ValidateTransferFunc[P, T, TA, IA, DS] + IssueValidators []ValidateIssueFunc[P, T, TA, IA, DS] Serializer driver.Serializer } -func NewValidator[P driver.PublicParameters, T any, TA driver.TransferAction, IA driver.IssueAction]( +func NewValidator[P driver.PublicParameters, T any, TA driver.TransferAction, IA driver.IssueAction, DS driver.Deserializer]( Logger logging.Logger, publicParams P, - deserializer driver.Deserializer, + deserializer DS, actionDeserializer ActionDeserializer[TA, IA], - transferValidators []ValidateTransferFunc[P, T, TA, IA], - issueValidators []ValidateIssueFunc[P, T, TA, IA], + transferValidators []ValidateTransferFunc[P, T, TA, IA, DS], + issueValidators []ValidateIssueFunc[P, T, TA, IA, DS], serializer driver.Serializer, -) *Validator[P, T, TA, IA] { - return &Validator[P, T, TA, IA]{ +) *Validator[P, T, TA, IA, DS] { + return &Validator[P, T, TA, IA, DS]{ Logger: Logger, PublicParams: publicParams, Deserializer: deserializer, @@ -76,7 +76,7 @@ func NewValidator[P driver.PublicParameters, T any, TA driver.TransferAction, IA } } -func (v *Validator[P, T, TA, IA]) VerifyTokenRequestFromRaw(ctx context.Context, getState driver.GetStateFnc, anchor string, raw []byte) ([]interface{}, driver.ValidationAttributes, error) { +func (v *Validator[P, T, TA, IA, DS]) VerifyTokenRequestFromRaw(ctx context.Context, getState driver.GetStateFnc, anchor string, raw []byte) ([]interface{}, driver.ValidationAttributes, error) { if len(raw) == 0 { return nil, nil, errors.New("empty token request") } @@ -115,7 +115,7 @@ func (v *Validator[P, T, TA, IA]) VerifyTokenRequestFromRaw(ctx context.Context, return v.VerifyTokenRequest(backend, backend, anchor, tr, attributes) } -func (v *Validator[P, T, TA, IA]) VerifyTokenRequest(ledger driver.Ledger, signatureProvider driver.SignatureProvider, anchor string, tr *driver.TokenRequest, attributes driver.ValidationAttributes) ([]interface{}, driver.ValidationAttributes, error) { +func (v *Validator[P, T, TA, IA, DS]) VerifyTokenRequest(ledger driver.Ledger, signatureProvider driver.SignatureProvider, anchor string, tr *driver.TokenRequest, attributes driver.ValidationAttributes) ([]interface{}, driver.ValidationAttributes, error) { if err := v.verifyAuditorSignature(signatureProvider, attributes); err != nil { return nil, nil, errors.Wrapf(err, "failed to verifier auditor's signature [%s]", anchor) } @@ -142,7 +142,7 @@ func (v *Validator[P, T, TA, IA]) VerifyTokenRequest(ledger driver.Ledger, signa return actions, attributes, nil } -func (v *Validator[P, T, TA, IA]) UnmarshalActions(raw []byte) ([]interface{}, error) { +func (v *Validator[P, T, TA, IA, DS]) UnmarshalActions(raw []byte) ([]interface{}, error) { tr := &driver.TokenRequest{} err := tr.FromBytes(raw) if err != nil { @@ -163,7 +163,7 @@ func (v *Validator[P, T, TA, IA]) UnmarshalActions(raw []byte) ([]interface{}, e return res, nil } -func (v *Validator[P, T, TA, IA]) verifyAuditorSignature(signatureProvider driver.SignatureProvider, attributes driver.ValidationAttributes) error { +func (v *Validator[P, T, TA, IA, DS]) verifyAuditorSignature(signatureProvider driver.SignatureProvider, attributes driver.ValidationAttributes) error { if len(v.PublicParams.Auditors()) != 0 { auditor := v.PublicParams.Auditors()[0] verifier, err := v.Deserializer.GetAuditorVerifier(auditor) @@ -176,7 +176,7 @@ func (v *Validator[P, T, TA, IA]) verifyAuditorSignature(signatureProvider drive return nil } -func (v *Validator[P, T, TA, IA]) verifyIssues(ledger driver.Ledger, issues []IA, signatureProvider driver.SignatureProvider, attributes driver.ValidationAttributes) error { +func (v *Validator[P, T, TA, IA, DS]) verifyIssues(ledger driver.Ledger, issues []IA, signatureProvider driver.SignatureProvider, attributes driver.ValidationAttributes) error { for _, issue := range issues { if err := v.verifyIssue(issue, ledger, signatureProvider, attributes); err != nil { return errors.Wrapf(err, "failed to verify transfer action") @@ -185,8 +185,8 @@ func (v *Validator[P, T, TA, IA]) verifyIssues(ledger driver.Ledger, issues []IA return nil } -func (v *Validator[P, T, TA, IA]) verifyIssue(tr IA, ledger driver.Ledger, signatureProvider driver.SignatureProvider, attributes driver.ValidationAttributes) error { - context := &Context[P, T, TA, IA]{ +func (v *Validator[P, T, TA, IA, DS]) verifyIssue(tr IA, ledger driver.Ledger, signatureProvider driver.SignatureProvider, attributes driver.ValidationAttributes) error { + context := &Context[P, T, TA, IA, DS]{ Logger: v.Logger, PP: v.PublicParams, Deserializer: v.Deserializer, @@ -217,7 +217,7 @@ func (v *Validator[P, T, TA, IA]) verifyIssue(tr IA, ledger driver.Ledger, signa return nil } -func (v *Validator[P, T, TA, IA]) verifyTransfers(ledger driver.Ledger, transferActions []TA, signatureProvider driver.SignatureProvider, attributes driver.ValidationAttributes) error { +func (v *Validator[P, T, TA, IA, DS]) verifyTransfers(ledger driver.Ledger, transferActions []TA, signatureProvider driver.SignatureProvider, attributes driver.ValidationAttributes) error { v.Logger.Debugf("check sender start...") defer v.Logger.Debugf("check sender finished.") for _, action := range transferActions { @@ -228,8 +228,8 @@ func (v *Validator[P, T, TA, IA]) verifyTransfers(ledger driver.Ledger, transfer return nil } -func (v *Validator[P, T, TA, IA]) verifyTransfer(tr TA, ledger driver.Ledger, signatureProvider driver.SignatureProvider, attributes driver.ValidationAttributes) error { - context := &Context[P, T, TA, IA]{ +func (v *Validator[P, T, TA, IA, DS]) verifyTransfer(tr TA, ledger driver.Ledger, signatureProvider driver.SignatureProvider, attributes driver.ValidationAttributes) error { + context := &Context[P, T, TA, IA, DS]{ Logger: v.Logger, PP: v.PublicParams, Deserializer: v.Deserializer, diff --git a/token/core/common/ws.go b/token/core/common/ws.go index d608d9aff..650e10b67 100644 --- a/token/core/common/ws.go +++ b/token/core/common/ws.go @@ -39,6 +39,7 @@ type WalletRegistry interface { RegisterWallet(id string, wallet driver.Wallet) error BindIdentity(identity driver.Identity, eID string, wID string, meta any) error ContainsIdentity(i driver.Identity, id string) bool + GetIdentityMetadata(identity driver.Identity, wID string, meta any) error } type WalletFactory interface { diff --git a/token/core/fabtoken/driver/base.go b/token/core/fabtoken/driver/base.go index 00d4d8abb..d9a641eb9 100644 --- a/token/core/fabtoken/driver/base.go +++ b/token/core/fabtoken/driver/base.go @@ -12,8 +12,8 @@ import ( "github.com/hyperledger-labs/fabric-token-sdk/token/driver" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity" config2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/config" + common2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/driver" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp" - common2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/common" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/sig" "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging" "github.com/pkg/errors" @@ -64,6 +64,7 @@ func (d *base) newWalletService( } roleFactory := msp.NewRoleFactory( + logger, tmsID, identityConfig, // config fscIdentity, // FSC identity diff --git a/token/core/fabtoken/driver/driver.go b/token/core/fabtoken/driver/driver.go index 7d257624f..e79bac8bf 100644 --- a/token/core/fabtoken/driver/driver.go +++ b/token/core/fabtoken/driver/driver.go @@ -8,6 +8,7 @@ package driver import ( "github.com/hyperledger-labs/fabric-smart-client/platform/view" + "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" view2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/server/view" tracing2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/tracing" "github.com/hyperledger-labs/fabric-token-sdk/token/core/common" @@ -63,6 +64,8 @@ func NewDriver( func (d *Driver) NewTokenService(_ driver.ServiceProvider, networkID string, channel string, namespace string, publicParams []byte) (driver.TokenManagerService, error) { logger := logging.DriverLogger("token-sdk.driver.fabtoken", networkID, channel, namespace) + logger.Debugf("creating new token service with public parameters [%s]", hash.Hashable(publicParams)) + if len(publicParams) == 0 { return nil, errors.Errorf("empty public parameters") } @@ -104,7 +107,7 @@ func (d *Driver) NewTokenService(_ driver.ServiceProvider, networkID string, cha metricsProvider := metrics.NewTMSProvider(tmsConfig.ID(), d.metricsProvider) tracerProvider := tracing2.NewTracerProviderWithBackingProvider(d.tracerProvider, metricsProvider) authorization := common.NewAuthorizationMultiplexer( - common.NewTMSAuthorization(publicParamsManager.PublicParams(), ws), + common.NewTMSAuthorization(logger, publicParamsManager.PublicParams(), ws), htlc.NewScriptAuth(ws), ) service, err := fabtoken.NewService( diff --git a/token/core/fabtoken/validator.go b/token/core/fabtoken/validator.go index 1ba246358..8eb537e10 100644 --- a/token/core/fabtoken/validator.go +++ b/token/core/fabtoken/validator.go @@ -13,9 +13,9 @@ import ( "github.com/hyperledger-labs/fabric-token-sdk/token/token" ) -type ValidateTransferFunc = common.ValidateTransferFunc[*PublicParams, *token.Token, *TransferAction, *IssueAction] +type ValidateTransferFunc = common.ValidateTransferFunc[*PublicParams, *token.Token, *TransferAction, *IssueAction, driver.Deserializer] -type ValidateIssueFunc = common.ValidateIssueFunc[*PublicParams, *token.Token, *TransferAction, *IssueAction] +type ValidateIssueFunc = common.ValidateIssueFunc[*PublicParams, *token.Token, *TransferAction, *IssueAction, driver.Deserializer] type ActionDeserializer struct{} @@ -41,9 +41,9 @@ func (a *ActionDeserializer) DeserializeActions(tr *driver.TokenRequest) ([]*Iss return issueActions, transferActions, nil } -type Context = common.Context[*PublicParams, *token.Token, *TransferAction, *IssueAction] +type Context = common.Context[*PublicParams, *token.Token, *TransferAction, *IssueAction, driver.Deserializer] -type Validator = common.Validator[*PublicParams, *token.Token, *TransferAction, *IssueAction] +type Validator = common.Validator[*PublicParams, *token.Token, *TransferAction, *IssueAction, driver.Deserializer] func NewValidator(logger logging.Logger, pp *PublicParams, deserializer driver.Deserializer, extraValidators ...ValidateTransferFunc) *Validator { transferValidators := []ValidateTransferFunc{ @@ -57,7 +57,7 @@ func NewValidator(logger logging.Logger, pp *PublicParams, deserializer driver.D IssueValidate, } - return common.NewValidator[*PublicParams, *token.Token, *TransferAction, *IssueAction]( + return common.NewValidator[*PublicParams, *token.Token, *TransferAction, *IssueAction, driver.Deserializer]( logger, pp, deserializer, diff --git a/token/core/zkatdlog/crypto/audit/auditor_test.go b/token/core/zkatdlog/crypto/audit/auditor_test.go index 3ea64efaa..11bc0e4d0 100644 --- a/token/core/zkatdlog/crypto/audit/auditor_test.go +++ b/token/core/zkatdlog/crypto/audit/auditor_test.go @@ -255,7 +255,7 @@ func getIdemixInfo(dir string) (driver.Identity, *msp3.AuditInfo) { Expect(err).NotTo(HaveOccurred()) cryptoProvider, err := msp3.NewBCCSP(keyStore, math.FP256BN_AMCL, false) Expect(err).NotTo(HaveOccurred()) - p, err := idemix.NewProvider(config, sigService, types.EidNymRhNym, cryptoProvider) + p, err := idemix.NewKeyManager(config, sigService, types.EidNymRhNym, cryptoProvider) Expect(err).NotTo(HaveOccurred()) Expect(p).NotTo(BeNil()) diff --git a/token/core/zkatdlog/crypto/validator/validator.go b/token/core/zkatdlog/crypto/validator/validator.go index 3a91a0220..cacadd898 100644 --- a/token/core/zkatdlog/crypto/validator/validator.go +++ b/token/core/zkatdlog/crypto/validator/validator.go @@ -16,11 +16,11 @@ import ( "github.com/hyperledger-labs/fabric-token-sdk/token/driver" ) -type ValidateTransferFunc = common.ValidateTransferFunc[*crypto.PublicParams, *token.Token, *transfer.Action, *issue.IssueAction] +type ValidateTransferFunc = common.ValidateTransferFunc[*crypto.PublicParams, *token.Token, *transfer.Action, *issue.IssueAction, driver.Deserializer] -type ValidateIssueFunc = common.ValidateIssueFunc[*crypto.PublicParams, *token.Token, *transfer.Action, *issue.IssueAction] +type ValidateIssueFunc = common.ValidateIssueFunc[*crypto.PublicParams, *token.Token, *transfer.Action, *issue.IssueAction, driver.Deserializer] -type Context = common.Context[*crypto.PublicParams, *token.Token, *transfer.Action, *issue.IssueAction] +type Context = common.Context[*crypto.PublicParams, *token.Token, *transfer.Action, *issue.IssueAction, driver.Deserializer] type ActionDeserializer struct{} @@ -46,7 +46,7 @@ func (a *ActionDeserializer) DeserializeActions(tr *driver.TokenRequest) ([]*iss return issueActions, transferActions, nil } -type Validator = common.Validator[*crypto.PublicParams, *token.Token, *transfer.Action, *issue.IssueAction] +type Validator = common.Validator[*crypto.PublicParams, *token.Token, *transfer.Action, *issue.IssueAction, driver.Deserializer] func New(logger logging.Logger, pp *crypto.PublicParams, deserializer driver.Deserializer, extraValidators ...ValidateTransferFunc) *Validator { transferValidators := []ValidateTransferFunc{ @@ -60,7 +60,7 @@ func New(logger logging.Logger, pp *crypto.PublicParams, deserializer driver.Des IssueValidate, } - return common.NewValidator[*crypto.PublicParams, *token.Token, *transfer.Action, *issue.IssueAction]( + return common.NewValidator[*crypto.PublicParams, *token.Token, *transfer.Action, *issue.IssueAction, driver.Deserializer]( logger, pp, deserializer, diff --git a/token/core/zkatdlog/crypto/validator/validator_test.go b/token/core/zkatdlog/crypto/validator/validator_test.go index 3707a064b..bc39c87d5 100644 --- a/token/core/zkatdlog/crypto/validator/validator_test.go +++ b/token/core/zkatdlog/crypto/validator/validator_test.go @@ -387,7 +387,7 @@ func getIdemixInfo(dir string) (driver.Identity, *msp3.AuditInfo, driver.Signing Expect(err).NotTo(HaveOccurred()) cryptoProvider, err := msp3.NewBCCSP(keyStore, math.FP256BN_AMCL, false) Expect(err).NotTo(HaveOccurred()) - p, err := idemix.NewProvider(config, sigService, types.EidNymRhNym, cryptoProvider) + p, err := idemix.NewKeyManager(config, sigService, types.EidNymRhNym, cryptoProvider) Expect(err).NotTo(HaveOccurred()) Expect(p).NotTo(BeNil()) diff --git a/token/core/zkatdlog/nogh/driver/base.go b/token/core/zkatdlog/nogh/driver/base.go index 46441776f..6bc911f3c 100644 --- a/token/core/zkatdlog/nogh/driver/base.go +++ b/token/core/zkatdlog/nogh/driver/base.go @@ -15,8 +15,8 @@ import ( "github.com/hyperledger-labs/fabric-token-sdk/token/driver" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity" config2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/config" + common2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/driver" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp" - common2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/common" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/sig" "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging" "github.com/pkg/errors" @@ -68,6 +68,7 @@ func (d *base) newWalletService( return nil, errors.WithMessage(err, "failed to create identity config") } roleFactory := msp.NewRoleFactory( + logger, tmsID, identityConfig, // config fscIdentity, // FSC identity diff --git a/token/core/zkatdlog/nogh/driver/driver.go b/token/core/zkatdlog/nogh/driver/driver.go index cb3b07635..8658e76df 100644 --- a/token/core/zkatdlog/nogh/driver/driver.go +++ b/token/core/zkatdlog/nogh/driver/driver.go @@ -8,6 +8,7 @@ package driver import ( "github.com/hyperledger-labs/fabric-smart-client/platform/view" + "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" view2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/server/view" tracing2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/tracing" "github.com/hyperledger-labs/fabric-token-sdk/token/core/common" @@ -64,6 +65,8 @@ func NewDriver( func (d *Driver) NewTokenService(_ driver.ServiceProvider, networkID string, channel string, namespace string, publicParams []byte) (driver.TokenManagerService, error) { logger := logging.DriverLogger("token-sdk.driver.zkatdlog", networkID, channel, namespace) + logger.Debugf("creating new token service with public parameters [%s]", hash.Hashable(publicParams)) + if len(publicParams) == 0 { return nil, errors.Errorf("empty public parameters") } @@ -104,7 +107,7 @@ func (d *Driver) NewTokenService(_ driver.ServiceProvider, networkID string, cha tokDeserializer := &TokenDeserializer{} authorization := common.NewAuthorizationMultiplexer( - common.NewTMSAuthorization(ppm.PublicParams(), ws), + common.NewTMSAuthorization(logger, ppm.PublicParams(), ws), htlc.NewScriptAuth(ws), ) diff --git a/token/driver/identity.go b/token/driver/identity.go index 692fe54e2..84b7d47e0 100644 --- a/token/driver/identity.go +++ b/token/driver/identity.go @@ -25,6 +25,15 @@ const ( CertifierRole ) +var ( + IdentityRoleStrings = map[IdentityRole]string{ + IssuerRole: "issuer", + AuditorRole: "auditor", + OwnerRole: "owner", + CertifierRole: "certifier", + } +) + // IdentityInfo models a long-term identity inside the Identity Provider. // An identity has an identifier (ID) and an Enrollment ID, unique identifier. // An identity can be remote, meaning that the corresponding secret key is remotely available. diff --git a/token/driver/publicparams.go b/token/driver/publicparams.go index 53695f376..b10ef305d 100644 --- a/token/driver/publicparams.go +++ b/token/driver/publicparams.go @@ -24,9 +24,9 @@ func (pp *SerializedPublicParameters) Deserialize(raw []byte) error { return nil } -// DefaultPublicParamsFetcher models a public parameters fetcher per namespace. -type DefaultPublicParamsFetcher interface { - // Fetch fetches the public parameters from a repository for a given namespace. +// NetworkPublicParamsFetcher models a public parameters fetcher per network. +type NetworkPublicParamsFetcher interface { + // Fetch fetches the public parameters for the given network, channel, and namespace Fetch(network driver.Network, channel driver.Channel, namespace driver.Namespace) ([]byte, error) } diff --git a/token/sdk/dig/sdk.go b/token/sdk/dig/sdk.go index dc95da6fc..93d9b30e6 100644 --- a/token/sdk/dig/sdk.go +++ b/token/sdk/dig/sdk.go @@ -42,7 +42,6 @@ import ( "github.com/hyperledger-labs/fabric-token-sdk/token/services/network/common" driver3 "github.com/hyperledger-labs/fabric-token-sdk/token/services/network/driver" "github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/network/orion" sdriver "github.com/hyperledger-labs/fabric-token-sdk/token/services/selector/driver" "github.com/hyperledger-labs/fabric-token-sdk/token/services/selector/sherdlock" selector "github.com/hyperledger-labs/fabric-token-sdk/token/services/selector/simple" @@ -144,7 +143,6 @@ func (p *SDK) Install() error { return sherdlock.NewFetcherProvider(dbManager, notifierManager, metricsProvider, sherdlock.Mixed) }), p.Container().Provide(fabric.NewChaincodePublicParamsFetcher, dig.As(new(fabric.DefaultPublicParamsFetcher))), - p.Container().Provide(orion.NewCustodianPublicParamsFetcher, dig.As(new(orion.DefaultPublicParamsFetcher))), ) if err != nil { return errors.WithMessagef(err, "failed setting up dig container") @@ -228,14 +226,10 @@ func connectNetworks(configService *config2.Service, networkProvider *network.Pr if err != nil { return errors.Wrapf(err, "failed to get network [%s]", tmsID) } - opts, err := net.Connect(tmsID.Namespace) + _, err = net.Connect(tmsID.Namespace) if err != nil { return errors.WithMessagef(err, "failed to connect to connect backend to tms [%s]", tmsID) } - _, err = tmsProvider.GetManagementService(opts...) - if err != nil { - return errors.WithMessagef(err, "failed to instantiate tms [%s]", tmsID) - } } logger.Infof("Token platform enabled, starting...done") return nil diff --git a/token/services/identity/msp/idemix/role.go b/token/services/identity/common/anonrole.go similarity index 54% rename from token/services/identity/msp/idemix/role.go rename to token/services/identity/common/anonrole.go index b485e02e2..43942abca 100644 --- a/token/services/identity/msp/idemix/role.go +++ b/token/services/identity/common/anonrole.go @@ -4,13 +4,14 @@ Copyright IBM Corp. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -package idemix +package common import ( "runtime/debug" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" "github.com/hyperledger-labs/fabric-token-sdk/token/driver" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging" "github.com/pkg/errors" "go.uber.org/zap/zapcore" ) @@ -25,16 +26,18 @@ type localMembership interface { IDs() ([]string, error) } -// Role is a container of idemix-based long-term identities. -type Role struct { +// AnonymousRole models a role whose identities are anonymous +type AnonymousRole struct { + logger logging.Logger roleID driver.IdentityRole networkID string nodeIdentity driver.Identity localMembership localMembership } -func NewRole(roleID driver.IdentityRole, networkID string, nodeIdentity driver.Identity, localMembership localMembership) *Role { - return &Role{ +func NewAnonymousRole(logger logging.Logger, roleID driver.IdentityRole, networkID string, nodeIdentity driver.Identity, localMembership localMembership) *AnonymousRole { + return &AnonymousRole{ + logger: logger, roleID: roleID, networkID: networkID, nodeIdentity: nodeIdentity, @@ -42,14 +45,14 @@ func NewRole(roleID driver.IdentityRole, networkID string, nodeIdentity driver.I } } -func (r *Role) ID() driver.IdentityRole { +func (r *AnonymousRole) ID() driver.IdentityRole { return r.roleID } // GetIdentityInfo returns the identity information for the given identity identifier -func (r *Role) GetIdentityInfo(id string) (driver.IdentityInfo, error) { - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("[%s] getting info for [%s]", r.networkID, id) +func (r *AnonymousRole) GetIdentityInfo(id string) (driver.IdentityInfo, error) { + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("[%s] getting info for [%s]", r.networkID, id) } info, err := r.localMembership.GetIdentityInfo(id, nil) @@ -60,7 +63,7 @@ func (r *Role) GetIdentityInfo(id string) (driver.IdentityInfo, error) { } // MapToID returns the identity for the given argument -func (r *Role) MapToID(v driver.WalletLookupID) (driver.Identity, string, error) { +func (r *AnonymousRole) MapToID(v driver.WalletLookupID) (driver.Identity, string, error) { switch vv := v.(type) { case []byte: return r.mapIdentityToID(vv) @@ -73,12 +76,21 @@ func (r *Role) MapToID(v driver.WalletLookupID) (driver.Identity, string, error) } } -func (r *Role) mapStringToID(v string) (driver.Identity, string, error) { +// RegisterIdentity registers the given identity +func (r *AnonymousRole) RegisterIdentity(config driver.IdentityConfiguration) error { + return r.localMembership.RegisterIdentity(config) +} + +func (r *AnonymousRole) IdentityIDs() ([]string, error) { + return r.localMembership.IDs() +} + +func (r *AnonymousRole) mapStringToID(v string) (driver.Identity, string, error) { defaultID := r.localMembership.DefaultNetworkIdentity() defaultIdentifier := r.localMembership.GetDefaultIdentifier() - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("[%s] mapping string identifier for [%s,%s], default identities [%s:%s]", + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("[%s] mapping string identifier for [%s,%s], default identities [%s:%s]", r.networkID, v, hash.Hashable(v).String(), @@ -91,38 +103,38 @@ func (r *Role) mapStringToID(v string) (driver.Identity, string, error) { viewIdentity := driver.Identity(label) switch { case len(label) == 0: - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed empty identity") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed empty identity") } return nil, defaultIdentifier, nil case label == defaultIdentifier: - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed default identifier") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed default identifier") } return nil, defaultIdentifier, nil case label == defaultID.UniqueID(): - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed default identity") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed default identity") } return nil, defaultIdentifier, nil case label == string(defaultID): - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed default identity as string") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed default identity as string") } return nil, defaultIdentifier, nil case defaultID.Equal(viewIdentity): - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed default identity as view identity") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed default identity as view identity") } return nil, defaultIdentifier, nil case r.nodeIdentity.Equal(viewIdentity): - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed node identity as view identity") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed node identity as view identity") } return nil, defaultIdentifier, nil case r.localMembership.IsMe(viewIdentity): - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed a local member") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed a local member") } return nil, defaultIdentifier, nil } @@ -130,18 +142,18 @@ func (r *Role) mapStringToID(v string) (driver.Identity, string, error) { if idIdentifier, err := r.localMembership.GetIdentifier(viewIdentity); err == nil { return nil, idIdentifier, nil } - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("cannot find match for string [%s]", v) + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("cannot find match for string [%s]", v) } return nil, label, nil } -func (r *Role) mapIdentityToID(v driver.Identity) (driver.Identity, string, error) { +func (r *AnonymousRole) mapIdentityToID(v driver.Identity) (driver.Identity, string, error) { defaultID := r.localMembership.DefaultNetworkIdentity() defaultIdentifier := r.localMembership.GetDefaultIdentifier() - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("[%s] mapping driver.Identity identifier for [%s], default identities [%s:%s]", + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("[%s] mapping driver.Identity identifier for [%s], default identities [%s:%s]", r.networkID, v, defaultID.String(), @@ -152,50 +164,41 @@ func (r *Role) mapIdentityToID(v driver.Identity) (driver.Identity, string, erro id := v switch { case id.IsNone(): - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed empty identity") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed empty identity") } return nil, defaultIdentifier, nil case id.Equal(defaultID): - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed default identity") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed default identity") } return nil, defaultIdentifier, nil case string(id) == defaultIdentifier: - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed 'idemix' identity") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed 'idemix' identity") } return nil, defaultIdentifier, nil case id.Equal(r.nodeIdentity): - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed identity is the node identity (same bytes)") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed identity is the node identity (same bytes)") } return nil, defaultIdentifier, nil case r.localMembership.IsMe(id): - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("passed identity is me") + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("passed identity is me") } return id, "", nil } label := string(id) - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("looking up identifier for identity as label [%s]", hash.Hashable(label)) + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("looking up identifier for identity as label [%s]", hash.Hashable(label)) } if idIdentifier, err := r.localMembership.GetIdentifier(id); err == nil { return nil, idIdentifier, nil } - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("cannot find match for driver.Identity string [%s]", id) + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("cannot find match for driver.Identity string [%s]", id) } return nil, string(id), nil } - -// RegisterIdentity registers the given identity -func (r *Role) RegisterIdentity(config driver.IdentityConfiguration) error { - return r.localMembership.RegisterIdentity(config) -} - -func (r *Role) IdentityIDs() ([]string, error) { - return r.localMembership.IDs() -} diff --git a/token/services/identity/common/identity.go b/token/services/identity/common/identity.go new file mode 100644 index 000000000..a669136f5 --- /dev/null +++ b/token/services/identity/common/identity.go @@ -0,0 +1,47 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package common + +import "github.com/hyperledger-labs/fabric-token-sdk/token/driver" + +// GetIdentityFunc is a function that returns an Identity and its associated audit info for the given options +type GetIdentityFunc func(auditInfo []byte) (driver.Identity, []byte, error) + +// LocalIdentity contains information about an identity +type LocalIdentity struct { + Name string + EnrollmentID string + Default bool + GetIdentity GetIdentityFunc + Remote bool +} + +// IdentityInfo implements the driver.IdentityInfo interface on top LocalIdentity +type IdentityInfo struct { + localIdentity *LocalIdentity + getIdentity func() (driver.Identity, []byte, error) +} + +func NewIdentityInfo(localIdentity *LocalIdentity, getIdentity func() (driver.Identity, []byte, error)) *IdentityInfo { + return &IdentityInfo{localIdentity: localIdentity, getIdentity: getIdentity} +} + +func (i *IdentityInfo) ID() string { + return i.localIdentity.Name +} + +func (i *IdentityInfo) EnrollmentID() string { + return i.localIdentity.EnrollmentID +} + +func (i *IdentityInfo) Get() (driver.Identity, []byte, error) { + return i.getIdentity() +} + +func (i *IdentityInfo) Remote() bool { + return i.localIdentity.Remote +} diff --git a/token/services/identity/common/lm.go b/token/services/identity/common/lm.go new file mode 100644 index 000000000..99d7f717e --- /dev/null +++ b/token/services/identity/common/lm.go @@ -0,0 +1,380 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package common + +import ( + "os" + "path/filepath" + "sync" + + "github.com/hyperledger-labs/fabric-smart-client/platform/common/utils/collections" + "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" + "github.com/hyperledger-labs/fabric-token-sdk/token/driver" + driver3 "github.com/hyperledger-labs/fabric-token-sdk/token/services/db/driver" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/config" + driver2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/driver" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging" + "github.com/pkg/errors" + "go.uber.org/zap/zapcore" + "gopkg.in/yaml.v2" +) + +type KeyManagerProvider interface { + Get(identityConfig *driver.IdentityConfiguration) (KeyManager, error) +} + +type KeyManager interface { + driver2.Deserializer + EnrollmentID() string + IsRemote() bool + Anonymous() bool + Identity([]byte) (driver.Identity, []byte, error) +} + +type LocalMembership struct { + config driver2.Config + defaultNetworkIdentity driver.Identity + signerService driver2.SigService + deserializerManager driver2.DeserializerManager + identityDB driver3.IdentityDB + binderService driver2.BinderService + KeyManagerProvider KeyManagerProvider + IdentityType string + logger logging.Logger + + localIdentitiesMutex sync.RWMutex + localIdentities []*LocalIdentity + localIdentitiesByName map[string]*LocalIdentity + localIdentitiesByEnrollmentID map[string]*LocalIdentity + localIdentitiesByIdentity map[string]*LocalIdentity +} + +func NewLocalMembership( + logger logging.Logger, + config driver2.Config, + defaultNetworkIdentity driver.Identity, + signerService driver2.SigService, + deserializerManager driver2.DeserializerManager, + identityDB driver3.IdentityDB, + binderService driver2.BinderService, + identityType string, + KeyManagerProvider KeyManagerProvider, +) *LocalMembership { + return &LocalMembership{ + logger: logger, + config: config, + defaultNetworkIdentity: defaultNetworkIdentity, + signerService: signerService, + deserializerManager: deserializerManager, + identityDB: identityDB, + localIdentitiesByEnrollmentID: map[string]*LocalIdentity{}, + localIdentitiesByName: map[string]*LocalIdentity{}, + localIdentitiesByIdentity: map[string]*LocalIdentity{}, + binderService: binderService, + IdentityType: identityType, + KeyManagerProvider: KeyManagerProvider, + } +} + +func (l *LocalMembership) DefaultNetworkIdentity() driver.Identity { + return l.defaultNetworkIdentity +} + +func (l *LocalMembership) IsMe(id driver.Identity) bool { + return l.signerService.IsMe(id) +} + +func (l *LocalMembership) GetIdentifier(id driver.Identity) (string, error) { + l.localIdentitiesMutex.RLock() + defer l.localIdentitiesMutex.RUnlock() + + for _, label := range []string{string(id), id.String()} { + if l.logger.IsEnabledFor(zapcore.DebugLevel) { + l.logger.Debugf("get local identity by label [%s]", label) + } + r := l.getLocalIdentity(label) + if r == nil { + if l.logger.IsEnabledFor(zapcore.DebugLevel) { + l.logger.Debugf("local identity not found for label [%s][%v]", collections.Keys(l.localIdentitiesByName)) + } + continue + } + return r.Name, nil + } + return "", errors.Errorf("identifier not found for id [%s]", id) +} + +func (l *LocalMembership) GetDefaultIdentifier() string { + l.localIdentitiesMutex.RLock() + defer l.localIdentitiesMutex.RUnlock() + + return l.getDefaultIdentifier() +} + +func (l *LocalMembership) GetIdentityInfo(label string, auditInfo []byte) (driver.IdentityInfo, error) { + l.localIdentitiesMutex.RLock() + defer l.localIdentitiesMutex.RUnlock() + + if l.logger.IsEnabledFor(zapcore.DebugLevel) { + l.logger.Debugf("get identity info by label [%s]", hash.Hashable(label)) + } + localIdentity := l.getLocalIdentity(label) + if localIdentity == nil { + return nil, errors.Errorf("local identity not found for label [%s][%v]", hash.Hashable(label), l.localIdentitiesByName) + } + return NewIdentityInfo(localIdentity, func() (driver.Identity, []byte, error) { + return localIdentity.GetIdentity(auditInfo) + }), nil +} + +func (l *LocalMembership) RegisterIdentity(idConfig driver.IdentityConfiguration) error { + l.localIdentitiesMutex.Lock() + defer l.localIdentitiesMutex.Unlock() + + return l.registerIdentityConfiguration(&idConfig, l.getDefaultIdentifier() == "") +} + +func (l *LocalMembership) IDs() ([]string, error) { + l.localIdentitiesMutex.RLock() + defer l.localIdentitiesMutex.RUnlock() + + var ids []string + for _, identity := range l.localIdentities { + ids = append(ids, identity.Name) + } + return ids, nil +} + +func (l *LocalMembership) Load(identities []*config.Identity) error { + l.localIdentitiesMutex.Lock() + defer l.localIdentitiesMutex.Unlock() + + l.logger.Debugf("load identities [%+q]", identities) + + // cleanup tables + l.localIdentities = make([]*LocalIdentity, 0) + l.localIdentitiesByName = make(map[string]*LocalIdentity) + l.localIdentitiesByEnrollmentID = make(map[string]*LocalIdentity) + + // load identities from configuration + for _, identityConfig := range identities { + l.logger.Debugf("load wallet for identity [%+v]", identityConfig) + if err := l.registerIdentity(*identityConfig); err != nil { + return errors.WithMessage(err, "failed to load identity") + } + l.logger.Debugf("load wallet for identity [%+v] done.", identityConfig) + } + + // load identities from storage + l.logger.Debugf("load identities from storage...") + if err := l.loadFromStorage(); err != nil { + return errors.Wrapf(err, "failed to load identities from identityDB") + } + l.logger.Debugf("load identities from storage...done") + + // if no default identity, use the first one + defaultIdentifier := l.getDefaultIdentifier() + if len(defaultIdentifier) == 0 { + l.logger.Warnf("no default identity, use the first one available") + if len(l.localIdentities) > 0 { + l.logger.Warnf("set default identity to %s", l.localIdentities[0].Name) + l.localIdentities[0].Default = true + } else { + l.logger.Warnf("cannot set default identity, no identity available") + } + } else { + l.logger.Debugf("default identifier is [%s]", defaultIdentifier) + } + + return nil +} + +func (l *LocalMembership) getDefaultIdentifier() string { + for _, identity := range l.localIdentities { + if identity.Default { + return identity.Name + } + } + return "" +} + +func (l *LocalMembership) registerIdentity(identity config.Identity) error { + // marshal opts + optsRaw, err := yaml.Marshal(identity.Opts) + if err != nil { + return errors.WithMessage(err, "failed to marshal identity options") + } + return l.registerIdentityConfiguration(&driver.IdentityConfiguration{ + ID: identity.ID, + URL: identity.Path, + Config: optsRaw, + Raw: nil, + }, identity.Default) +} + +func (l *LocalMembership) registerLocalIdentity(identityConfig *driver.IdentityConfiguration, defaultIdentity bool) error { + provider, err := l.KeyManagerProvider.Get(identityConfig) + if err != nil { + return errors.Wrapf(err, "failed to get identity provider for [%s]", identityConfig.ID) + } + + l.logger.Debugf("append local identity for [%s]", identityConfig.ID) + if err := l.addLocalIdentity(identityConfig, provider, defaultIdentity); err != nil { + return errors.Wrapf(err, "failed to add local identity for [%s]", identityConfig.ID) + } + + l.logger.Debugf("does the configuration already exists for [%s]?", identityConfig.ID) + if exists, _ := l.identityDB.ConfigurationExists(identityConfig.ID, l.IdentityType); !exists { + l.logger.Debugf("does the configuration already exists for [%s]? no, add it", identityConfig.ID) + if err := l.identityDB.AddConfiguration(driver3.IdentityConfiguration{ + ID: identityConfig.ID, + Type: l.IdentityType, + URL: identityConfig.URL, + Config: identityConfig.Config, + Raw: identityConfig.Raw, + }); err != nil { + return err + } + } + l.logger.Debugf("added local identity for id [%s], remote [%v]", identityConfig.ID+"@"+provider.EnrollmentID(), provider.IsRemote()) + return nil +} + +func (l *LocalMembership) registerIdentityConfiguration(identity *driver.IdentityConfiguration, defaultIdentity bool) error { + // Try to register the local identity + identity.URL = l.config.TranslatePath(identity.URL) + if err := l.registerLocalIdentity(identity, defaultIdentity); err != nil { + l.logger.Warnf("failed to load local identity at [%s]:[%s]", identity.URL, err) + // Does path correspond to a folder containing multiple identities? + if err := l.registerLocalIdentities(identity); err != nil { + return errors.WithMessage(err, "failed to register local identity") + } + } + return nil +} + +func (l *LocalMembership) registerLocalIdentities(configuration *driver.IdentityConfiguration) error { + entries, err := os.ReadDir(configuration.URL) + if err != nil { + l.logger.Warnf("failed reading from [%s]: [%s]", configuration.URL, err) + return nil + } + found := 0 + for _, entry := range entries { + if !entry.IsDir() { + continue + } + id := entry.Name() + if err := l.registerLocalIdentity(&driver.IdentityConfiguration{ + ID: id, + URL: filepath.Join(configuration.URL, id), + Config: configuration.Config, + }, false); err != nil { + l.logger.Errorf("failed registering local identity [%s]: [%s]", id, err) + continue + } + found++ + } + if found == 0 { + return errors.Errorf("no valid identities found in [%s]", configuration.URL) + } + return nil +} + +func (l *LocalMembership) addLocalIdentity(config *driver.IdentityConfiguration, keyManager KeyManager, defaultID bool) error { + eID := keyManager.EnrollmentID() + name := config.ID + localIdentity := &LocalIdentity{ + Name: name, + Default: defaultID, + EnrollmentID: eID, + GetIdentity: keyManager.Identity, + Remote: keyManager.IsRemote(), + } + l.localIdentitiesByName[name] = localIdentity + if len(eID) != 0 { + l.localIdentitiesByEnrollmentID[eID] = localIdentity + } + + l.logger.Debugf("adding identity mapping for [%s] by name and eID [%s]", name, eID) + + // deserializer + l.deserializerManager.AddDeserializer(keyManager) + + // if the keyManager is not anonymous + if !keyManager.Anonymous() { + identity, _, err := keyManager.Identity(nil) + if err != nil { + return errors.WithMessagef(err, "failed to get wallet identity from [%s]", name) + } + if l.logger.IsEnabledFor(zapcore.DebugLevel) { + l.logger.Debugf("adding identity mapping for [%s]", identity) + } + l.localIdentitiesByIdentity[identity.String()] = localIdentity + if l.binderService != nil { + if err := l.binderService.Bind(l.defaultNetworkIdentity, identity, false); err != nil { + return errors.WithMessagef(err, "cannot bind identity for [%s,%s]", identity, eID) + } + } + } + + l.localIdentities = append(l.localIdentities, localIdentity) + return nil +} + +func (l *LocalMembership) getLocalIdentity(label string) *LocalIdentity { + if l.logger.IsEnabledFor(zapcore.DebugLevel) { + l.logger.Debugf("get local identity by label [%s]", hash.Hashable(label)) + } + r, ok := l.localIdentitiesByName[label] + if ok { + return r + } + r, ok = l.localIdentitiesByIdentity[label] + if ok { + return r + } + + if l.logger.IsEnabledFor(zapcore.DebugLevel) { + l.logger.Debugf("local identity not found for label [%s][%v]", hash.Hashable(label), l.localIdentitiesByName) + } + return nil +} + +func (l *LocalMembership) loadFromStorage() error { + it, err := l.identityDB.IteratorConfigurations(l.IdentityType) + if err != nil { + return errors.WithMessage(err, "failed to get registered identities from kvs") + } + // copy the iterator + items := make([]driver3.IdentityConfiguration, 0) + for it.HasNext() { + item, err := it.Next() + if err != nil { + return err + } + items = append(items, item) + } + it.Close() + for _, entry := range items { + id := entry.ID + if l.getLocalIdentity(id) != nil { + l.logger.Debugf("from storage: id [%s] already exists", id) + continue + } + l.logger.Debugf("from storage: id [%s] does no exist, register it", id) + if err := l.registerIdentityConfiguration(&driver.IdentityConfiguration{ + ID: entry.ID, + URL: entry.URL, + Config: entry.Config, + Raw: entry.Raw, + }, l.getDefaultIdentifier() == ""); err != nil { + return err + } + } + return nil +} diff --git a/token/services/identity/msp/x509/role.go b/token/services/identity/common/ltrole.go similarity index 59% rename from token/services/identity/msp/x509/role.go rename to token/services/identity/common/ltrole.go index 915df900a..11cf2238e 100644 --- a/token/services/identity/msp/x509/role.go +++ b/token/services/identity/common/ltrole.go @@ -4,36 +4,29 @@ Copyright IBM Corp. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -package x509 +package common import ( "runtime/debug" "github.com/hyperledger-labs/fabric-token-sdk/token/driver" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging" "github.com/pkg/errors" "go.uber.org/zap/zapcore" ) -type localMembership interface { - DefaultNetworkIdentity() driver.Identity - IsMe(id driver.Identity) bool - GetIdentityInfo(label string, auditInfo []byte) (driver.IdentityInfo, error) - GetIdentifier(id driver.Identity) (string, error) - GetDefaultIdentifier() string - RegisterIdentity(config driver.IdentityConfiguration) error - IDs() ([]string, error) -} - -// Role is a container of x509-based long-term identities. -type Role struct { +// LongTermRole models a role whose identities are not anonymous +type LongTermRole struct { + logger logging.Logger roleID driver.IdentityRole networkID string nodeIdentity driver.Identity localMembership localMembership } -func NewRole(roleID driver.IdentityRole, networkID string, nodeIdentity driver.Identity, localMembership localMembership) *Role { - return &Role{ +func NewLongTermRole(logger logging.Logger, roleID driver.IdentityRole, networkID string, nodeIdentity driver.Identity, localMembership localMembership) *LongTermRole { + return &LongTermRole{ + logger: logger, roleID: roleID, networkID: networkID, nodeIdentity: nodeIdentity, @@ -41,14 +34,14 @@ func NewRole(roleID driver.IdentityRole, networkID string, nodeIdentity driver.I } } -func (r *Role) ID() driver.IdentityRole { +func (r *LongTermRole) ID() driver.IdentityRole { return r.roleID } // GetIdentityInfo returns the identity information for the given identity identifier -func (r *Role) GetIdentityInfo(id string) (driver.IdentityInfo, error) { - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("[%s] getting info for [%s]", r.networkID, id) +func (r *LongTermRole) GetIdentityInfo(id string) (driver.IdentityInfo, error) { + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("[%s] getting info for [%s]", r.networkID, id) } info, err := r.localMembership.GetIdentityInfo(id, nil) @@ -59,7 +52,7 @@ func (r *Role) GetIdentityInfo(id string) (driver.IdentityInfo, error) { } // MapToID returns the identity for the given argument -func (r *Role) MapToID(v driver.WalletLookupID) (driver.Identity, string, error) { +func (r *LongTermRole) MapToID(v driver.WalletLookupID) (driver.Identity, string, error) { switch vv := v.(type) { case driver.Identity: return r.mapIdentityToID(vv) @@ -72,12 +65,12 @@ func (r *Role) MapToID(v driver.WalletLookupID) (driver.Identity, string, error) } } -func (r *Role) mapStringToID(v string) (driver.Identity, string, error) { +func (r *LongTermRole) mapStringToID(v string) (driver.Identity, string, error) { defaultID := r.localMembership.DefaultNetworkIdentity() defaultIdentifier := r.localMembership.GetDefaultIdentifier() - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("[%s] mapping identifier for [%s,%s], default identities [%s:%s]", + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("[%s] mapping identifier for [%s,%s], default identities [%s:%s]", r.networkID, v, string(defaultID), @@ -87,8 +80,8 @@ func (r *Role) mapStringToID(v string) (driver.Identity, string, error) { } label := v - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("[LongTermIdentity] looking up identifier for label [%s]", label) + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("[LongTermIdentity] looking up identifier for label [%s]", label) } switch { case len(label) == 0: @@ -108,8 +101,8 @@ func (r *Role) mapStringToID(v string) (driver.Identity, string, error) { if idIdentifier, err := r.localMembership.GetIdentifier(id); err == nil { return id, idIdentifier, nil } - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("[LongTermIdentity] failed getting identity info for [%s], returning the identity", id) + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("[LongTermIdentity] failed getting identity info for [%s], returning the identity", id) } return id, "", nil } @@ -117,25 +110,25 @@ func (r *Role) mapStringToID(v string) (driver.Identity, string, error) { if info, err := r.localMembership.GetIdentityInfo(label, nil); err == nil { id, _, err := info.Get() if err != nil { - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("failed getting identity info for [%s], returning the identity", id) + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("failed getting identity info for [%s], returning the identity", id) } return nil, info.ID(), nil } return id, label, nil } - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("[LongTermIdentity] cannot find match for driver.Identity string [%s]", label) + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("[LongTermIdentity] cannot find match for driver.Identity string [%s]", label) } return nil, label, nil } -func (r *Role) mapIdentityToID(v driver.Identity) (driver.Identity, string, error) { +func (r *LongTermRole) mapIdentityToID(v driver.Identity) (driver.Identity, string, error) { defaultID := r.localMembership.DefaultNetworkIdentity() defaultIdentifier := r.localMembership.GetDefaultIdentifier() - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf( + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf( "[LongTermIdentity] looking up identifier for identity [%s], default identity [%s]", v, defaultID.String(), @@ -153,8 +146,8 @@ func (r *Role) mapIdentityToID(v driver.Identity) (driver.Identity, string, erro if idIdentifier, err := r.localMembership.GetIdentifier(id); err == nil { return id, idIdentifier, nil } - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("failed getting identity info for [%s], returning the identity", id) + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("failed getting identity info for [%s], returning the identity", id) } return id, "", nil case string(id) == defaultIdentifier: @@ -165,8 +158,8 @@ func (r *Role) mapIdentityToID(v driver.Identity) (driver.Identity, string, erro if info, err := r.localMembership.GetIdentityInfo(label, nil); err == nil { id, _, err := info.Get() if err != nil { - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("failed getting identity info for [%s], returning the identity", id) + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("failed getting identity info for [%s], returning the identity", id) } return nil, info.ID(), nil } @@ -175,24 +168,18 @@ func (r *Role) mapIdentityToID(v driver.Identity) (driver.Identity, string, erro if idIdentifier, err := r.localMembership.GetIdentifier(id); err == nil { return id, idIdentifier, nil } - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("[LongTermIdentity] cannot find match for driver.Identity string [%s]", v) + if r.logger.IsEnabledFor(zapcore.DebugLevel) { + r.logger.Debugf("[LongTermIdentity] cannot find match for driver.Identity string [%s]", v) } return id, "", nil } // RegisterIdentity registers the given identity -func (r *Role) RegisterIdentity(config driver.IdentityConfiguration) error { +func (r *LongTermRole) RegisterIdentity(config driver.IdentityConfiguration) error { return r.localMembership.RegisterIdentity(config) } -func (r *Role) IdentityIDs() ([]string, error) { +func (r *LongTermRole) IdentityIDs() ([]string, error) { return r.localMembership.IDs() } - -func (r *Role) Load(pp driver.PublicParameters) error { - logger.Debugf("reload x509 wallets...") - // nothing to do here - return nil -} diff --git a/token/services/identity/msp/common/common.go b/token/services/identity/driver/common.go similarity index 79% rename from token/services/identity/msp/common/common.go rename to token/services/identity/driver/common.go index 408f9aa01..4ff294bc8 100644 --- a/token/services/identity/msp/common/common.go +++ b/token/services/identity/driver/common.go @@ -4,21 +4,12 @@ Copyright IBM Corp. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -package common +package driver import ( "github.com/hyperledger-labs/fabric-token-sdk/token/driver" ) -// Resolver contains information about an identity and how to retrieve it. -type Resolver struct { - Name string `yaml:"name,omitempty"` - EnrollmentID string - Default bool - GetIdentity GetIdentityFunc - Remote bool -} - type SigService interface { IsMe(driver.Identity) bool RegisterSigner(identity driver.Identity, signer driver.Signer, verifier driver.Verifier, signerInfo []byte) error diff --git a/token/services/identity/msp/config/config.go b/token/services/identity/driver/config.go similarity index 97% rename from token/services/identity/msp/config/config.go rename to token/services/identity/driver/config.go index 92db9ce48..a301cef82 100644 --- a/token/services/identity/msp/config/config.go +++ b/token/services/identity/driver/config.go @@ -4,7 +4,7 @@ Copyright IBM Corp. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -package config +package driver import ( "github.com/hyperledger-labs/fabric-token-sdk/token/driver" diff --git a/token/services/identity/msp/common/identity.go b/token/services/identity/msp/common/identity.go deleted file mode 100644 index d911c57c6..000000000 --- a/token/services/identity/msp/common/identity.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package common - -import "github.com/hyperledger-labs/fabric-token-sdk/token/driver" - -type IdentityOptions struct { - EIDExtension bool - AuditInfo []byte -} - -// GetIdentityFunc is a function that returns an Identity and its associated audit info for the given options -type GetIdentityFunc func(opts *IdentityOptions) (driver.Identity, []byte, error) - -// IdentityInfo implements the driver.IdentityInfo interface. -type IdentityInfo struct { - id string - eid string - getIdentity func() (driver.Identity, []byte, error) - remote bool -} - -func NewIdentityInfo(id string, eid string, remote bool, getIdentity func() (driver.Identity, []byte, error)) *IdentityInfo { - return &IdentityInfo{id: id, eid: eid, remote: remote, getIdentity: getIdentity} -} - -func (i *IdentityInfo) ID() string { - return i.id -} - -func (i *IdentityInfo) EnrollmentID() string { - return i.eid -} - -func (i *IdentityInfo) Get() (driver.Identity, []byte, error) { - return i.getIdentity() -} - -func (i *IdentityInfo) Remote() bool { - return i.remote -} diff --git a/token/services/identity/msp/idemix/cache/cache.go b/token/services/identity/msp/idemix/cache/cache.go index 774f4fd76..3f81d3b7a 100644 --- a/token/services/identity/msp/idemix/cache/cache.go +++ b/token/services/identity/msp/idemix/cache/cache.go @@ -12,14 +12,13 @@ import ( "time" "github.com/hyperledger-labs/fabric-token-sdk/token/driver" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/common" "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging" "go.uber.org/zap/zapcore" ) var logger = logging.MustGetLogger("token-sdk.services.identity.msp.idemix") -type IdentityCacheBackendFunc func(opts *common.IdentityOptions) (driver.Identity, []byte, error) +type IdentityCacheBackendFunc func(auditInfo []byte) (driver.Identity, []byte, error) type identityCacheEntry struct { Identity driver.Identity @@ -27,29 +26,27 @@ type identityCacheEntry struct { } type IdentityCache struct { - once sync.Once - backed IdentityCacheBackendFunc - cache chan identityCacheEntry - opts *common.IdentityOptions + once sync.Once + backed IdentityCacheBackendFunc + auditInfo []byte + cache chan identityCacheEntry } -func NewIdentityCache(backed IdentityCacheBackendFunc, size int, opts *common.IdentityOptions) *IdentityCache { +func NewIdentityCache(backed IdentityCacheBackendFunc, size int, auditInfo []byte) *IdentityCache { logger.Debugf("new identity cache with size [%d]", size) ci := &IdentityCache{ - backed: backed, - cache: make(chan identityCacheEntry, size), - opts: opts, + backed: backed, + cache: make(chan identityCacheEntry, size), + auditInfo: auditInfo, } return ci } -func (c *IdentityCache) Identity(opts *common.IdentityOptions) (driver.Identity, []byte, error) { - if opts != nil { - // are the opts equal to the cache opts, if yes, use the cache - if c.opts != nil && (opts.EIDExtension != c.opts.EIDExtension || !bytes.Equal(opts.AuditInfo, c.opts.AuditInfo)) { - return c.fetchIdentityFromBackend(opts) - } +func (c *IdentityCache) Identity(auditInfo []byte) (driver.Identity, []byte, error) { + // Is the auditInfo equal to that used to fill the cache? If yes, use the cache + if !bytes.Equal(auditInfo, c.auditInfo) { + return c.fetchIdentityFromBackend(auditInfo) } c.once.Do(func() { @@ -88,7 +85,7 @@ func (c *IdentityCache) fetchIdentityFromCache() (driver.Identity, []byte, error logger.Debugf("fetching identity from cache [%s][%d] took [%v]", identity, len(audit), time.Since(start)) } case <-timeout.C: - id, a, err := c.backed(c.opts) + id, a, err := c.backed(c.auditInfo) if err != nil { return nil, nil, err } @@ -102,11 +99,11 @@ func (c *IdentityCache) fetchIdentityFromCache() (driver.Identity, []byte, error return identity, audit, nil } -func (c *IdentityCache) fetchIdentityFromBackend(opts *common.IdentityOptions) (driver.Identity, []byte, error) { +func (c *IdentityCache) fetchIdentityFromBackend(auditInfo []byte) (driver.Identity, []byte, error) { if logger.IsEnabledFor(zapcore.DebugLevel) { logger.Debugf("fetching identity from backend") } - id, audit, err := c.backed(opts) + id, audit, err := c.backed(auditInfo) if err != nil { return nil, nil, err } @@ -120,7 +117,7 @@ func (c *IdentityCache) fetchIdentityFromBackend(opts *common.IdentityOptions) ( func (c *IdentityCache) provisionIdentities() { count := 0 for { - id, audit, err := c.backed(c.opts) + id, audit, err := c.backed(c.auditInfo) if err != nil { logger.Errorf("failed to provision identity [%s]", err) continue diff --git a/token/services/identity/msp/idemix/cache/cache_test.go b/token/services/identity/msp/idemix/cache/cache_test.go index 542442e20..2689e16c1 100644 --- a/token/services/identity/msp/idemix/cache/cache_test.go +++ b/token/services/identity/msp/idemix/cache/cache_test.go @@ -10,18 +10,14 @@ import ( "testing" "github.com/hyperledger-labs/fabric-token-sdk/token/driver" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/common" "github.com/stretchr/testify/assert" ) func TestIdentityCache(t *testing.T) { - c := NewIdentityCache(func(opts *common.IdentityOptions) (driver.Identity, []byte, error) { + c := NewIdentityCache(func([]byte) (driver.Identity, []byte, error) { return []byte("hello world"), []byte("audit"), nil }, 100, nil) - id, audit, err := c.Identity(&common.IdentityOptions{ - EIDExtension: true, - AuditInfo: nil, - }) + id, audit, err := c.Identity(nil) assert.NoError(t, err) assert.Equal(t, driver.Identity([]byte("hello world")), id) assert.Equal(t, []byte("audit"), audit) diff --git a/token/services/identity/msp/idemix/provider.go b/token/services/identity/msp/idemix/km.go similarity index 89% rename from token/services/identity/msp/idemix/provider.go rename to token/services/identity/msp/idemix/km.go index 34d026d6f..1582a4335 100644 --- a/token/services/identity/msp/idemix/provider.go +++ b/token/services/identity/msp/idemix/km.go @@ -16,7 +16,6 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/pkg/utils/proto" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" "github.com/hyperledger-labs/fabric-token-sdk/token/driver" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/common" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/idemix/msp" m "github.com/hyperledger/fabric-protos-go/msp" "github.com/pkg/errors" @@ -31,7 +30,7 @@ type SignerService interface { RegisterSigner(identity driver.Identity, signer driver.Signer, verifier driver.Verifier, info []byte) error } -type Provider struct { +type KeyManager struct { *msp.Deserializer userKey bccsp.Key conf idemixmsp.IdemixMSPConfig @@ -41,7 +40,7 @@ type Provider struct { verType bccsp.VerificationType } -func NewProvider(conf1 *m.MSPConfig, signerService SignerService, sigType bccsp.SignatureType, cryptoProvider bccsp.BCCSP) (*Provider, error) { +func NewKeyManager(conf1 *m.MSPConfig, signerService SignerService, sigType bccsp.SignatureType, cryptoProvider bccsp.BCCSP) (*KeyManager, error) { logger.Debugf("Setting up Idemix-based MSP instance") if conf1 == nil { @@ -87,7 +86,7 @@ func NewProvider(conf1 *m.MSPConfig, signerService SignerService, sigType bccsp. } if conf.Signer == nil { - // No credential in config, so we don't setup a default signer + // No credential in config, so we don't set up a default signer return nil, errors.Errorf("no signer information found") } @@ -147,7 +146,7 @@ func NewProvider(conf1 *m.MSPConfig, signerService SignerService, sigType bccsp. sigType = bccsp.Standard } - return &Provider{ + return &KeyManager{ Deserializer: &msp.Deserializer{ Name: conf.Name, Csp: cryptoProvider, @@ -164,7 +163,7 @@ func NewProvider(conf1 *m.MSPConfig, signerService SignerService, sigType bccsp. }, nil } -func (p *Provider) Identity(opts *common.IdentityOptions) (driver.Identity, []byte, error) { +func (p *KeyManager) Identity(auditInfo []byte) (driver.Identity, []byte, error) { // Derive NymPublicKey nymKey, err := p.Csp.KeyDeriv( p.userKey, @@ -199,20 +198,15 @@ func (p *Provider) Identity(opts *common.IdentityOptions) (driver.Identity, []by rh := p.conf.Signer.RevocationHandle sigType := p.sigType var signerMetadata *bccsp.IdemixSignerMetadata - if opts != nil { - if opts.EIDExtension { - sigType = bccsp.EidNymRhNym + if len(auditInfo) != 0 { + ai, err := p.DeserializeAuditInfo(auditInfo) + if err != nil { + return nil, nil, err } - if len(opts.AuditInfo) != 0 { - ai, err := p.DeserializeAuditInfo(opts.AuditInfo) - if err != nil { - return nil, nil, err - } - - signerMetadata = &bccsp.IdemixSignerMetadata{ - EidNymAuditData: ai.EidNymAuditData, - RhNymAuditData: ai.RhNymAuditData, - } + + signerMetadata = &bccsp.IdemixSignerMetadata{ + EidNymAuditData: ai.EidNymAuditData, + RhNymAuditData: ai.RhNymAuditData, } } @@ -295,11 +289,11 @@ func (p *Provider) Identity(opts *common.IdentityOptions) (driver.Identity, []by return raw, infoRaw, nil } -func (p *Provider) IsRemote() bool { +func (p *KeyManager) IsRemote() bool { return p.userKey == nil } -func (p *Provider) DeserializeVerifier(raw []byte) (driver.Verifier, error) { +func (p *KeyManager) DeserializeVerifier(raw []byte) (driver.Verifier, error) { r, err := p.Deserialize(raw, true) if err != nil { return nil, err @@ -308,7 +302,7 @@ func (p *Provider) DeserializeVerifier(raw []byte) (driver.Verifier, error) { return r.Identity, nil } -func (p *Provider) DeserializeSigner(raw []byte) (driver.Signer, error) { +func (p *KeyManager) DeserializeSigner(raw []byte) (driver.Signer, error) { r, err := p.Deserialize(raw, true) if err != nil { return nil, err @@ -337,7 +331,7 @@ func (p *Provider) DeserializeSigner(raw []byte) (driver.Signer, error) { return si, nil } -func (p *Provider) Info(raw []byte, auditInfo []byte) (string, error) { +func (p *KeyManager) Info(raw []byte, auditInfo []byte) (string, error) { r, err := p.Deserialize(raw, true) if err != nil { return "", err @@ -361,15 +355,19 @@ func (p *Provider) Info(raw []byte, auditInfo []byte) (string, error) { return fmt.Sprintf("MSP.Idemix: [%s][%s][%s][%s][%s]", eid, driver.Identity(raw).UniqueID(), r.SerializedIdentity.Mspid, r.OU.OrganizationalUnitIdentifier, r.Role.Role.String()), nil } -func (p *Provider) String() string { - return fmt.Sprintf("Idemix Provider [%s]", hash.Hashable(p.Ipk).String()) +func (p *KeyManager) String() string { + return fmt.Sprintf("Idemix KeyManager [%s]", hash.Hashable(p.Ipk).String()) } -func (p *Provider) EnrollmentID() string { +func (p *KeyManager) EnrollmentID() string { return p.conf.Signer.EnrollmentId } -func (p *Provider) DeserializeSigningIdentity(raw []byte) (driver.SigningIdentity, error) { +func (p *KeyManager) Anonymous() bool { + return true +} + +func (p *KeyManager) DeserializeSigningIdentity(raw []byte) (driver.SigningIdentity, error) { si := &m.SerializedIdentity{} err := proto.Unmarshal(raw, si) if err != nil { diff --git a/token/services/identity/msp/idemix/provider_test.go b/token/services/identity/msp/idemix/km_test.go similarity index 90% rename from token/services/identity/msp/idemix/provider_test.go rename to token/services/identity/msp/idemix/km_test.go index f491835d8..f7da62179 100644 --- a/token/services/identity/msp/idemix/provider_test.go +++ b/token/services/identity/msp/idemix/km_test.go @@ -11,27 +11,25 @@ import ( "strings" "testing" - mem "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver/memory" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/idemix/msp" - idemix2 "github.com/IBM/idemix" "github.com/IBM/idemix/bccsp/types" bccsp "github.com/IBM/idemix/bccsp/types" math "github.com/IBM/mathlib" _ "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver/memory" + mem "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver/memory" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs/mock" registry2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/registry" "github.com/hyperledger-labs/fabric-token-sdk/token" kvs2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/kvs" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/common" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/idemix" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/idemix/msp" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/sig" msp2 "github.com/hyperledger/fabric/msp" "github.com/stretchr/testify/assert" ) -func TestProvider(t *testing.T) { +func TestKeyManager(t *testing.T) { backend, err := kvs.NewWithConfig(&mem.Driver{}, "", &mock.ConfigProvider{}) assert.NoError(t, err) sigService := sig.NewService(sig.NewMultiplexDeserializer(), kvs2.NewIdentityDB(backend, token.TMSID{Network: "pineapple"})) @@ -43,17 +41,21 @@ func TestProvider(t *testing.T) { assert.NoError(t, err) cryptoProvider, err := msp.NewBCCSP(keyStore, math.FP256BN_AMCL, false) assert.NoError(t, err) - p, err := idemix.NewProvider(config, sigService, types.EidNymRhNym, cryptoProvider) + + p, err := idemix.NewKeyManager(config, sigService, types.EidNymRhNym, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) + assert.True(t, p.Anonymous()) - p, err = idemix.NewProvider(config, sigService, bccsp.Standard, cryptoProvider) + p, err = idemix.NewKeyManager(config, sigService, bccsp.Standard, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) + assert.True(t, p.Anonymous()) - p, err = idemix.NewProvider(config, sigService, bccsp.EidNymRhNym, cryptoProvider) + p, err = idemix.NewKeyManager(config, sigService, bccsp.EidNymRhNym, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) + assert.True(t, p.Anonymous()) } func TestIdentityWithEidRhNymPolicy(t *testing.T) { @@ -72,7 +74,7 @@ func TestIdentityWithEidRhNymPolicy(t *testing.T) { assert.NoError(t, err) cryptoProvider, err := msp.NewBCCSP(keyStore, math.FP256BN_AMCL, false) assert.NoError(t, err) - p, err := idemix.NewProvider(config, sigService, types.EidNymRhNym, cryptoProvider) + p, err := idemix.NewKeyManager(config, sigService, types.EidNymRhNym, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) @@ -102,11 +104,11 @@ func TestIdentityWithEidRhNymPolicy(t *testing.T) { assert.NoError(t, err) cryptoProvider, err = msp.NewBCCSP(keyStore, math.FP256BN_AMCL, false) assert.NoError(t, err) - p, err = idemix.NewProvider(config, sigService, idemix.Any, cryptoProvider) + p, err = idemix.NewKeyManager(config, sigService, types.EidNymRhNym, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) - id, audit, err = p.Identity(&common.IdentityOptions{EIDExtension: true}) + id, audit, err = p.Identity(nil) assert.NoError(t, err) assert.NotNil(t, id) assert.NotNil(t, audit) @@ -145,7 +147,7 @@ func TestIdentityStandard(t *testing.T) { assert.NoError(t, err) cryptoProvider, err := msp.NewBCCSP(keyStore, math.FP256BN_AMCL, false) assert.NoError(t, err) - p, err := idemix.NewProvider(config, sigService, bccsp.Standard, cryptoProvider) + p, err := idemix.NewKeyManager(config, sigService, bccsp.Standard, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) @@ -167,7 +169,7 @@ func TestIdentityStandard(t *testing.T) { assert.NoError(t, err) cryptoProvider, err = msp.NewBCCSP(keyStore, math.FP256BN_AMCL, false) assert.NoError(t, err) - p, err = idemix.NewProvider(config, sigService, bccsp.Standard, cryptoProvider) + p, err = idemix.NewKeyManager(config, sigService, bccsp.Standard, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) @@ -189,7 +191,7 @@ func TestIdentityStandard(t *testing.T) { assert.NoError(t, err) cryptoProvider, err = msp.NewBCCSP(keyStore, math.FP256BN_AMCL, false) assert.NoError(t, err) - p, err = idemix.NewProvider(config, sigService, idemix.Any, cryptoProvider) + p, err = idemix.NewKeyManager(config, sigService, idemix.Any, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) @@ -223,7 +225,7 @@ func TestAuditWithEidRhNymPolicy(t *testing.T) { assert.NoError(t, err) cryptoProvider, err := msp.NewBCCSP(keyStore, math.FP256BN_AMCL, false) assert.NoError(t, err) - p, err := idemix.NewProvider(config, sigService, types.EidNymRhNym, cryptoProvider) + p, err := idemix.NewKeyManager(config, sigService, types.EidNymRhNym, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) @@ -233,7 +235,7 @@ func TestAuditWithEidRhNymPolicy(t *testing.T) { assert.NoError(t, err) cryptoProvider, err = msp.NewBCCSP(keyStore, math.FP256BN_AMCL, false) assert.NoError(t, err) - p2, err := idemix.NewProvider(config, sigService, types.EidNymRhNym, cryptoProvider) + p2, err := idemix.NewKeyManager(config, sigService, types.EidNymRhNym, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p2) @@ -258,7 +260,7 @@ func TestAuditWithEidRhNymPolicy(t *testing.T) { assert.Error(t, auditInfo.Match(id)) } -func TestProvider_DeserializeSigner(t *testing.T) { +func TestKeyManager_DeserializeSigner(t *testing.T) { registry := registry2.New() backend, err := kvs.NewWithConfig(&mem.Driver{}, "", &mock.ConfigProvider{}) @@ -273,13 +275,13 @@ func TestProvider_DeserializeSigner(t *testing.T) { assert.NoError(t, err) cryptoProvider, err := msp.NewBCCSP(keyStore, math.FP256BN_AMCL, false) assert.NoError(t, err) - p, err := idemix.NewProvider(config, sigService, types.EidNymRhNym, cryptoProvider) + p, err := idemix.NewKeyManager(config, sigService, types.EidNymRhNym, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) config, err = msp2.GetLocalMspConfigWithType("./testdata/sameissuer/idemix2", nil, "idemix", "idemix") assert.NoError(t, err) - p2, err := idemix.NewProvider(config, sigService, types.EidNymRhNym, cryptoProvider) + p2, err := idemix.NewKeyManager(config, sigService, types.EidNymRhNym, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p2) @@ -336,7 +338,7 @@ func TestIdentityFromFabricCA(t *testing.T) { assert.NoError(t, err) cryptoProvider, err := msp.NewBCCSP(keyStore, math.BN254, false) assert.NoError(t, err) - p, err := idemix.NewProvider(config, sigService, bccsp.Standard, cryptoProvider) + p, err := idemix.NewKeyManager(config, sigService, bccsp.Standard, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) @@ -358,7 +360,7 @@ func TestIdentityFromFabricCA(t *testing.T) { assert.NoError(t, err) cryptoProvider, err = msp.NewBCCSP(keyStore, math.BN254, false) assert.NoError(t, err) - p, err = idemix.NewProvider(config, sigService, bccsp.Standard, cryptoProvider) + p, err = idemix.NewKeyManager(config, sigService, bccsp.Standard, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) @@ -380,7 +382,7 @@ func TestIdentityFromFabricCA(t *testing.T) { assert.NoError(t, err) cryptoProvider, err = msp.NewBCCSP(keyStore, math.BN254, false) assert.NoError(t, err) - p, err = idemix.NewProvider(config, sigService, idemix.Any, cryptoProvider) + p, err = idemix.NewKeyManager(config, sigService, idemix.Any, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) @@ -417,7 +419,7 @@ func TestIdentityFromFabricCAWithEidRhNymPolicy(t *testing.T) { assert.NoError(t, err) cryptoProvider, err := msp.NewBCCSP(keyStore, math.BN254, false) assert.NoError(t, err) - p, err := idemix.NewProvider(config, sigService, bccsp.EidNymRhNym, cryptoProvider) + p, err := idemix.NewKeyManager(config, sigService, bccsp.EidNymRhNym, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) @@ -449,11 +451,11 @@ func TestIdentityFromFabricCAWithEidRhNymPolicy(t *testing.T) { assert.NoError(t, err) cryptoProvider, err = msp.NewBCCSP(keyStore, math.BN254, false) assert.NoError(t, err) - p, err = idemix.NewProvider(config, sigService, idemix.Any, cryptoProvider) + p, err = idemix.NewKeyManager(config, sigService, types.EidNymRhNym, cryptoProvider) assert.NoError(t, err) assert.NotNil(t, p) - id, audit, err = p.Identity(&common.IdentityOptions{EIDExtension: true}) + id, audit, err = p.Identity(nil) assert.NoError(t, err) assert.NotNil(t, id) assert.NotNil(t, audit) diff --git a/token/services/identity/msp/idemix/kmp.go b/token/services/identity/msp/idemix/kmp.go new file mode 100644 index 000000000..22e1ef1f8 --- /dev/null +++ b/token/services/identity/msp/idemix/kmp.go @@ -0,0 +1,108 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package idemix + +import ( + bccsp "github.com/IBM/idemix/bccsp/types" + math "github.com/IBM/mathlib" + "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" + "github.com/hyperledger-labs/fabric-token-sdk/token/driver" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/common" + driver2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/driver" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/idemix/cache" + msp2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/idemix/msp" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging" + "github.com/hyperledger/fabric-protos-go/msp" + "github.com/pkg/errors" +) + +var logger = logging.MustGetLogger("token-sdk.services.identity.msp.idemix") + +type KeyManagerProvider struct { + issuerPublicKey []byte + curveID math.CurveID + mspID string + keyStore bccsp.KeyStore + signerService SignerService + config driver2.Config + cacheSize int + + // ignoreVerifyOnlyWallet when set to true, for each wallet the service will force the load of the secrets + ignoreVerifyOnlyWallet bool +} + +func NewKeyManagerProvider(issuerPublicKey []byte, curveID math.CurveID, mspID string, keyStore bccsp.KeyStore, signerService SignerService, config driver2.Config, cacheSize int, ignoreVerifyOnlyWallet bool) *KeyManagerProvider { + return &KeyManagerProvider{issuerPublicKey: issuerPublicKey, curveID: curveID, mspID: mspID, keyStore: keyStore, signerService: signerService, config: config, cacheSize: cacheSize, ignoreVerifyOnlyWallet: ignoreVerifyOnlyWallet} +} + +func (l *KeyManagerProvider) Get(identityConfig *driver.IdentityConfiguration) (common.KeyManager, error) { + var conf *msp.MSPConfig + var err error + if len(identityConfig.Raw) != 0 { + // load the msp config directly from identityConfig.Raw + logger.Infof("load the msp config directly from identityConfig.Raw [%s]", hash.Hashable(identityConfig.Raw)) + conf, err = msp2.NewMSPConfigFromRawSigner(l.issuerPublicKey, identityConfig.Raw, l.mspID) + } else { + // load from URL + logger.Infof("load the msp config form identityConfig.URL [%s]", identityConfig.URL) + conf, err = msp2.NewMSPConfigFromURL(l.issuerPublicKey, identityConfig.URL, l.mspID, l.ignoreVerifyOnlyWallet) + } + if err != nil { + return nil, err + } + + // instantiate provider from configuration + cryptoProvider, err := msp2.NewBCCSP(l.keyStore, l.curveID, l.curveID == math.BLS12_381_BBS) + if err != nil { + return nil, errors.WithMessage(err, "failed to instantiate crypto provider") + } + provider, err := NewKeyManager(conf, l.signerService, bccsp.EidNymRhNym, cryptoProvider) + if err != nil { + return nil, errors.Wrapf(err, "failed instantiating idemix msp provider from [%s]", identityConfig.URL) + } + + cacheSize, err := l.cacheSizeForID(identityConfig.ID) + if err != nil { + return nil, err + } + + var getIdentityFunc func([]byte) (driver.Identity, []byte, error) + if provider.IsRemote() { + getIdentityFunc = func([]byte) (driver.Identity, []byte, error) { + return nil, nil, errors.Errorf("cannot invoke this function, remote must register pseudonyms") + } + } else { + getIdentityFunc = cache.NewIdentityCache( + provider.Identity, + cacheSize, + nil, + ).Identity + } + + return &WrappedKeyManager{ + KeyManager: provider, + getIdentityFunc: getIdentityFunc, + }, nil +} + +func (l *KeyManagerProvider) cacheSizeForID(id string) (int, error) { + cacheSize := l.config.CacheSizeForOwnerID(id) + if cacheSize <= 0 { + logger.Debugf("cache size for %s not configured, using default (%d)", id, l.cacheSize) + cacheSize = l.cacheSize + } + return cacheSize, nil +} + +type WrappedKeyManager struct { + common.KeyManager + getIdentityFunc func([]byte) (driver.Identity, []byte, error) +} + +func (k *WrappedKeyManager) Identity(auditInfo []byte) (driver.Identity, []byte, error) { + return k.getIdentityFunc(auditInfo) +} diff --git a/token/services/identity/msp/idemix/lm.go b/token/services/identity/msp/idemix/lm.go deleted file mode 100644 index fc8ba7198..000000000 --- a/token/services/identity/msp/idemix/lm.go +++ /dev/null @@ -1,393 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package idemix - -import ( - "os" - "path/filepath" - "sync" - - bccsp "github.com/IBM/idemix/bccsp/types" - math "github.com/IBM/mathlib" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" - "github.com/hyperledger-labs/fabric-token-sdk/token/driver" - driver3 "github.com/hyperledger-labs/fabric-token-sdk/token/services/db/driver" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/config" - driver2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/driver" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/common" - config2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/config" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/idemix/cache" - msp2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/idemix/msp" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging" - "github.com/hyperledger/fabric-protos-go/msp" - "github.com/pkg/errors" - "go.uber.org/zap/zapcore" -) - -var logger = logging.MustGetLogger("token-sdk.services.identity.msp.idemix") - -type LocalMembership struct { - issuerPublicKey []byte - curveID math.CurveID - - config config2.Config - defaultNetworkIdentity driver.Identity - signerService common.SigService - deserializerManager driver2.DeserializerManager - identityDB driver3.IdentityDB - keyStore bccsp.KeyStore - mspID string - cacheSize int - - resolversMutex sync.RWMutex - resolvers []*common.Resolver - resolversByName map[string]*common.Resolver - resolversByEnrollmentID map[string]*common.Resolver - identities []*config.Identity - // ignoreVerifyOnlyWallet when set to true, for each wallet the service will force the load of the secrets - ignoreVerifyOnlyWallet bool -} - -func NewLocalMembership( - issuerPublicKey []byte, - idemixCurveID math.CurveID, - config config2.Config, - defaultNetworkIdentity driver.Identity, - signerService common.SigService, - deserializerManager driver2.DeserializerManager, - identityDB driver3.IdentityDB, - keyStore bccsp.KeyStore, - mspID string, - cacheSize int, - identities []*config.Identity, - ignoreVerifyOnlyWallet bool, -) *LocalMembership { - return &LocalMembership{ - issuerPublicKey: issuerPublicKey, - curveID: idemixCurveID, - config: config, - defaultNetworkIdentity: defaultNetworkIdentity, - signerService: signerService, - deserializerManager: deserializerManager, - identityDB: identityDB, - keyStore: keyStore, - mspID: mspID, - cacheSize: cacheSize, - resolversByEnrollmentID: map[string]*common.Resolver{}, - resolversByName: map[string]*common.Resolver{}, - identities: identities, - ignoreVerifyOnlyWallet: ignoreVerifyOnlyWallet, - } -} - -func (l *LocalMembership) DefaultNetworkIdentity() driver.Identity { - return l.defaultNetworkIdentity -} - -func (l *LocalMembership) IsMe(id driver.Identity) bool { - return l.signerService.IsMe(id) -} - -func (l *LocalMembership) GetIdentifier(id driver.Identity) (string, error) { - l.resolversMutex.RLock() - defer l.resolversMutex.RUnlock() - - label := string(id) - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("get anonymous identity info by label [%s]", hash.Hashable(label)) - } - r := l.getResolver(label) - if r == nil { - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("anonymous identity info not found for label [%s][%v]", hash.Hashable(label), l.resolversByName) - } - return "", errors.New("not found") - } - return r.Name, nil -} - -func (l *LocalMembership) GetDefaultIdentifier() string { - for _, resolver := range l.resolvers { - if resolver.Default { - return resolver.Name - } - } - return "" -} - -func (l *LocalMembership) GetIdentityInfo(label string, auditInfo []byte) (driver.IdentityInfo, error) { - l.resolversMutex.RLock() - defer l.resolversMutex.RUnlock() - - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("get anonymous identity info by label [%s]", hash.Hashable(label)) - } - r := l.getResolver(label) - if r == nil { - return nil, errors.Errorf("anonymous identity info not found for label [%s][%v]", hash.Hashable(label), l.resolversByName) - } - - return common.NewIdentityInfo( - r.Name, - r.EnrollmentID, - r.Remote, - func() (driver.Identity, []byte, error) { - return r.GetIdentity(&common.IdentityOptions{ - EIDExtension: true, - AuditInfo: auditInfo, - }) - }, - ), nil -} - -func (l *LocalMembership) RegisterIdentity(idConfig driver.IdentityConfiguration) error { - l.resolversMutex.Lock() - defer l.resolversMutex.Unlock() - - return l.registerIdentityConfiguration(idConfig, l.GetDefaultIdentifier() == "") -} - -func (l *LocalMembership) IDs() ([]string, error) { - var ids []string - for _, resolver := range l.resolvers { - ids = append(ids, resolver.Name) - } - return ids, nil -} - -func (l *LocalMembership) Load() error { - logger.Debugf("Load Idemix Wallets with the respect to curve [%d], [%+q]", l.curveID, l.identities) - - l.resolversMutex.Lock() - defer l.resolversMutex.Unlock() - - // cleanup all resolvers - l.resolvers = make([]*common.Resolver, 0) - l.resolversByName = make(map[string]*common.Resolver) - l.resolversByEnrollmentID = make(map[string]*common.Resolver) - - // load identities from configuration - for _, identityConfig := range l.identities { - logger.Debugf("load wallet for identity [%+v]", identityConfig) - if err := l.registerIdentity(*identityConfig); err != nil { - return errors.WithMessage(err, "failed to load identity") - } - logger.Debugf("load wallet for identity [%+v] done.", identityConfig) - } - - // load identities from storage - logger.Debugf("load identities from storage...") - if err := l.loadFromStorage(); err != nil { - return errors.Wrapf(err, "failed to load identities from identityDB") - } - logger.Debugf("load identities from storage...done") - - // if no default identity, use the first one - defaultIdentifier := l.GetDefaultIdentifier() - if len(defaultIdentifier) == 0 { - logger.Warnf("no default identity, use the first one available") - if len(l.resolvers) > 0 { - logger.Warnf("set default identity to %s", l.resolvers[0].Name) - l.resolvers[0].Default = true - } else { - logger.Warnf("cannot set default identity, no identity available") - } - } else { - logger.Debugf("default identifier is [%s]", defaultIdentifier) - } - - return nil -} - -func (l *LocalMembership) registerIdentity(identity config.Identity) error { - return l.registerIdentityConfiguration(driver.IdentityConfiguration{ - ID: identity.ID, - URL: identity.Path, - Config: nil, - Raw: nil, - }, identity.Default) -} - -func (l *LocalMembership) registerIdentityConfiguration(identity driver.IdentityConfiguration, defaultIdentity bool) error { - // Try to register the MSP provider - identity.URL = l.config.TranslatePath(identity.URL) - if err := l.registerProvider(identity, defaultIdentity); err != nil { - logger.Warnf("failed to load idemix msp provider at [%s]:[%s]", identity.URL, err) - // Does path correspond to a holder containing multiple MSP identities? - if err := l.registerProviders(identity); err != nil { - return errors.WithMessage(err, "failed to register MSP provider") - } - } - return nil -} - -func (l *LocalMembership) registerProvider(identityConfig driver.IdentityConfiguration, defaultIdentity bool) error { - var conf *msp.MSPConfig - var err error - if len(identityConfig.Raw) != 0 { - // load the msp config directly from identityConfig.Raw - logger.Infof("load the msp config directly from identityConfig.Raw [%s]", hash.Hashable(identityConfig.Raw)) - conf, err = msp2.NewMSPConfigFromRawSigner(l.issuerPublicKey, identityConfig.Raw, l.mspID) - } else { - // load from URL - logger.Infof("load the msp config form identityConfig.URL [%s]", identityConfig.URL) - conf, err = msp2.NewMSPConfigFromURL(l.issuerPublicKey, identityConfig.URL, l.mspID, l.ignoreVerifyOnlyWallet) - } - if err != nil { - return err - } - - // instantiate provider from configuration - cryptoProvider, err := msp2.NewBCCSP(l.keyStore, l.curveID, l.curveID == math.BLS12_381_BBS) - if err != nil { - return errors.WithMessage(err, "failed to instantiate crypto provider") - } - provider, err := NewProvider(conf, l.signerService, bccsp.EidNymRhNym, cryptoProvider) - if err != nil { - return errors.Wrapf(err, "failed instantiating idemix msp provider from [%s]", identityConfig.URL) - } - - cacheSize, err := l.cacheSizeForID(identityConfig.ID) - if err != nil { - return err - } - - var getIdentityFunc func(opts *common.IdentityOptions) (driver.Identity, []byte, error) - l.deserializerManager.AddDeserializer(provider) - if provider.IsRemote() { - getIdentityFunc = func(opts *common.IdentityOptions) (driver.Identity, []byte, error) { - return nil, nil, errors.Errorf("cannot invoke this function, remote must register pseudonyms") - } - } else { - getIdentityFunc = cache.NewIdentityCache( - provider.Identity, - cacheSize, - &common.IdentityOptions{ - EIDExtension: true, - }, - ).Identity - } - logger.Debugf("append resolver for [%s]", identityConfig.ID) - l.addResolver(identityConfig.ID, provider.EnrollmentID(), provider.IsRemote(), defaultIdentity, getIdentityFunc) - - logger.Debugf("does the configuration already exists for [%s]?", identityConfig.ID) - if exists, _ := l.identityDB.ConfigurationExists(identityConfig.ID, msp2.IdentityConfigurationType); !exists { - logger.Debugf("does the configuration already exists for [%s]? no, add it", identityConfig.ID) - if err := l.identityDB.AddConfiguration(driver3.IdentityConfiguration{ - ID: identityConfig.ID, - Type: msp2.IdentityConfigurationType, - URL: identityConfig.URL, - Config: identityConfig.Config, - Raw: identityConfig.Raw, - }); err != nil { - return err - } - } - logger.Debugf("added idemix resolver for id [%s] with cache of size [%d], remote [%v]", identityConfig.ID+"@"+provider.EnrollmentID(), cacheSize, provider.IsRemote()) - return nil -} - -func (l *LocalMembership) registerProviders(configuration driver.IdentityConfiguration) error { - entries, err := os.ReadDir(configuration.URL) - if err != nil { - logger.Warnf("failed reading from [%s]: [%s]", configuration.URL, err) - return nil - } - found := 0 - for _, entry := range entries { - if !entry.IsDir() { - continue - } - id := entry.Name() - if err := l.registerProvider(driver.IdentityConfiguration{ - ID: id, - URL: filepath.Join(configuration.URL, id), - Config: configuration.Config, - }, false); err != nil { - logger.Errorf("failed registering msp provider [%s]: [%s]", id, err) - continue - } - found++ - } - if found == 0 { - return errors.Errorf("no valid identities found in [%s]", configuration.URL) - } - return nil -} - -func (l *LocalMembership) addResolver(Name string, EnrollmentID string, remote bool, defaultID bool, IdentityGetter common.GetIdentityFunc) { - resolver := &common.Resolver{ - Name: Name, - Default: defaultID, - EnrollmentID: EnrollmentID, - GetIdentity: IdentityGetter, - Remote: remote, - } - l.resolversByName[Name] = resolver - if len(EnrollmentID) != 0 { - l.resolversByEnrollmentID[EnrollmentID] = resolver - } - l.resolvers = append(l.resolvers, resolver) -} - -func (l *LocalMembership) getResolver(label string) *common.Resolver { - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("get anonymous identity info by label [%s]", hash.Hashable(label)) - } - r, ok := l.resolversByName[label] - if ok { - return r - } - - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("anonymous identity info not found for label [%s][%v]", hash.Hashable(label), l.resolversByName) - } - return nil -} - -func (l *LocalMembership) cacheSizeForID(id string) (int, error) { - cacheSize := l.config.CacheSizeForOwnerID(id) - if cacheSize <= 0 { - logger.Debugf("cache size for %s not configured, using default (%d)", id, l.cacheSize) - cacheSize = l.cacheSize - } - return cacheSize, nil -} - -func (l *LocalMembership) loadFromStorage() error { - it, err := l.identityDB.IteratorConfigurations(msp2.IdentityConfigurationType) - if err != nil { - return errors.WithMessage(err, "failed to get registered identities from kvs") - } - // copy the iterator - items := make([]driver3.IdentityConfiguration, 0) - for it.HasNext() { - item, err := it.Next() - if err != nil { - return err - } - items = append(items, item) - } - it.Close() - for _, entry := range items { - id := entry.ID - if l.getResolver(id) != nil { - logger.Debugf("from storage: id [%s] already exists", id) - continue - } - logger.Debugf("from storage: id [%s] does no exist, register it", id) - if err := l.registerIdentityConfiguration(driver.IdentityConfiguration{ - ID: entry.ID, - URL: entry.URL, - Config: entry.Config, - Raw: entry.Raw, - }, l.GetDefaultIdentifier() == ""); err != nil { - return err - } - } - return nil -} diff --git a/token/services/identity/msp/rolefactory.go b/token/services/identity/msp/rolefactory.go index 4a6762bfd..e0082bfa8 100644 --- a/token/services/identity/msp/rolefactory.go +++ b/token/services/identity/msp/rolefactory.go @@ -11,13 +11,13 @@ import ( "github.com/hyperledger-labs/fabric-token-sdk/token" "github.com/hyperledger-labs/fabric-token-sdk/token/driver" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity" + common2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/common" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/config" driver2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/driver" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/common" - config2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/config" idemix2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/idemix" "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/idemix/msp" x5092 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/x509" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging" "github.com/pkg/errors" ) @@ -42,13 +42,14 @@ var RoleToMSPID = map[driver.IdentityRole]string{ // RoleFactory is the factory for creating wallets, idemix and x509 type RoleFactory struct { + Logger logging.Logger TMSID token.TMSID - Config config2.Config + Config driver2.Config FSCIdentity driver.Identity NetworkDefaultIdentity driver.Identity - IdentityProvider common.IdentityProvider - SignerService common.SigService - BinderService common.BinderService + IdentityProvider driver2.IdentityProvider + SignerService driver2.SigService + BinderService driver2.BinderService StorageProvider identity.StorageProvider DeserializerManager driver2.DeserializerManager ignoreRemote bool @@ -56,18 +57,20 @@ type RoleFactory struct { // NewRoleFactory creates a new RoleFactory func NewRoleFactory( + logger logging.Logger, TMSID token.TMSID, - config config2.Config, + config driver2.Config, fscIdentity driver.Identity, networkDefaultIdentity driver.Identity, - identityProvider common.IdentityProvider, - signerService common.SigService, - binderService common.BinderService, + identityProvider driver2.IdentityProvider, + signerService driver2.SigService, + binderService driver2.BinderService, storageProvider identity.StorageProvider, deserializerManager driver2.DeserializerManager, ignoreRemote bool, ) *RoleFactory { return &RoleFactory{ + Logger: logger, TMSID: TMSID, Config: config, FSCIdentity: fscIdentity, @@ -83,15 +86,8 @@ func NewRoleFactory( // NewIdemix creates a new Idemix-based role func (f *RoleFactory) NewIdemix(role driver.IdentityRole, cacheSize int, issuerPublicKey []byte, curveID math3.CurveID) (identity.Role, error) { - identities, err := f.IdentitiesForRole(role) - if err != nil { - return nil, errors.Wrapf(err, "failed to get identities for role [%d]", role) - } + f.Logger.Debugf("create idemix role for [%s]", driver.IdentityRoleStrings[role]) - identityDB, err := f.StorageProvider.OpenIdentityDB(f.TMSID) - if err != nil { - return nil, errors.Wrapf(err, "failed to get wallet path storage") - } backend, err := f.StorageProvider.NewKeystore() if err != nil { return nil, errors.Wrapf(err, "failed to get new keystore backend") @@ -100,25 +96,41 @@ func (f *RoleFactory) NewIdemix(role driver.IdentityRole, cacheSize int, issuerP if err != nil { return nil, errors.Wrapf(err, "failed to instantiate bccsp key store") } - lm := idemix2.NewLocalMembership( + kmp := idemix2.NewKeyManagerProvider( issuerPublicKey, curveID, + RoleToMSPID[role], + keyStore, + f.SignerService, + f.Config, + cacheSize, + f.ignoreRemote, + ) + + identityDB, err := f.StorageProvider.OpenIdentityDB(f.TMSID) + if err != nil { + return nil, errors.Wrapf(err, "failed to get wallet path storage") + } + lm := common2.NewLocalMembership( + f.Logger, f.Config, f.NetworkDefaultIdentity, f.SignerService, f.DeserializerManager, identityDB, - keyStore, + f.BinderService, RoleToMSPID[role], - cacheSize, - identities, - f.ignoreRemote, + kmp, ) - if err := lm.Load(); err != nil { + identities, err := f.IdentitiesForRole(role) + if err != nil { + return nil, errors.Wrapf(err, "failed to get identities for role [%d]", role) + } + if err := lm.Load(identities); err != nil { return nil, errors.WithMessage(err, "failed to load identities") } - return &BindingRole{ - Role: idemix2.NewRole(role, f.TMSID.Network, f.FSCIdentity, lm), + return &WrappingBindingRole{ + Role: common2.NewAnonymousRole(f.Logger, role, f.TMSID.Network, f.FSCIdentity, lm), IdentityType: IdemixIdentity, RootIdentity: f.FSCIdentity, IdentityProvider: f.IdentityProvider, @@ -136,29 +148,35 @@ func (f *RoleFactory) NewWrappedX509(role driver.IdentityRole, ignoreRemote bool } func (f *RoleFactory) newX509WithType(role driver.IdentityRole, identityType string, ignoreRemote bool) (identity.Role, error) { - identities, err := f.IdentitiesForRole(role) - if err != nil { - return nil, errors.Wrapf(err, "failed to get identities for role [%d]", role) - } + f.Logger.Debugf("create x509 role for [%s]", driver.IdentityRoleStrings[role]) + + kmp := x5092.NewKeyManagerProvider(f.Config, RoleToMSPID[role], f.SignerService, ignoreRemote) + identityDB, err := f.StorageProvider.OpenIdentityDB(f.TMSID) if err != nil { return nil, errors.Wrapf(err, "failed to get wallet path storage") } - lm := x5092.NewLocalMembership( + lm := common2.NewLocalMembership( + logging.MustGetLogger("token-sdk.services.identity.msp.x509"), f.Config, f.NetworkDefaultIdentity, f.SignerService, - f.BinderService, f.DeserializerManager, identityDB, + f.BinderService, RoleToMSPID[role], - ignoreRemote, + kmp, ) + identities, err := f.IdentitiesForRole(role) + if err != nil { + return nil, errors.Wrapf(err, "failed to get identities for role [%d]", role) + } if err := lm.Load(identities); err != nil { return nil, errors.WithMessage(err, "failed to load identities") } - return &BindingRole{ - Role: x5092.NewRole(role, f.TMSID.Network, f.FSCIdentity, lm), + + return &WrappingBindingRole{ + Role: common2.NewLongTermRole(f.Logger, role, f.TMSID.Network, f.FSCIdentity, lm), IdentityType: identityType, RootIdentity: f.FSCIdentity, IdentityProvider: f.IdentityProvider, @@ -171,21 +189,32 @@ func (f *RoleFactory) IdentitiesForRole(role driver.IdentityRole) ([]*config.Ide return f.Config.IdentitiesForRole(role) } -type BindingRole struct { +// BindingRole returns a new role wrapping the passed one. +// Identities will be bound to the long term identities this factory refers to. +func (f *RoleFactory) BindingRole(role identity.Role) (identity.Role, error) { + return &WrappingBindingRole{ + Role: role, + RootIdentity: f.FSCIdentity, + IdentityProvider: f.IdentityProvider, + BinderService: f.BinderService, + }, nil +} + +type WrappingBindingRole struct { identity.Role IdentityType identity.Type RootIdentity driver.Identity - IdentityProvider common.IdentityProvider - BinderService common.BinderService + IdentityProvider driver2.IdentityProvider + BinderService driver2.BinderService } -func (r *BindingRole) GetIdentityInfo(id string) (driver.IdentityInfo, error) { +func (r *WrappingBindingRole) GetIdentityInfo(id string) (driver.IdentityInfo, error) { info, err := r.Role.GetIdentityInfo(id) if err != nil { return nil, err } - return &Info{ + return &WrappingBindingInfo{ IdentityInfo: info, IdentityType: r.IdentityType, RootIdentity: r.RootIdentity, @@ -194,26 +223,26 @@ func (r *BindingRole) GetIdentityInfo(id string) (driver.IdentityInfo, error) { }, nil } -// Info wraps a driver.IdentityInfo to further register the audit info, +// WrappingBindingInfo wraps a driver.IdentityInfo to further register the audit info, // and binds the new identity to the default FSC node identity -type Info struct { +type WrappingBindingInfo struct { driver.IdentityInfo IdentityType identity.Type RootIdentity driver.Identity - IdentityProvider common.IdentityProvider - BinderService common.BinderService + IdentityProvider driver2.IdentityProvider + BinderService driver2.BinderService } -func (i *Info) ID() string { +func (i *WrappingBindingInfo) ID() string { return i.IdentityInfo.ID() } -func (i *Info) EnrollmentID() string { +func (i *WrappingBindingInfo) EnrollmentID() string { return i.IdentityInfo.EnrollmentID() } -func (i *Info) Get() (driver.Identity, []byte, error) { +func (i *WrappingBindingInfo) Get() (driver.Identity, []byte, error) { // get the identity id, ai, err := i.IdentityInfo.Get() if err != nil { diff --git a/token/services/identity/msp/x509/deserializer.go b/token/services/identity/msp/x509/deserializer.go index 3ba395be9..4470fab32 100644 --- a/token/services/identity/msp/x509/deserializer.go +++ b/token/services/identity/msp/x509/deserializer.go @@ -21,7 +21,7 @@ import ( // MSPIdentityDeserializer takes as MSP identity and returns an ECDSA verifier type MSPIdentityDeserializer struct{} -func (deserializer *MSPIdentityDeserializer) DeserializeVerifier(id driver.Identity) (driver.Verifier, error) { +func (d *MSPIdentityDeserializer) DeserializeVerifier(id driver.Identity) (driver.Verifier, error) { si := &msp.SerializedIdentity{} err := proto.Unmarshal(id, si) if err != nil { diff --git a/token/services/identity/msp/x509/provider.go b/token/services/identity/msp/x509/km.go similarity index 67% rename from token/services/identity/msp/x509/provider.go rename to token/services/identity/msp/x509/km.go index 55fe76efc..2fac942c2 100644 --- a/token/services/identity/msp/x509/provider.go +++ b/token/services/identity/msp/x509/km.go @@ -12,7 +12,6 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/pkg/utils/proto" "github.com/hyperledger-labs/fabric-token-sdk/token/driver" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/common" msp2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/x509/msp" "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging" "github.com/hyperledger/fabric-protos-go/msp" @@ -25,28 +24,28 @@ type SignerService interface { RegisterSigner(identity driver.Identity, signer driver.Signer, verifier driver.Verifier, signerInfo []byte) error } -type Provider struct { +type KeyManager struct { sID driver.SigningIdentity id []byte enrollmentID string } -// NewProvider returns a new X509 provider with the passed BCCSP configuration. +// NewKeyManager returns a new X509 provider with the passed BCCSP configuration. // If the configuration path contains the secret key, // then the provider can generate also signatures, otherwise it cannot. -func NewProvider(mspConfigPath, keyStorePath, mspID string, signerService SignerService, bccspConfig *msp2.BCCSP) (*Provider, *msp.MSPConfig, error) { +func NewKeyManager(mspConfigPath, keyStorePath, mspID string, signerService SignerService, bccspConfig *msp2.BCCSP) (*KeyManager, *msp.MSPConfig, error) { conf, err := msp2.GetLocalMspConfig(mspConfigPath, mspID) if err != nil { return nil, nil, errors.WithMessagef(err, "could not get msp config from dir [%s]", mspConfigPath) } - p, conf, err := NewProviderFromConf(conf, mspConfigPath, keyStorePath, mspID, signerService, bccspConfig) + p, conf, err := NewKeyManagerFromConf(conf, mspConfigPath, keyStorePath, mspID, signerService, bccspConfig) if err != nil { return nil, nil, err } return p, conf, nil } -func NewProviderFromConf(conf *msp.MSPConfig, mspConfigPath, keyStorePath, mspID string, signerService SignerService, bccspConfig *msp2.BCCSP) (*Provider, *msp.MSPConfig, error) { +func NewKeyManagerFromConf(conf *msp.MSPConfig, mspConfigPath, keyStorePath, mspID string, signerService SignerService, bccspConfig *msp2.BCCSP) (*KeyManager, *msp.MSPConfig, error) { if conf == nil { logger.Debugf("load msp config from [%s:%s]", mspConfigPath, mspID) var err error @@ -56,19 +55,19 @@ func NewProviderFromConf(conf *msp.MSPConfig, mspConfigPath, keyStorePath, mspID } } logger.Debugf("msp config [%d]", conf.Type) - p, err := newSigningProvider(conf, mspConfigPath, keyStorePath, mspID, signerService, bccspConfig) + p, err := newSigningKeyManager(conf, mspConfigPath, keyStorePath, mspID, signerService, bccspConfig) if err == nil { return p, conf, nil } // load as verify only - p, conf, err = newVerifyingProvider(conf, mspConfigPath, mspID) + p, conf, err = newVerifyingKeyManager(conf, mspConfigPath, mspID) if err != nil { return nil, nil, err } return p, conf, err } -func newSigningProvider(conf *msp.MSPConfig, mspConfigPath, keyStorePath, mspID string, signerService SignerService, bccspConfig *msp2.BCCSP) (*Provider, error) { +func newSigningKeyManager(conf *msp.MSPConfig, mspConfigPath, keyStorePath, mspID string, signerService SignerService, bccspConfig *msp2.BCCSP) (*KeyManager, error) { sID, err := msp2.GetSigningIdentity(conf, mspConfigPath, keyStorePath, bccspConfig) if err != nil { return nil, err @@ -84,10 +83,10 @@ func newSigningProvider(conf *msp.MSPConfig, mspConfigPath, keyStorePath, mspID return nil, errors.Wrapf(err, "failed registering x509 signer") } } - return newProvider(sID, idRaw) + return newKeyManager(sID, idRaw) } -func newVerifyingProvider(conf *msp.MSPConfig, mspConfigPath, mspID string) (*Provider, *msp.MSPConfig, error) { +func newVerifyingKeyManager(conf *msp.MSPConfig, mspConfigPath, mspID string) (*KeyManager, *msp.MSPConfig, error) { conf, err := msp2.RemoveSigningIdentityInfo(conf) if err != nil { return nil, nil, err @@ -96,26 +95,26 @@ func newVerifyingProvider(conf *msp.MSPConfig, mspConfigPath, mspID string) (*Pr if err != nil { return nil, nil, errors.WithMessagef(err, "failed to load msp identity at [%s]", mspConfigPath) } - p, err := newProvider(nil, idRaw) + p, err := newKeyManager(nil, idRaw) if err != nil { return nil, nil, err } return p, conf, nil } -func newProvider(sID driver.SigningIdentity, id []byte) (*Provider, error) { +func newKeyManager(sID driver.SigningIdentity, id []byte) (*KeyManager, error) { enrollmentID, err := msp2.GetEnrollmentID(id) if err != nil { return nil, errors.Wrapf(err, "failed to get enrollment id") } - return &Provider{sID: sID, id: id, enrollmentID: enrollmentID}, nil + return &KeyManager{sID: sID, id: id, enrollmentID: enrollmentID}, nil } -func (p *Provider) IsRemote() bool { +func (p *KeyManager) IsRemote() bool { return p.sID == nil } -func (p *Provider) Identity(opts *common.IdentityOptions) (driver.Identity, []byte, error) { +func (p *KeyManager) Identity([]byte) (driver.Identity, []byte, error) { revocationHandle, err := msp2.GetRevocationHandle(p.id) if err != nil { return nil, nil, errors.Wrapf(err, "failed getting revocation handle") @@ -132,11 +131,11 @@ func (p *Provider) Identity(opts *common.IdentityOptions) (driver.Identity, []by return p.id, infoRaw, nil } -func (p *Provider) EnrollmentID() string { +func (p *KeyManager) EnrollmentID() string { return p.enrollmentID } -func (p *Provider) DeserializeVerifier(raw []byte) (driver.Verifier, error) { +func (p *KeyManager) DeserializeVerifier(raw []byte) (driver.Verifier, error) { si := &msp.SerializedIdentity{} err := proto.Unmarshal(raw, si) if err != nil { @@ -156,11 +155,11 @@ func (p *Provider) DeserializeVerifier(raw []byte) (driver.Verifier, error) { return msp2.NewECDSAVerifier(publicKey), nil } -func (p *Provider) DeserializeSigner(raw []byte) (driver.Signer, error) { +func (p *KeyManager) DeserializeSigner(raw []byte) (driver.Signer, error) { return nil, errors.New("not supported") } -func (p *Provider) Info(raw []byte, auditInfo []byte) (string, error) { +func (p *KeyManager) Info(raw []byte, auditInfo []byte) (string, error) { si := &msp.SerializedIdentity{} err := proto.Unmarshal(raw, si) if err != nil { @@ -173,10 +172,14 @@ func (p *Provider) Info(raw []byte, auditInfo []byte) (string, error) { return fmt.Sprintf("MSP.x509: [%s][%s][%s]", driver.Identity(raw).UniqueID(), si.Mspid, cert.Subject.CommonName), nil } -func (p *Provider) SerializedIdentity() (driver.SigningIdentity, error) { - return p.sID, nil +func (p *KeyManager) Anonymous() bool { + return false +} + +func (p *KeyManager) String() string { + return fmt.Sprintf("X509 KeyManager for EID [%s]", p.enrollmentID) } -func (p *Provider) String() string { - return fmt.Sprintf("X509 Provider for EID [%s]", p.enrollmentID) +func (p *KeyManager) SerializedIdentity() (driver.SigningIdentity, error) { + return p.sID, nil } diff --git a/token/services/identity/msp/x509/provider_test.go b/token/services/identity/msp/x509/km_test.go similarity index 84% rename from token/services/identity/msp/x509/provider_test.go rename to token/services/identity/msp/x509/km_test.go index cdd8a6002..e6c8cb9d8 100644 --- a/token/services/identity/msp/x509/provider_test.go +++ b/token/services/identity/msp/x509/km_test.go @@ -13,8 +13,10 @@ import ( ) func TestDeserializer(t *testing.T) { - p, _, err := NewProvider("./testdata/msp", "", "apple", nil, nil) + p, _, err := NewKeyManager("./testdata/msp", "", "apple", nil, nil) assert.NoError(t, err) + assert.False(t, p.Anonymous()) + id, auditInfo, err := p.Identity(nil) assert.NoError(t, err) eID := p.EnrollmentID() diff --git a/token/services/identity/msp/x509/kmp.go b/token/services/identity/msp/x509/kmp.go new file mode 100644 index 000000000..db4a88e60 --- /dev/null +++ b/token/services/identity/msp/x509/kmp.go @@ -0,0 +1,130 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package x509 + +import ( + "os" + "path/filepath" + + "github.com/hyperledger-labs/fabric-smart-client/pkg/utils/proto" + "github.com/hyperledger-labs/fabric-token-sdk/token/driver" + common2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/common" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/config" + driver2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/driver" + "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/x509/msp" + m "github.com/hyperledger/fabric-protos-go/msp" + "github.com/pkg/errors" + "gopkg.in/yaml.v2" +) + +const ( + KeystoreFullFolder = "keystoreFull" + PrivateKeyFileName = "priv_sk" + KeystoreFolder = "keystore" +) + +type KeyManagerProvider struct { + config driver2.Config + mspID string + signerService driver2.SigService + // ignoreVerifyOnlyWallet when set to true, for each wallet the service will force the load of the secrets + ignoreVerifyOnlyWallet bool +} + +func NewKeyManagerProvider(config driver2.Config, mspID string, signerService driver2.SigService, ignoreVerifyOnlyWallet bool) *KeyManagerProvider { + return &KeyManagerProvider{config: config, mspID: mspID, signerService: signerService, ignoreVerifyOnlyWallet: ignoreVerifyOnlyWallet} +} + +func (k *KeyManagerProvider) Get(idConfig *driver.IdentityConfiguration) (common2.KeyManager, error) { + identityConfig := &config.Identity{ + ID: idConfig.ID, + Path: idConfig.URL, + } + if len(idConfig.Config) != 0 { + // load opts as yaml + if err := yaml.Unmarshal(idConfig.Config, &identityConfig.Opts); err != nil { + return nil, errors.Wrapf(err, "failed to load options for [%s]", idConfig.ID) + } + } + var mspConfig *m.MSPConfig + if len(idConfig.Raw) != 0 { + // load raw as mspConfig + mspConfig = &m.MSPConfig{} + if err := proto.Unmarshal(idConfig.Raw, mspConfig); err != nil { + return nil, errors.Wrapf(err, "failed to load msp config [%s]", idConfig.ID) + } + } + return k.registerIdentity(mspConfig, identityConfig, idConfig) +} + +func (k *KeyManagerProvider) registerIdentity(conf *m.MSPConfig, identityConfig *config.Identity, idConfig *driver.IdentityConfiguration) (common2.KeyManager, error) { + // Try to register the MSP provider + translatedPath := k.config.TranslatePath(identityConfig.Path) + p, err := k.registerProvider(conf, identityConfig, translatedPath, idConfig) + if err != nil { + return nil, errors.WithMessage(err, "failed to register MSP provider") + } + + return p, nil +} + +func (k *KeyManagerProvider) registerProvider(conf *m.MSPConfig, identityConfig *config.Identity, translatedPath string, idConfig *driver.IdentityConfiguration) (common2.KeyManager, error) { + opts, err := msp.ToBCCSPOpts(identityConfig.Opts) + if err != nil { + return nil, errors.WithMessage(err, "failed to extract BCCSP options") + } + if opts == nil { + logger.Debugf("no BCCSP options set for [%s], opts [%v]", identityConfig.ID, identityConfig.Opts) + } else { + logger.Debugf("BCCSP options set for [%s] to [%v:%v:%v]", identityConfig.ID, opts, opts.PKCS11, opts.SW) + } + + keyStorePath := k.keyStorePath(translatedPath) + logger.Debugf("load provider at [%s][%s]", translatedPath, keyStorePath) + // Try without "msp" + provider, conf, err := NewKeyManagerFromConf(conf, translatedPath, keyStorePath, k.mspID, k.signerService, opts) + if err != nil { + logger.Debugf("failed loading provider at [%s]: [%s]", translatedPath, err) + // Try with "msp" + provider, conf, err = NewKeyManagerFromConf(conf, filepath.Join(translatedPath, "msp"), keyStorePath, k.mspID, k.signerService, opts) + if err != nil { + logger.Debugf("failed loading provider at [%s]: [%s]", filepath.Join(translatedPath, "msp"), err) + return nil, err + } + } + + optsRaw, err := yaml.Marshal(identityConfig.Opts) + if err != nil { + return nil, errors.Wrapf(err, "failed to marshal config [%v]", identityConfig) + } + confRaw, err := proto.Marshal(conf) + if err != nil { + return nil, errors.Wrapf(err, "failed to marshal msp config [%v]", identityConfig) + } + idConfig.Config = optsRaw + idConfig.Raw = confRaw + + return provider, nil +} + +func (k *KeyManagerProvider) keyStorePath(translatedPath string) string { + if !k.ignoreVerifyOnlyWallet { + return "" + } + + path := filepath.Join(translatedPath, KeystoreFullFolder) + if _, err := os.Stat(path); err == nil { + return path + } + + path = filepath.Join(translatedPath, "msp", KeystoreFullFolder) + if _, err := os.Stat(path); err == nil { + return path + } + + return "" +} diff --git a/token/services/identity/msp/x509/lm.go b/token/services/identity/msp/x509/lm.go deleted file mode 100644 index 4d39839cf..000000000 --- a/token/services/identity/msp/x509/lm.go +++ /dev/null @@ -1,383 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package x509 - -import ( - "os" - "path/filepath" - "sync" - - driver3 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/driver" - - "github.com/hyperledger-labs/fabric-smart-client/pkg/utils/proto" - "github.com/hyperledger-labs/fabric-token-sdk/token/driver" - driver2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/db/driver" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/config" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/common" - config2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/config" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/identity/msp/x509/msp" - m "github.com/hyperledger/fabric-protos-go/msp" - "github.com/pkg/errors" - "go.uber.org/zap/zapcore" - "gopkg.in/yaml.v2" -) - -const ( - KeystoreFullFolder = "keystoreFull" - PrivateKeyFileName = "priv_sk" - KeystoreFolder = "keystore" - IdentityConfigurationType = "x509" -) - -type LocalMembership struct { - config config2.Config - defaultNetworkIdentity driver.Identity - signerService common.SigService - binderService common.BinderService - deserializerManager driver3.DeserializerManager - identityDB driver2.IdentityDB - mspID string - - resolversMutex sync.RWMutex - resolvers []*common.Resolver - resolversByName map[string]*common.Resolver - resolversByEnrollmentID map[string]*common.Resolver - bccspResolversByIdentity map[string]*common.Resolver - // ignoreVerifyOnlyWallet when set to true, for each wallet the service will force the load of the secrets - ignoreVerifyOnlyWallet bool -} - -func NewLocalMembership( - config config2.Config, - defaultNetworkIdentity driver.Identity, - signerService common.SigService, - binderService common.BinderService, - deserializerManager driver3.DeserializerManager, - identityDB driver2.IdentityDB, - mspID string, - ignoreVerifyOnlyWallet bool, -) *LocalMembership { - return &LocalMembership{ - config: config, - defaultNetworkIdentity: defaultNetworkIdentity, - signerService: signerService, - binderService: binderService, - deserializerManager: deserializerManager, - identityDB: identityDB, - mspID: mspID, - bccspResolversByIdentity: map[string]*common.Resolver{}, - resolversByEnrollmentID: map[string]*common.Resolver{}, - resolversByName: map[string]*common.Resolver{}, - ignoreVerifyOnlyWallet: ignoreVerifyOnlyWallet, - } -} - -func (lm *LocalMembership) Load(identities []*config.Identity) error { - logger.Debugf("Load x509 Wallets: [%+q]", identities) - - // load identities from configuration - for _, identityConfig := range identities { - logger.Debugf("Load x509 Wallet: [%v]", identityConfig) - if err := lm.registerIdentity(nil, identityConfig, identityConfig.Default); err != nil { - return errors.WithMessage(err, "failed to load identity") - } - } - - // load identities from storage - logger.Debugf("load identities from storage...") - if err := lm.loadFromStorage(); err != nil { - return errors.Wrapf(err, "failed to load identities from storage") - } - logger.Debugf("load identities from storage...done") - - // if no default identity, use the first one - defaultIdentifier := lm.GetDefaultIdentifier() - if len(defaultIdentifier) == 0 { - logger.Warnf("no default identity, use the first one available") - if len(lm.resolvers) > 0 { - logger.Warnf("set default identity to %s", lm.resolvers[0].Name) - lm.resolvers[0].Default = true - } else { - logger.Warnf("cannot set default identity, no identity available") - } - } else { - logger.Debugf("default identifier is [%s]", defaultIdentifier) - } - return nil -} - -func (lm *LocalMembership) DefaultNetworkIdentity() driver.Identity { - return lm.defaultNetworkIdentity -} - -func (lm *LocalMembership) IsMe(id driver.Identity) bool { - return lm.signerService.IsMe(id) -} - -func (lm *LocalMembership) GetIdentifier(id driver.Identity) (string, error) { - label := id.String() - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("get identity info by label [%s]", label) - } - r := lm.getResolver(label) - if r == nil { - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("identity info not found for label [%s][%v]", label, lm.resolversByName) - } - return "", errors.New("not found") - } - return r.Name, nil -} - -func (lm *LocalMembership) GetDefaultIdentifier() string { - for _, resolver := range lm.resolvers { - if resolver.Default { - return resolver.Name - } - } - return "" -} - -func (lm *LocalMembership) GetIdentityInfo(label string, auditInfo []byte) (driver.IdentityInfo, error) { - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("get identity info by label [%s]", label) - } - r := lm.getResolver(label) - if r == nil { - return nil, errors.Errorf("identity info not found for label [%s][%v]", label, lm.resolversByName) - } - - return common.NewIdentityInfo( - r.Name, - r.EnrollmentID, - r.Remote, - func() (driver.Identity, []byte, error) { - return r.GetIdentity(nil) - }, - ), nil -} - -func (lm *LocalMembership) RegisterIdentity(idConfig driver.IdentityConfiguration) error { - identityConfig := &config.Identity{ - ID: idConfig.ID, - Path: idConfig.URL, - } - if len(idConfig.Config) != 0 { - // load opts as yaml - if err := yaml.Unmarshal(idConfig.Config, &identityConfig.Opts); err != nil { - return errors.Wrapf(err, "failed to load options for [%s]", idConfig.ID) - } - } - var mspConfig *m.MSPConfig - if len(idConfig.Raw) != 0 { - // load raw as mspConfig - mspConfig = &m.MSPConfig{} - if err := proto.Unmarshal(idConfig.Raw, mspConfig); err != nil { - return errors.Wrapf(err, "failed to load msp config [%s]", idConfig.ID) - } - } - return lm.registerIdentity(mspConfig, identityConfig, lm.GetDefaultIdentifier() == "") -} - -func (lm *LocalMembership) IDs() ([]string, error) { - var ids []string - for _, resolver := range lm.resolvers { - ids = append(ids, resolver.Name) - } - return ids, nil -} - -func (lm *LocalMembership) registerIdentity(conf *m.MSPConfig, c *config.Identity, setDefault bool) error { - // Try to register the MSP provider - translatedPath := lm.config.TranslatePath(c.Path) - if err := lm.registerProvider(conf, c, translatedPath, setDefault); err != nil { - // Does path correspond to a holder containing multiple MSP identities? - if err := lm.registerProviders(c, translatedPath); err != nil { - return errors.WithMessage(err, "failed to register MSP provider") - } - } - return nil -} - -func (lm *LocalMembership) registerProvider(conf *m.MSPConfig, identityConfig *config.Identity, translatedPath string, setDefault bool) error { - opts, err := msp.ToBCCSPOpts(identityConfig.Opts) - if err != nil { - return errors.WithMessage(err, "failed to extract BCCSP options") - } - if opts == nil { - logger.Debugf("no BCCSP options set for [%s], opts [%v]", identityConfig.ID, identityConfig.Opts) - } else { - logger.Debugf("BCCSP options set for [%s] to [%v:%v:%v]", identityConfig.ID, opts, opts.PKCS11, opts.SW) - } - - keyStorePath := lm.keyStorePath(translatedPath) - logger.Debugf("load provider at [%s][%s]", translatedPath, keyStorePath) - // Try without "msp" - provider, conf, err := NewProviderFromConf(conf, translatedPath, keyStorePath, lm.mspID, lm.signerService, opts) - if err != nil { - logger.Debugf("failed loading provider at [%s]: [%s]", translatedPath, err) - // Try with "msp" - provider, conf, err = NewProviderFromConf(conf, filepath.Join(translatedPath, "msp"), keyStorePath, lm.mspID, lm.signerService, opts) - if err != nil { - logger.Debugf("failed loading provider at [%s]: [%s]", filepath.Join(translatedPath, "msp"), err) - return err - } - } - - if err := lm.addResolver(identityConfig, provider, setDefault); err != nil { - return err - } - - if exists, _ := lm.identityDB.ConfigurationExists(identityConfig.ID, IdentityConfigurationType); !exists { - optsRaw, err := yaml.Marshal(identityConfig.Opts) - if err != nil { - return errors.Wrapf(err, "failed to marshal config [%v]", identityConfig) - } - confRaw, err := proto.Marshal(conf) - if err != nil { - return errors.Wrapf(err, "failed to marshal msp config [%v]", identityConfig) - } - if err := lm.identityDB.AddConfiguration(driver2.IdentityConfiguration{ - ID: identityConfig.ID, - Type: IdentityConfigurationType, - URL: identityConfig.Path, - Config: optsRaw, - Raw: confRaw, - }); err != nil { - return err - } - } - - return nil -} - -func (lm *LocalMembership) registerProviders(c *config.Identity, translatedPath string) error { - entries, err := os.ReadDir(translatedPath) - if err != nil { - logger.Warnf("failed reading from [%s]: [%s]", translatedPath, err) - return nil - } - for _, entry := range entries { - if !entry.IsDir() { - continue - } - id := entry.Name() - if err := lm.registerProvider(nil, c, filepath.Join(translatedPath, id), false); err != nil { - logger.Errorf("failed registering msp provider [%s]: [%s]", id, err) - } - } - return nil -} - -func (lm *LocalMembership) addResolver(identityConfig *config.Identity, provider *Provider, defaultID bool) error { - lm.resolversMutex.Lock() - defer lm.resolversMutex.Unlock() - - eID := provider.EnrollmentID() - walletId, _, err := provider.Identity(nil) - if err != nil { - return errors.WithMessagef(err, "failed to get wallet identity from [%s]", identityConfig.ID) - } - logger.Debugf("adding x509 wallet resolver [%s:%s:%s]", identityConfig.ID, eID, walletId) - - // deserializer - lm.deserializerManager.AddDeserializer(provider) - - // bind - if lm.binderService != nil { - if err := lm.binderService.Bind(lm.defaultNetworkIdentity, walletId, false); err != nil { - return errors.WithMessagef(err, "cannot bind identity for [%s,%s]", walletId, eID) - } - } - - resolver := &common.Resolver{ - Name: identityConfig.ID, - Default: defaultID, - EnrollmentID: eID, - GetIdentity: provider.Identity, - Remote: provider.IsRemote(), - } - lm.bccspResolversByIdentity[walletId.String()] = resolver - lm.resolversByName[identityConfig.ID] = resolver - if len(eID) != 0 { - lm.resolversByEnrollmentID[eID] = resolver - } - lm.resolvers = append(lm.resolvers, resolver) - - logger.Debugf("adding x509 wallet resolver [%s:%s:%s] done", identityConfig.ID, eID, walletId) - return nil -} - -func (lm *LocalMembership) getResolver(label string) *common.Resolver { - lm.resolversMutex.RLock() - defer lm.resolversMutex.RUnlock() - - r, ok := lm.resolversByName[label] - if ok { - return r - } - - r, ok = lm.bccspResolversByIdentity[label] - if ok { - return r - } - - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("identity info not found for label [%s][%v]", label, lm.bccspResolversByIdentity) - } - return nil -} - -func (lm *LocalMembership) keyStorePath(translatedPath string) string { - if !lm.ignoreVerifyOnlyWallet { - return "" - } - - path := filepath.Join(translatedPath, KeystoreFullFolder) - if _, err := os.Stat(path); err == nil { - return path - } - - path = filepath.Join(translatedPath, "msp", KeystoreFullFolder) - if _, err := os.Stat(path); err == nil { - return path - } - - return "" -} - -func (lm *LocalMembership) loadFromStorage() error { - it, err := lm.identityDB.IteratorConfigurations(IdentityConfigurationType) - if err != nil { - return errors.WithMessage(err, "failed to get registered identities from kvs") - } - // copy the iterator - items := make([]driver2.IdentityConfiguration, 0) - for it.HasNext() { - item, err := it.Next() - if err != nil { - return err - } - items = append(items, item) - } - it.Close() - for _, entry := range items { - id := entry.ID - if lm.getResolver(id) != nil { - continue - } - if err := lm.RegisterIdentity(driver.IdentityConfiguration{ - ID: id, - URL: entry.URL, - Config: entry.Config, - Raw: entry.Raw, - }); err != nil { - return err - } - } - return nil -} diff --git a/token/services/network/fabric/driver.go b/token/services/network/fabric/driver.go index cb8e41957..fc5bb97af 100644 --- a/token/services/network/fabric/driver.go +++ b/token/services/network/fabric/driver.go @@ -23,7 +23,7 @@ import ( "go.opentelemetry.io/otel/trace" ) -type DefaultPublicParamsFetcher driver3.DefaultPublicParamsFetcher +type DefaultPublicParamsFetcher driver3.NetworkPublicParamsFetcher type Driver struct { fnsProvider *fabric.NetworkServiceProvider @@ -36,7 +36,7 @@ type Driver struct { tmsProvider *token.ManagementServiceProvider identityProvider driver2.IdentityProvider tracerProvider trace.TracerProvider - defaultPublicParamsFetcher driver3.DefaultPublicParamsFetcher + defaultPublicParamsFetcher driver3.NetworkPublicParamsFetcher } func NewDriver( @@ -89,14 +89,7 @@ func (d *Driver) New(network, channel string) (driver.Network, error) { d.tokensManager, d.viewManager, d.tmsProvider, - endorsement.NewServiceProvider( - fns, - d.configService, - d.viewManager, - d.viewRegistry, - d.identityProvider, - d.tmsProvider, - ), + endorsement.NewServiceProvider(fns, d.configService, d.viewManager, d.viewRegistry, d.identityProvider), d.tracerProvider, d.defaultPublicParamsFetcher, ), nil diff --git a/token/services/network/fabric/endorsement/fsc.go b/token/services/network/fabric/endorsement/fsc.go index fd4291705..1891211f0 100644 --- a/token/services/network/fabric/endorsement/fsc.go +++ b/token/services/network/fabric/endorsement/fsc.go @@ -29,13 +29,12 @@ const ( func newFSCService( nw *fabric.NetworkService, - tms *token.ManagementService, + tmsID token.TMSID, configuration tdriver.Configuration, viewRegistry ViewRegistry, viewManager ViewManager, identityProvider IdentityProvider, ) (*fscService, error) { - tmsID := tms.ID() ch, err := nw.Channel(tmsID.Channel) if err != nil { return nil, errors.Wrapf(err, "failed getting channel [%s]", tmsID.Channel) @@ -43,6 +42,7 @@ func newFSCService( committer := ch.Committer() if configuration.GetBool(AmIAnEndorserKey) { logger.Info("this node is an endorser, prepare it...") + // if I'm an endorser, I need to process all token transactions if err := committer.ProcessNamespace(tmsID.Namespace); err != nil { return nil, errors.WithMessagef(err, "failed to add namespace to committer [%s]", tmsID.Namespace) } @@ -77,14 +77,14 @@ func newFSCService( return &fscService{ endorsers: endorsers, - tms: tms, + tmsID: tmsID, viewManager: viewManager, policyType: policyType, }, nil } type fscService struct { - tms *token.ManagementService + tmsID token.TMSID endorsers []view.Identity viewManager ViewManager policyType string @@ -103,7 +103,7 @@ func (e *fscService) Endorse(context view.Context, requestRaw []byte, signer vie logger.Debugf("request approval via fts endrosers with policy [%s]: [%d]...", e.policyType, len(endorsers)) envBoxed, err := e.viewManager.InitiateView(&fts.RequestApprovalView{ - TMS: e.tms, + TMSID: e.tmsID, RequestRaw: requestRaw, TxID: txID, Endorsers: endorsers, diff --git a/token/services/network/fabric/endorsement/provider.go b/token/services/network/fabric/endorsement/provider.go index 2d0aa2401..f8b9ec909 100644 --- a/token/services/network/fabric/endorsement/provider.go +++ b/token/services/network/fabric/endorsement/provider.go @@ -49,7 +49,6 @@ func NewServiceProvider( viewManager ViewManager, viewRegistry ViewRegistry, identityProvider IdentityProvider, - tmsProvider *token2.ManagementServiceProvider, ) *ServiceProvider { l := &loader{ fns: fns, @@ -57,7 +56,6 @@ func NewServiceProvider( viewManager: viewManager, viewRegistry: viewRegistry, identityProvider: identityProvider, - tmsProvider: tmsProvider, } return &ServiceProvider{Provider: lazy.NewProviderWithKeyMapper(key, l.load)} } @@ -72,11 +70,9 @@ type loader struct { viewManager ViewManager viewRegistry ViewRegistry identityProvider IdentityProvider - tmsProvider *token2.ManagementServiceProvider } func (l *loader) load(tmsID token2.TMSID) (Service, error) { - // if I'm an endorser, I need to process all token transactions configuration, err := l.configService.ConfigurationFor(tmsID.Network, tmsID.Channel, tmsID.Namespace) if err != nil { return nil, errors.WithMessagef(err, "failed to get configuration for [%s]", tmsID) @@ -88,11 +84,7 @@ func (l *loader) load(tmsID token2.TMSID) (Service, error) { } logger.Infof("FSC endorsement enabled...") - tms, err := l.tmsProvider.GetManagementService(token2.WithTMSID(tmsID)) - if err != nil { - return nil, errors.WithMessagef(err, "failed to get tms for [%s]", tmsID) - } - return newFSCService(l.fns, tms, configuration, l.viewRegistry, l.viewManager, l.identityProvider) + return newFSCService(l.fns, tmsID, configuration, l.viewRegistry, l.viewManager, l.identityProvider) } func key(tmsID token2.TMSID) string { diff --git a/token/services/network/fabric/fts/approval.go b/token/services/network/fabric/fts/approval.go index 0eb7246d4..d686d4b9e 100644 --- a/token/services/network/fabric/fts/approval.go +++ b/token/services/network/fabric/fts/approval.go @@ -32,7 +32,7 @@ const ( var logger = logging.MustGetLogger("token-sdk.network.fabric.fts") type RequestApprovalView struct { - TMS *token2.ManagementService + TMSID token2.TMSID TxID driver.TxID RequestRaw []byte // RequestAnchor, if not nil it will instruct the approver to verify the token request using this anchor and not the transaction it. @@ -55,11 +55,15 @@ func (r *RequestApprovalView) Call(context view.Context) (interface{}, error) { return nil, errors.WithMessagef(err, "failed to create endorser transaction") } - tx.SetProposal(r.TMS.Namespace(), "", InvokeFunction) + tms := token2.GetManagementService(context, token2.WithTMSID(r.TMSID)) + if tms == nil { + return nil, errors.Errorf("no token management service for [%s]", r.TMSID) + } + tx.SetProposal(tms.Namespace(), "", InvokeFunction) if err := tx.EndorseProposal(); err != nil { return nil, errors.WithMessagef(err, "failed to endorse proposal") } - if err := tx.SetTransientState("tmsID", r.TMS.ID()); err != nil { + if err := tx.SetTransientState("tmsID", tms.ID()); err != nil { return nil, errors.WithMessagef(err, "failed to set TMS ID transient") } if err := tx.SetTransient("token_request", r.RequestRaw); err != nil { diff --git a/token/services/network/fabric/network.go b/token/services/network/fabric/network.go index 83de09ed3..ba1c5223c 100644 --- a/token/services/network/fabric/network.go +++ b/token/services/network/fabric/network.go @@ -162,7 +162,7 @@ type Network struct { vaultLazyCache lazy.Provider[string, driver.Vault] tokenVaultLazyCache lazy.Provider[string, driver.TokenVault] subscribers *events.Subscribers - defaultPublicParamsFetcher driver3.DefaultPublicParamsFetcher + defaultPublicParamsFetcher driver3.NetworkPublicParamsFetcher endorsementServiceProvider *endorsement.ServiceProvider } @@ -178,7 +178,7 @@ func NewNetwork( tmsProvider *token2.ManagementServiceProvider, endorsementServiceProvider *endorsement.ServiceProvider, tracerProvider trace.TracerProvider, - defaultPublicParamsFetcher driver3.DefaultPublicParamsFetcher, + defaultPublicParamsFetcher driver3.NetworkPublicParamsFetcher, ) *Network { loader := &loader{ newVault: newVault, @@ -275,25 +275,12 @@ func (n *Network) Connect(ns string) ([]token2.ServiceOption, error) { return nil, errors.WithMessagef(err, "failed to fetch attach transaction filter [%s]", tmsID) } - // check the vault for public parameters, - // use them if they exists - v, err := n.TokenVault(ns) - if err != nil { - return nil, errors.WithMessagef(err, "failed to get network at [%s]", tmsID) - } - ppRaw, err := v.QueryEngine().PublicParams() - if err != nil { - return nil, errors.WithMessagef(err, "failed to get public params at [%s]", tmsID) - } - if len(ppRaw) != 0 { - return []token2.ServiceOption{token2.WithTMSID(tmsID), token2.WithPublicParameter(ppRaw)}, nil - } // Let the endorsement service initialize itself, if needed _, err = n.endorsementServiceProvider.Get(tmsID) if err != nil { return nil, errors.WithMessagef(err, "failed to get endorsement service at [%s]", tmsID) } - return []token2.ServiceOption{token2.WithTMSID(tmsID)}, nil + return nil, nil } func (n *Network) Vault(namespace string) (driver.Vault, error) { diff --git a/token/services/network/orion/driver.go b/token/services/network/orion/driver.go index de96961eb..285c4d870 100644 --- a/token/services/network/orion/driver.go +++ b/token/services/network/orion/driver.go @@ -13,7 +13,6 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/cache/secondcache" view2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/server/view" "github.com/hyperledger-labs/fabric-token-sdk/token" - driver3 "github.com/hyperledger-labs/fabric-token-sdk/token/driver" vault2 "github.com/hyperledger-labs/fabric-token-sdk/token/sdk/vault" "github.com/hyperledger-labs/fabric-token-sdk/token/services/config" "github.com/hyperledger-labs/fabric-token-sdk/token/services/network/common" @@ -23,8 +22,6 @@ import ( "go.opentelemetry.io/otel/trace" ) -type DefaultPublicParamsFetcher driver3.DefaultPublicParamsFetcher - func NewDriver( onsProvider *orion.NetworkServiceProvider, viewRegistry driver2.Registry, @@ -35,39 +32,36 @@ func NewDriver( identityProvider view2.IdentityProvider, filterProvider *common.AcceptTxInDBFilterProvider, tmsProvider *token.ManagementServiceProvider, - defaultPublicParamsFetcher DefaultPublicParamsFetcher, tracerProvider trace.TracerProvider, ) driver.NamedDriver { return driver.NamedDriver{ Name: "orion", Driver: &Driver{ - onsProvider: onsProvider, - viewRegistry: viewRegistry, - viewManager: viewManager, - vaultProvider: vaultProvider, - configProvider: configProvider, - configService: configService, - identityProvider: identityProvider, - filterProvider: filterProvider, - tmsProvider: tmsProvider, - defaultPublicParamsFetcher: defaultPublicParamsFetcher, - tracerProvider: tracerProvider, + onsProvider: onsProvider, + viewRegistry: viewRegistry, + viewManager: viewManager, + vaultProvider: vaultProvider, + configProvider: configProvider, + configService: configService, + identityProvider: identityProvider, + filterProvider: filterProvider, + tmsProvider: tmsProvider, + tracerProvider: tracerProvider, }, } } type Driver struct { - onsProvider *orion.NetworkServiceProvider - viewRegistry driver2.Registry - viewManager *view.Manager - vaultProvider vault.Provider - configProvider configProvider - configService *config.Service - identityProvider view2.IdentityProvider - filterProvider *common.AcceptTxInDBFilterProvider - tmsProvider *token.ManagementServiceProvider - defaultPublicParamsFetcher driver3.DefaultPublicParamsFetcher - tracerProvider trace.TracerProvider + onsProvider *orion.NetworkServiceProvider + viewRegistry driver2.Registry + viewManager *view.Manager + vaultProvider vault.Provider + configProvider configProvider + configService *config.Service + identityProvider view2.IdentityProvider + filterProvider *common.AcceptTxInDBFilterProvider + tmsProvider *token.ManagementServiceProvider + tracerProvider trace.TracerProvider } func (d *Driver) New(network, _ string) (driver.Network, error) { @@ -98,7 +92,6 @@ func (d *Driver) New(network, _ string) (driver.Network, error) { d.configService, d.filterProvider, dbManager, - d.defaultPublicParamsFetcher, d.tracerProvider, ), nil } diff --git a/token/services/network/orion/network.go b/token/services/network/orion/network.go index 4f8b9cb05..b1630663e 100644 --- a/token/services/network/orion/network.go +++ b/token/services/network/orion/network.go @@ -17,7 +17,6 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/tracing" "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" token2 "github.com/hyperledger-labs/fabric-token-sdk/token" - driver2 "github.com/hyperledger-labs/fabric-token-sdk/token/driver" "github.com/hyperledger-labs/fabric-token-sdk/token/services/db" common2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/network/common" "github.com/hyperledger-labs/fabric-token-sdk/token/services/network/common/rws/keys" @@ -45,11 +44,10 @@ type Network struct { filterProvider common2.TransactionFilterProvider[*common2.AcceptTxInDBsFilter] finalityTracer trace.Tracer - vaultLazyCache lazy.Provider[string, driver.Vault] - tokenVaultLazyCache lazy.Provider[string, driver.TokenVault] - subscribers *events.Subscribers - dbManager *DBManager - defaultPublicParamsFetcher driver2.DefaultPublicParamsFetcher + vaultLazyCache lazy.Provider[string, driver.Vault] + tokenVaultLazyCache lazy.Provider[string, driver.TokenVault] + subscribers *events.Subscribers + dbManager *DBManager } func NewNetwork( @@ -61,7 +59,6 @@ func NewNetwork( nsFinder common2.Configuration, filterProvider common2.TransactionFilterProvider[*common2.AcceptTxInDBsFilter], dbManager *DBManager, - defaultPublicParamsFetcher driver2.DefaultPublicParamsFetcher, tracerProvider trace.TracerProvider, ) *Network { loader := &loader{ @@ -80,7 +77,6 @@ func NewNetwork( vaultLazyCache: lazy.NewProvider(loader.loadVault), tokenVaultLazyCache: lazy.NewProvider(loader.loadTokenVault), subscribers: events.NewSubscribers(), ledger: &ledger{network: n.Name(), viewManager: viewManager, dbManager: dbManager}, - defaultPublicParamsFetcher: defaultPublicParamsFetcher, finalityTracer: tracerProvider.Tracer("finality_listener", tracing.WithMetricsOpts(tracing.MetricsOpts{ Namespace: "tokensdk_orion", LabelNames: []tracing.LabelName{}, @@ -136,13 +132,7 @@ func (n *Network) Connect(ns string) ([]token2.ServiceOption, error) { if err := n.n.Committer().AddTransactionFilter(transactionFilter); err != nil { return nil, errors.WithMessagef(err, "failed to fetch attach transaction filter [%s]", tmsID) } - - // fetch public params and instantiate the tms - ppRaw, err := n.FetchPublicParameters(ns) - if err != nil { - return nil, errors.WithMessagef(err, "failed to fetch public parameters for [%s]", tmsID) - } - return []token2.ServiceOption{token2.WithTMSID(tmsID), token2.WithPublicParameter(ppRaw)}, nil + return nil, nil } func (n *Network) Vault(namespace string) (driver.Vault, error) { diff --git a/token/services/network/orion/ppfetcher.go b/token/services/network/orion/ppfetcher.go deleted file mode 100644 index f8ff71ca2..000000000 --- a/token/services/network/orion/ppfetcher.go +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package orion - -import ( - "context" - - driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver" - view2 "github.com/hyperledger-labs/fabric-smart-client/platform/view" -) - -func NewCustodianPublicParamsFetcher(viewManager *view2.Manager) *custodianPublicParamsFetcher { - return &custodianPublicParamsFetcher{viewManager: viewManager} -} - -type custodianPublicParamsFetcher struct { - viewManager *view2.Manager -} - -func (f *custodianPublicParamsFetcher) Fetch(network driver2.Network, _ driver2.Channel, namespace driver2.Namespace) ([]byte, error) { - pp, err := f.viewManager.InitiateView(NewPublicParamsRequestView(network, namespace), context.TODO()) - if err != nil { - return nil, err - } - return pp.([]byte), nil -} diff --git a/token/services/ttx/auditor.go b/token/services/ttx/auditor.go index 670cc7b76..5a3894b13 100644 --- a/token/services/ttx/auditor.go +++ b/token/services/ttx/auditor.go @@ -307,11 +307,11 @@ func (a *AuditApproveView) signAndSendBack(context view.Context) error { // Sign aid, err := a.w.GetAuditorIdentity() if err != nil { - return errors.WithMessagef(err, "failed getting auditor identity for [%s]", context.Me()) + return errors.WithMessagef(err, "failed getting auditor identity for node [%s]", context.Me()) } signer, err := a.w.GetSigner(aid) if err != nil { - return errors.WithMessagef(err, "failed getting signing identity for auditor identity [%s]", context.Me()) + return errors.WithMessagef(err, "failed getting signing identity for auditor identity [%s]", aid) } logger.Debug("signer at auditor", signer, aid) diff --git a/token/services/ttx/endorse.go b/token/services/ttx/endorse.go index c29b6c227..0236a7508 100644 --- a/token/services/ttx/endorse.go +++ b/token/services/ttx/endorse.go @@ -641,6 +641,7 @@ func (f *ReceiveTransactionView) Call(context view.Context) (interface{}, error) } tx, err := NewTransactionFromBytes(context, msg) if err != nil { + logger.Warnf("failed creating transaction from bytes: [%v], try to unmarshal as signature request...", err) // try to unmarshal as SignatureRequest tx, err = f.unmarshalAsSignatureRequest(context, msg) if err != nil {