Explicitly specify hash in client applications

For some signing implementations, such as ed25519, a non-default hash
implementation must be specified when creating the Gateway connection in
client applications. Rather than relying on the default hash algorithm,
it is probably good practice in general to specify an algorithm that is
compatible with your signing implementation.

This change explicitly specifies the hash algorithm to raise visibility
of the option to select the hash algorithm.

Signed-off-by: Mark S. Lewis <Mark.S.Lewis@outlook.com>
This commit is contained in:
Mark S. Lewis 2024-10-07 15:48:06 +01:00
parent e37e991c4c
commit 489b422a2a
No known key found for this signature in database
19 changed files with 170 additions and 142 deletions

View file

@ -18,6 +18,7 @@ import (
"time" "time"
"github.com/hyperledger/fabric-gateway/pkg/client" "github.com/hyperledger/fabric-gateway/pkg/client"
"github.com/hyperledger/fabric-gateway/pkg/hash"
"github.com/hyperledger/fabric-gateway/pkg/identity" "github.com/hyperledger/fabric-gateway/pkg/identity"
"github.com/hyperledger/fabric-protos-go-apiv2/gateway" "github.com/hyperledger/fabric-protos-go-apiv2/gateway"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -50,6 +51,7 @@ func main() {
gw, err := client.Connect( gw, err := client.Connect(
id, id,
client.WithSign(sign), client.WithSign(sign),
client.WithHash(hash.SHA256),
client.WithClientConnection(clientConnection), client.WithClientConnection(clientConnection),
// Default timeouts for different gRPC calls // Default timeouts for different gRPC calls
client.WithEvaluateTimeout(5*time.Second), client.WithEvaluateTimeout(5*time.Second),

View file

@ -16,6 +16,7 @@ import org.hyperledger.fabric.client.Contract;
import org.hyperledger.fabric.client.EndorseException; import org.hyperledger.fabric.client.EndorseException;
import org.hyperledger.fabric.client.Gateway; import org.hyperledger.fabric.client.Gateway;
import org.hyperledger.fabric.client.GatewayException; import org.hyperledger.fabric.client.GatewayException;
import org.hyperledger.fabric.client.Hash;
import org.hyperledger.fabric.client.SubmitException; import org.hyperledger.fabric.client.SubmitException;
import org.hyperledger.fabric.client.identity.Identities; import org.hyperledger.fabric.client.identity.Identities;
import org.hyperledger.fabric.client.identity.Identity; import org.hyperledger.fabric.client.identity.Identity;
@ -60,7 +61,11 @@ public final class App {
// this endpoint. // this endpoint.
var channel = newGrpcConnection(); var channel = newGrpcConnection();
var builder = Gateway.newInstance().identity(newIdentity()).signer(newSigner()).connection(channel) var builder = Gateway.newInstance()
.identity(newIdentity())
.signer(newSigner())
.hash(Hash.SHA256)
.connection(channel)
// Default timeouts for different gRPC calls // Default timeouts for different gRPC calls
.evaluateOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS)) .evaluateOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS))
.endorseOptions(options -> options.withDeadlineAfter(15, TimeUnit.SECONDS)) .endorseOptions(options -> options.withDeadlineAfter(15, TimeUnit.SECONDS))

View file

@ -5,7 +5,7 @@
*/ */
const grpc = require('@grpc/grpc-js'); const grpc = require('@grpc/grpc-js');
const { connect, signers } = require('@hyperledger/fabric-gateway'); const { connect, hash, signers } = require('@hyperledger/fabric-gateway');
const crypto = require('node:crypto'); const crypto = require('node:crypto');
const fs = require('node:fs/promises'); const fs = require('node:fs/promises');
const path = require('node:path'); const path = require('node:path');
@ -79,6 +79,7 @@ async function main() {
client, client,
identity: await newIdentity(), identity: await newIdentity(),
signer: await newSigner(), signer: await newSigner(),
hash: hash.sha256,
// Default timeouts for different gRPC calls // Default timeouts for different gRPC calls
evaluateOptions: () => { evaluateOptions: () => {
return { deadline: Date.now() + 5000 }; // 5 seconds return { deadline: Date.now() + 5000 }; // 5 seconds

View file

@ -5,7 +5,7 @@
*/ */
import * as grpc from '@grpc/grpc-js'; import * as grpc from '@grpc/grpc-js';
import { connect, Contract, Identity, Signer, signers } from '@hyperledger/fabric-gateway'; import { connect, Contract, hash, Identity, Signer, signers } from '@hyperledger/fabric-gateway';
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import { promises as fs } from 'fs'; import { promises as fs } from 'fs';
import * as path from 'path'; import * as path from 'path';
@ -46,6 +46,7 @@ async function main(): Promise<void> {
client, client,
identity: await newIdentity(), identity: await newIdentity(),
signer: await newSigner(), signer: await newSigner(),
hash: hash.sha256,
// Default timeouts for different gRPC calls // Default timeouts for different gRPC calls
evaluateOptions: () => { evaluateOptions: () => {
return { deadline: Date.now() + 5000 }; // 5 seconds return { deadline: Date.now() + 5000 }; // 5 seconds

View file

@ -9,6 +9,7 @@ import (
"time" "time"
"github.com/hyperledger/fabric-gateway/pkg/client" "github.com/hyperledger/fabric-gateway/pkg/client"
"github.com/hyperledger/fabric-gateway/pkg/hash"
"github.com/hyperledger/fabric-gateway/pkg/identity" "github.com/hyperledger/fabric-gateway/pkg/identity"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
@ -24,6 +25,7 @@ func Initialize(setup OrgSetup) (*OrgSetup, error) {
gateway, err := client.Connect( gateway, err := client.Connect(
id, id,
client.WithSign(sign), client.WithSign(sign),
client.WithHash(hash.SHA256),
client.WithClientConnection(clientConnection), client.WithClientConnection(clientConnection),
client.WithEvaluateTimeout(5*time.Second), client.WithEvaluateTimeout(5*time.Second),
client.WithEndorseTimeout(15*time.Second), client.WithEndorseTimeout(15*time.Second),

View file

@ -15,6 +15,7 @@ import (
"time" "time"
"github.com/hyperledger/fabric-gateway/pkg/client" "github.com/hyperledger/fabric-gateway/pkg/client"
"github.com/hyperledger/fabric-gateway/pkg/hash"
) )
const ( const (
@ -35,6 +36,7 @@ func main() {
gateway, err := client.Connect( gateway, err := client.Connect(
id, id,
client.WithSign(sign), client.WithSign(sign),
client.WithHash(hash.SHA256),
client.WithClientConnection(clientConnection), client.WithClientConnection(clientConnection),
client.WithEvaluateTimeout(5*time.Second), client.WithEvaluateTimeout(5*time.Second),
client.WithEndorseTimeout(15*time.Second), client.WithEndorseTimeout(15*time.Second),

View file

@ -16,6 +16,7 @@ import org.hyperledger.fabric.client.Contract;
import org.hyperledger.fabric.client.EndorseException; import org.hyperledger.fabric.client.EndorseException;
import org.hyperledger.fabric.client.Gateway; import org.hyperledger.fabric.client.Gateway;
import org.hyperledger.fabric.client.GatewayRuntimeException; import org.hyperledger.fabric.client.GatewayRuntimeException;
import org.hyperledger.fabric.client.Hash;
import org.hyperledger.fabric.client.Network; import org.hyperledger.fabric.client.Network;
import org.hyperledger.fabric.client.SubmitException; import org.hyperledger.fabric.client.SubmitException;
@ -40,6 +41,7 @@ public final class App implements AutoCloseable {
var builder = Gateway.newInstance() var builder = Gateway.newInstance()
.identity(Connections.newIdentity()) .identity(Connections.newIdentity())
.signer(Connections.newSigner()) .signer(Connections.newSigner())
.hash(Hash.SHA256)
.connection(grpcChannel) .connection(grpcChannel)
.evaluateOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS)) .evaluateOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS))
.endorseOptions(options -> options.withDeadlineAfter(15, TimeUnit.SECONDS)) .endorseOptions(options -> options.withDeadlineAfter(15, TimeUnit.SECONDS))

View file

@ -5,7 +5,7 @@
*/ */
import * as grpc from '@grpc/grpc-js'; import * as grpc from '@grpc/grpc-js';
import { ChaincodeEvent, CloseableAsyncIterable, connect, Contract, GatewayError, Network } from '@hyperledger/fabric-gateway'; import { ChaincodeEvent, CloseableAsyncIterable, connect, Contract, GatewayError, hash, Network } from '@hyperledger/fabric-gateway';
import { TextDecoder } from 'util'; import { TextDecoder } from 'util';
import { newGrpcConnection, newIdentity, newSigner } from './connect'; import { newGrpcConnection, newIdentity, newSigner } from './connect';
@ -23,6 +23,7 @@ async function main(): Promise<void> {
client, client,
identity: await newIdentity(), identity: await newIdentity(),
signer: await newSigner(), signer: await newSigner(),
hash: hash.sha256,
evaluateOptions: () => { evaluateOptions: () => {
return { deadline: Date.now() + 5000 }; // 5 seconds return { deadline: Date.now() + 5000 }; // 5 seconds
}, },

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
import { connect, Contract } from '@hyperledger/fabric-gateway'; import { connect, Contract, hash } from '@hyperledger/fabric-gateway';
import { TextDecoder } from 'util'; import { TextDecoder } from 'util';
import { import {
certDirectoryPathOrg1, certDirectoryPathOrg2, keyDirectoryPathOrg1, keyDirectoryPathOrg2, newGrpcConnection, newIdentity, certDirectoryPathOrg1, certDirectoryPathOrg2, keyDirectoryPathOrg1, keyDirectoryPathOrg2, newGrpcConnection, newIdentity,
@ -41,6 +41,7 @@ async function main(): Promise<void> {
client: clientOrg1, client: clientOrg1,
identity: await newIdentity(certDirectoryPathOrg1, mspIdOrg1), identity: await newIdentity(certDirectoryPathOrg1, mspIdOrg1),
signer: await newSigner(keyDirectoryPathOrg1), signer: await newSigner(keyDirectoryPathOrg1),
hash: hash.sha256,
}); });
const clientOrg2 = await newGrpcConnection( const clientOrg2 = await newGrpcConnection(
@ -53,6 +54,7 @@ async function main(): Promise<void> {
client: clientOrg2, client: clientOrg2,
identity: await newIdentity(certDirectoryPathOrg2, mspIdOrg2), identity: await newIdentity(certDirectoryPathOrg2, mspIdOrg2),
signer: await newSigner(keyDirectoryPathOrg2), signer: await newSigner(keyDirectoryPathOrg2),
hash: hash.sha256,
}); });
try { try {

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
import { connect } from '@hyperledger/fabric-gateway'; import { connect, hash } from '@hyperledger/fabric-gateway';
import { newGrpcConnection, newIdentity, newSigner, tlsCertPathOrg1, peerEndpointOrg1, peerNameOrg1, certDirectoryPathOrg1, mspIdOrg1, keyDirectoryPathOrg1, tlsCertPathOrg2, peerEndpointOrg2, peerNameOrg2, certDirectoryPathOrg2, mspIdOrg2, keyDirectoryPathOrg2 } from './connect'; import { newGrpcConnection, newIdentity, newSigner, tlsCertPathOrg1, peerEndpointOrg1, peerNameOrg1, certDirectoryPathOrg1, mspIdOrg1, keyDirectoryPathOrg1, tlsCertPathOrg2, peerEndpointOrg2, peerNameOrg2, certDirectoryPathOrg2, mspIdOrg2, keyDirectoryPathOrg2 } from './connect';
import { ContractWrapper } from './contractWrapper'; import { ContractWrapper } from './contractWrapper';
@ -30,6 +30,7 @@ async function main(): Promise<void> {
client: clientOrg1, client: clientOrg1,
identity: await newIdentity(certDirectoryPathOrg1, mspIdOrg1), identity: await newIdentity(certDirectoryPathOrg1, mspIdOrg1),
signer: await newSigner(keyDirectoryPathOrg1), signer: await newSigner(keyDirectoryPathOrg1),
hash: hash.sha256,
}); });
// The gRPC client connection from org2 should be shared by all Gateway connections to this endpoint. // The gRPC client connection from org2 should be shared by all Gateway connections to this endpoint.
@ -43,6 +44,7 @@ async function main(): Promise<void> {
client: clientOrg2, client: clientOrg2,
identity: await newIdentity(certDirectoryPathOrg2, mspIdOrg2), identity: await newIdentity(certDirectoryPathOrg2, mspIdOrg2),
signer: await newSigner(keyDirectoryPathOrg2), signer: await newSigner(keyDirectoryPathOrg2),
hash: hash.sha256,
}); });

View file

@ -5,7 +5,7 @@
*/ */
import * as grpc from '@grpc/grpc-js'; import * as grpc from '@grpc/grpc-js';
import { connect, Gateway, Identity, Signer, signers } from '@hyperledger/fabric-gateway'; import { connect, Gateway, hash, Identity, Signer, signers } from '@hyperledger/fabric-gateway';
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
@ -34,6 +34,7 @@ export async function newGatewayConnection(client: grpc.Client): Promise<Gateway
client, client,
identity: await newIdentity(), identity: await newIdentity(),
signer: await newSigner(), signer: await newSigner(),
hash: hash.sha256,
// Default timeouts for different gRPC calls // Default timeouts for different gRPC calls
evaluateOptions: () => { evaluateOptions: () => {
return { deadline: Date.now() + 5000 }; // 5 seconds return { deadline: Date.now() + 5000 }; // 5 seconds

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
import { connect, Contract, Identity, Signer, signers } from '@hyperledger/fabric-gateway'; import { connect, Contract, hash } from '@hyperledger/fabric-gateway';
import * as path from 'path'; import * as path from 'path';
import { TextDecoder } from 'util'; import { TextDecoder } from 'util';
import { ConnectionHelper } from './fabric-connection-profile'; import { ConnectionHelper } from './fabric-connection-profile';
@ -12,9 +12,9 @@ import JSONIDAdapter from './jsonid-adapter';
import { dump } from 'js-yaml'; import { dump } from 'js-yaml';
import {config} from 'dotenv'; import { config } from 'dotenv';
import * as env from 'env-var';
config({path:'app.env'}); config({path:'app.env'});
import * as env from 'env-var'
const channelName = env.get('CHANNEL_NAME').default('mychannel').asString(); const channelName = env.get('CHANNEL_NAME').default('mychannel').asString();
const chaincodeName = env.get('CHAINCODE_NAME').default('conga-nft-contract').asString(); const chaincodeName = env.get('CHAINCODE_NAME').default('conga-nft-contract').asString();
@ -46,6 +46,7 @@ async function main(): Promise<void> {
client, client,
identity, identity,
signer, signer,
hash: hash.sha256,
// Default timeouts for different gRPC calls // Default timeouts for different gRPC calls
evaluateOptions: () => { evaluateOptions: () => {
return { deadline: Date.now() + 5000 }; // 5 seconds return { deadline: Date.now() + 5000 }; // 5 seconds
@ -95,4 +96,3 @@ async function ping(contract: Contract): Promise<void> {
console.log('*** Result:'); console.log('*** Result:');
console.log(dump(result)); console.log(dump(result));
} }

View file

@ -5,10 +5,9 @@
*/ */
import { Identity, Signer, signers } from '@hyperledger/fabric-gateway'; import { Identity, Signer, signers } from '@hyperledger/fabric-gateway';
import * as crypto from 'crypto';
import { promises as fs } from 'fs'; import { promises as fs } from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as crypto from 'crypto';
import { errorMonitor } from 'events';
/** Internal interface used to describe all the possible components /** Internal interface used to describe all the possible components
* of the identity * of the identity

View file

@ -1,5 +1,5 @@
import * as grpc from '@grpc/grpc-js'; import * as grpc from '@grpc/grpc-js';
import { connect, Contract, Identity, Signer, signers } from '@hyperledger/fabric-gateway'; import { connect, Contract, hash, Identity, Signer, signers } from '@hyperledger/fabric-gateway';
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import * as path from 'path'; import * as path from 'path';
@ -37,6 +37,7 @@ async function initFabric(): Promise<void> {
client, client,
identity: await newIdentity(), identity: await newIdentity(),
signer: await newSigner(), signer: await newSigner(),
hash: hash.sha256,
// Default timeouts for different gRPC calls // Default timeouts for different gRPC calls
evaluateOptions: () => { evaluateOptions: () => {
return { deadline: Date.now() + 5000 }; // 5 seconds return { deadline: Date.now() + 5000 }; // 5 seconds

View file

@ -5,7 +5,7 @@
*/ */
import * as grpc from '@grpc/grpc-js'; import * as grpc from '@grpc/grpc-js';
import { connect, Gateway, Identity, Signer, signers } from '@hyperledger/fabric-gateway'; import { connect, Gateway, hash, Identity, Signer, signers } from '@hyperledger/fabric-gateway';
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
@ -34,6 +34,7 @@ export async function newGatewayConnection(client: grpc.Client): Promise<Gateway
client, client,
identity: await newIdentity(), identity: await newIdentity(),
signer: await newSigner(), signer: await newSigner(),
hash: hash.sha256,
// Default timeouts for different gRPC calls // Default timeouts for different gRPC calls
evaluateOptions: () => { evaluateOptions: () => {
return { deadline: Date.now() + 5000 }; // 5 seconds return { deadline: Date.now() + 5000 }; // 5 seconds

View file

@ -24,6 +24,7 @@ import (
"time" "time"
"github.com/hyperledger/fabric-gateway/pkg/client" "github.com/hyperledger/fabric-gateway/pkg/client"
"github.com/hyperledger/fabric-gateway/pkg/hash"
"github.com/hyperledger/fabric-gateway/pkg/identity" "github.com/hyperledger/fabric-gateway/pkg/identity"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
@ -63,7 +64,8 @@ func main() {
defer hsmSignClose() defer hsmSignClose()
// Create a Gateway connection for a specific client identity // Create a Gateway connection for a specific client identity
gateway, err := client.Connect(id, client.WithSign(hsmSign), client.WithClientConnection(clientConnection)) gateway, err := client.Connect(id, client.WithSign(hsmSign), client.WithHash(hash.SHA256),
client.WithClientConnection(clientConnection))
if err != nil { if err != nil {
panic(err) panic(err)
} }

View file

@ -5,7 +5,7 @@
*/ */
import * as grpc from '@grpc/grpc-js'; import * as grpc from '@grpc/grpc-js';
import { connect, Gateway, HSMSigner, HSMSignerFactory, HSMSignerOptions, signers } from '@hyperledger/fabric-gateway'; import { connect, Gateway, hash, HSMSigner, HSMSignerFactory, HSMSignerOptions, signers } from '@hyperledger/fabric-gateway';
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
@ -46,6 +46,7 @@ async function main() {
client, client,
identity: { mspId, credentials }, identity: { mspId, credentials },
signer:hsmSigner.signer, signer:hsmSigner.signer,
hash: hash.sha256,
}); });
await exampleTransaction(gateway); await exampleTransaction(gateway);

View file

@ -9,6 +9,7 @@ import io.grpc.Grpc;
import io.grpc.ManagedChannel; import io.grpc.ManagedChannel;
import io.grpc.TlsChannelCredentials; import io.grpc.TlsChannelCredentials;
import org.hyperledger.fabric.client.Gateway; import org.hyperledger.fabric.client.Gateway;
import org.hyperledger.fabric.client.Hash;
import org.hyperledger.fabric.client.identity.Identities; import org.hyperledger.fabric.client.identity.Identities;
import org.hyperledger.fabric.client.identity.Identity; import org.hyperledger.fabric.client.identity.Identity;
import org.hyperledger.fabric.client.identity.Signer; import org.hyperledger.fabric.client.identity.Signer;
@ -86,6 +87,7 @@ public final class Connections {
return Gateway.newInstance() return Gateway.newInstance()
.identity(newIdentity()) .identity(newIdentity())
.signer(newSigner()) .signer(newSigner())
.hash(Hash.SHA256)
.connection(grpcChannel) .connection(grpcChannel)
.evaluateOptions(options -> options.withDeadlineAfter(EVALUATE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) .evaluateOptions(options -> options.withDeadlineAfter(EVALUATE_TIMEOUT_SECONDS, TimeUnit.SECONDS))
.endorseOptions(options -> options.withDeadlineAfter(ENDORSE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) .endorseOptions(options -> options.withDeadlineAfter(ENDORSE_TIMEOUT_SECONDS, TimeUnit.SECONDS))

View file

@ -5,7 +5,7 @@
*/ */
import * as grpc from '@grpc/grpc-js'; import * as grpc from '@grpc/grpc-js';
import { ConnectOptions, Identity, Signer, signers } from '@hyperledger/fabric-gateway'; import { ConnectOptions, hash, Identity, Signer, signers } from '@hyperledger/fabric-gateway';
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import { promises as fs } from 'fs'; import { promises as fs } from 'fs';
import * as path from 'path'; import * as path from 'path';
@ -47,6 +47,7 @@ export async function newConnectOptions(client: grpc.Client): Promise<ConnectOpt
client, client,
identity: await newIdentity(), identity: await newIdentity(),
signer: await newSigner(), signer: await newSigner(),
hash: hash.sha256,
// Default timeouts for different gRPC calls // Default timeouts for different gRPC calls
evaluateOptions: () => { evaluateOptions: () => {
return { deadline: Date.now() + 5000 }; // 5 seconds return { deadline: Date.now() + 5000 }; // 5 seconds