Skip to content

Commit

Permalink
Remove dev dependency on jsrsasign (#626)
Browse files Browse the repository at this point in the history
Refactor generation of key identifiers for hardware security module configuration in Node scenario tests to use Node crypto library, avoiding the need for dependency on jsrsasign.

Signed-off-by: Mark S. Lewis <[email protected]>
  • Loading branch information
bestbeforetoday authored Sep 4, 2023
1 parent 7496598 commit 5fe4c4f
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 24 deletions.
2 changes: 0 additions & 2 deletions scenario/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,12 @@
"devDependencies": {
"@cucumber/cucumber": "^9.3.0",
"@tsconfig/node16": "^16.1.0",
"@types/jsrsasign": "^10.5.8",
"@types/node": "^16.18.39",
"@typescript-eslint/eslint-plugin": "^6.2.1",
"@typescript-eslint/parser": "^6.2.1",
"cucumber-console-formatter": "^1.0.0",
"eslint": "^8.46.0",
"expect": "^29.6.2",
"jsrsasign": "^10.8.6",
"npm-run-all": "^4.1.5",
"typescript": "~5.1.6"
}
Expand Down
13 changes: 7 additions & 6 deletions scenario/node/src/customworld.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
import { DataTable, setWorldConstructor } from '@cucumber/cucumber';
import * as grpc from '@grpc/grpc-js';
import { ChaincodeEvent, HSMSigner, HSMSignerFactory, HSMSignerOptions, Identity, Signer, signers } from '@hyperledger/fabric-gateway';
import * as crypto from 'crypto';
import { KeyObject, X509Certificate, createPrivateKey } from 'crypto';
import { promises as fs } from 'fs';
import * as path from 'path';
import { findSoftHSMPKCS11Lib, fixturesDir, getOrgForMsp } from './fabric';
import { getSKIFromCertificate } from './fabricski';
import { GatewayContext } from './gatewaycontext';
import { TransactionInvocation } from './transactioninvocation';
import { assertDefined, Constructor, isInstanceOf } from './utils';
import { Constructor, assertDefined, isInstanceOf } from './utils';

let hsmSignerFactory: HSMSignerFactory;

Expand Down Expand Up @@ -78,11 +78,11 @@ async function newSigner(user: string, mspId: string): Promise<Signer> {
return signers.newPrivateKeySigner(privateKey);
}

async function readPrivateKey(user: string, mspId: string): Promise<crypto.KeyObject> {
async function readPrivateKey(user: string, mspId: string): Promise<KeyObject> {
const credentialsPath = getCredentialsPath(user, mspId);
const keyPath = path.join(credentialsPath, 'keystore', 'key.pem');
const privateKeyPem = await fs.readFile(keyPath);
return crypto.createPrivateKey(privateKeyPem);
return createPrivateKey(privateKeyPem);
}

function getCredentialsPath(user: string, mspId: string): string {
Expand All @@ -104,8 +104,9 @@ async function newHSMSigner(user: string): Promise<HSMSigner> {
hsmSignerFactory = signers.newHSMSignerFactory(findSoftHSMPKCS11Lib());
}

const certificate = await readHSMCertificate(user);
const ski = getSKIFromCertificate(certificate.toString());
const certificatePem = await readHSMCertificate(user);
const certificate = new X509Certificate(certificatePem);
const ski = getSKIFromCertificate(certificate);
const hsmConfigOptions: HSMSignerOptions = {
label: 'ForFabric',
pin: '98765432',
Expand Down
32 changes: 16 additions & 16 deletions scenario/node/src/fabricski.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import * as crypto from 'crypto';
import * as jsrsa from 'jsrsasign';
/*
* Copyright IBM Corp. All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/

export function getSKIFromCertificate(pem: string): Buffer {
const key = jsrsa.KEYUTIL.getKey(pem);
const uncompressedPoint = getUncompressedPointOnCurve(key as jsrsa.KJUR.crypto.ECDSA);
const hashBuffer = crypto.createHash('sha256');
hashBuffer.update(uncompressedPoint);
import { KeyObject, X509Certificate, createHash } from 'node:crypto';
import { assertDefined } from './utils';

const digest = hashBuffer.digest('hex');
return Buffer.from(digest, 'hex');
export function getSKIFromCertificate(certificate: X509Certificate): Buffer {
const uncompressedPoint = getUncompressedPointOnCurve(certificate.publicKey);
return createHash('sha256').update(uncompressedPoint).digest();
}

function getUncompressedPointOnCurve(key: jsrsa.KJUR.crypto.ECDSA): Buffer {
const xyhex = key.getPublicKeyXYHex();
const xBuffer = Buffer.from(xyhex.x, 'hex');
const yBuffer = Buffer.from(xyhex.y, 'hex');
const uncompressedPrefix = Buffer.from('04', 'hex');
const uncompressedPoint = Buffer.concat([uncompressedPrefix, xBuffer, yBuffer]);
return uncompressedPoint;
function getUncompressedPointOnCurve(key: KeyObject): Buffer {
const jwk = key.export({ format: 'jwk' });
const x = Buffer.from(assertDefined(jwk.x, 'x'), 'base64url');
const y = Buffer.from(assertDefined(jwk.y, 'y'), 'base64url');
const prefix = Buffer.from('04', 'hex');
return Buffer.concat([prefix, x, y]);
}

0 comments on commit 5fe4c4f

Please sign in to comment.