Skip to content

Commit

Permalink
Update TypeScript HSM sample application
Browse files Browse the repository at this point in the history
- Update to Node 16.
- Simplify SKI code using Node standard packages and avoiding use of jsrsasign.

Signed-off-by: Mark S. Lewis <[email protected]>
  • Loading branch information
bestbeforetoday committed Sep 7, 2023
1 parent f2c1c59 commit 1bd3f70
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 31 deletions.
18 changes: 8 additions & 10 deletions hardware-security-module/application-typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "",
"main": "dist/hsm-sample.js",
"engines": {
"node": ">=14"
"node": ">=16"
},
"scripts": {
"build": "tsc",
Expand All @@ -17,18 +17,16 @@
"author": "",
"license": "Apache-2.0",
"dependencies": {
"@hyperledger/fabric-gateway": "^1.1.1",
"jsrsasign": "^10.3.0"
"@hyperledger/fabric-gateway": "^1.1.1"
},
"devDependencies": {
"@tsconfig/node14": "^1.0.1",
"@types/jsrsasign": "^9.0.3",
"@types/node": "^14.17.32",
"@typescript-eslint/eslint-plugin": "^5.3.0",
"@typescript-eslint/parser": "^5.3.0",
"@tsconfig/node16": "^16.1.1",
"@types/node": "^16.18.48",
"@typescript-eslint/eslint-plugin": "^6.6.0",
"@typescript-eslint/parser": "^6.6.0",
"eslint": "^8.1.0",
"npm-run-all": "^4.1.5",
"rimraf": "^3.0.2",
"typescript": "~4.5.4"
"rimraf": "^5.0.1",
"typescript": "~5.2.2"
}
}
42 changes: 22 additions & 20 deletions hardware-security-module/application-typescript/src/hsm-sample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
*/

import * as grpc from '@grpc/grpc-js';
import * as crypto from 'crypto';
import { connect, Gateway, HSMSigner, HSMSignerFactory, HSMSignerOptions, signers } from '@hyperledger/fabric-gateway';
import * as crypto from 'crypto';
import * as fs from 'fs';
import * as jsrsa from 'jsrsasign';
import * as path from 'path';
import { TextDecoder } from 'util';

Expand Down Expand Up @@ -42,7 +41,7 @@ async function main() {

// Get the signer function and a close function. The close function closes the signer
// once there is no further need for it.
hsmSigner = await newHSMSigner(hsmSignerFactory, credentials.toString());
hsmSigner = newHSMSigner(hsmSignerFactory, credentials);
gateway = connect({
client,
identity: { mspId, credentials },
Expand Down Expand Up @@ -100,8 +99,9 @@ async function newGrpcConnection(): Promise<grpc.Client> {
}

// Create a new HSM Signer
async function newHSMSigner(hsmSignerFactory: HSMSignerFactory, certificatePEM: string): Promise<HSMSigner> {
const ski = getSKIFromCertificate(certificatePEM);
function newHSMSigner(hsmSignerFactory: HSMSignerFactory, certificatePEM: Buffer): HSMSigner {
const certificate = new crypto.X509Certificate(certificatePEM);
const ski = getSKIFromCertificate(certificate);

// Options for the signer based on using SoftHSM with Token initialized as follows
// softhsm2-util --init-token --slot 0 --label "ForFabric" --pin 98765432 --so-pin 1234
Expand Down Expand Up @@ -139,23 +139,25 @@ function findSoftHSMPKCS11Lib(): string {
// fabric-ca-client set's the CKA_ID of the public/private keys in the HSM to a generated SKI
// value. This function replicates that calculation from a certificate PEM so that the HSM
// object associated with the certificate can be found
function getSKIFromCertificate(certificatePEM: string): Buffer {
const key = jsrsa.KEYUTIL.getKey(certificatePEM);
const uncompressedPoint = getUncompressedPointOnCurve(key as jsrsa.KJUR.crypto.ECDSA);
const hashBuffer = crypto.createHash('sha256');
hashBuffer.update(uncompressedPoint);

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

function getUncompressedPointOnCurve(key: crypto.KeyObject): Buffer {
const jwk = key.export({ format: 'jwk' });
const x = Buffer.from(assertDefined(jwk.x), 'base64url');
const y = Buffer.from(assertDefined(jwk.y), 'base64url');
const prefix = Buffer.from('04', 'hex');
return Buffer.concat([prefix, x, y]);
}

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 assertDefined<T>(value: T | undefined): T {
if (value === undefined) {
throw new Error('required value was undefined');
}

return value;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@tsconfig/node14/tsconfig.json",
"extends": "@tsconfig/node16/tsconfig.json",
"compilerOptions": {
"declaration": true,
"declarationMap": true,
Expand Down

0 comments on commit 1bd3f70

Please sign in to comment.