@cef-ebsi/cli 1.3.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +1 -1
- package/dist/abi/pilot/DidRegistry.js +568 -0
- package/dist/abi/pilot/DidRegistry.js.map +1 -0
- package/dist/abi/{test/TirV4.js → pilot/Ptr.js} +255 -299
- package/dist/abi/pilot/Ptr.js.map +1 -0
- package/dist/abi/pilot/SchemaSCRegistry.js +264 -0
- package/dist/abi/pilot/SchemaSCRegistry.js.map +1 -0
- package/dist/abi/{test/TprV3.js → pilot/Tcr.js} +269 -261
- package/dist/abi/pilot/Tcr.js.map +1 -0
- package/dist/abi/pilot/Timestamp.js +658 -0
- package/dist/abi/pilot/Timestamp.js.map +1 -0
- package/dist/abi/pilot/Tir.js +428 -0
- package/dist/abi/pilot/Tir.js.map +1 -0
- package/dist/abi/pilot/TnT.js +842 -0
- package/dist/abi/pilot/TnT.js.map +1 -0
- package/dist/abi/pilot/Tpr.js +492 -0
- package/dist/abi/pilot/Tpr.js.map +1 -0
- package/dist/abi/test/DidRegistry.js +144 -658
- package/dist/abi/test/DidRegistry.js.map +1 -1
- package/dist/abi/{pilot/TirV4.js → test/Ptr.js} +255 -299
- package/dist/abi/test/Ptr.js.map +1 -0
- package/dist/abi/test/SchemaSCRegistry.js +122 -795
- package/dist/abi/test/SchemaSCRegistry.js.map +1 -1
- package/dist/abi/{pilot/TprV3.js → test/Tcr.js} +269 -261
- package/dist/abi/test/Tcr.js.map +1 -0
- package/dist/abi/test/Timestamp.js +239 -673
- package/dist/abi/test/Timestamp.js.map +1 -1
- package/dist/abi/test/Tir.js +167 -636
- package/dist/abi/test/Tir.js.map +1 -1
- package/dist/abi/test/TnT.js +842 -0
- package/dist/abi/test/TnT.js.map +1 -0
- package/dist/abi/test/Tpr.js +166 -942
- package/dist/abi/test/Tpr.js.map +1 -1
- package/dist/app.js +447 -443
- package/dist/app.js.map +1 -1
- package/dist/buildParam/{didV3.js → didr.js} +210 -204
- package/dist/buildParam/didr.js.map +1 -0
- package/dist/buildParam/index.js +42 -48
- package/dist/buildParam/index.js.map +1 -1
- package/dist/buildParam/ptr.js +80 -0
- package/dist/buildParam/ptr.js.map +1 -0
- package/dist/buildParam/tcr.js +36 -0
- package/dist/buildParam/tcr.js.map +1 -0
- package/dist/buildParam/{timestampV3.js → timestamp.js} +179 -136
- package/dist/buildParam/timestamp.js.map +1 -0
- package/dist/buildParam/{tirV3.js → tir.js} +67 -59
- package/dist/buildParam/tir.js.map +1 -0
- package/dist/buildParam/{tntV1.js → tnt.js} +90 -61
- package/dist/buildParam/tnt.js.map +1 -0
- package/dist/buildParam/{tprV2.js → tpr.js} +44 -33
- package/dist/buildParam/tpr.js.map +1 -0
- package/dist/buildParam/{tsrV2.js → tsr.js} +45 -40
- package/dist/buildParam/tsr.js.map +1 -0
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/{authorisation-v5.js → authorisation.js} +95 -72
- package/dist/commands/authorisation.js.map +1 -0
- package/dist/commands/compute.js +429 -389
- package/dist/commands/compute.js.map +1 -1
- package/dist/commands/{conformance-v3.js → conformance.js} +236 -248
- package/dist/commands/conformance.js.map +1 -0
- package/dist/commands/hardwarewallet.js +5 -5
- package/dist/commands/hardwarewallet.js.map +1 -1
- package/dist/commands/index.js +4 -4
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/{ledger-v4.js → ledger.js} +203 -127
- package/dist/commands/ledger.js.map +1 -0
- package/dist/commands/ptr.js +56 -0
- package/dist/commands/ptr.js.map +1 -0
- package/dist/commands/tcr.js +51 -0
- package/dist/commands/tcr.js.map +1 -0
- package/dist/commands/tnl.js +10 -9
- package/dist/commands/tnl.js.map +1 -1
- package/dist/commands/tsr.js +46 -0
- package/dist/commands/tsr.js.map +1 -0
- package/dist/commands/view.js +8 -8
- package/dist/commands/view.js.map +1 -1
- package/dist/config.js +311 -279
- package/dist/config.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/interfaces/index.js +1 -1
- package/dist/interfaces/index.js.map +1 -1
- package/dist/programs/migrateDid.js +33 -33
- package/dist/programs/migrateDid.js.map +1 -1
- package/dist/programs/migrateDids.js +39 -42
- package/dist/programs/migrateDids.js.map +1 -1
- package/dist/programs/migrateTsr.js +153 -113
- package/dist/programs/migrateTsr.js.map +1 -1
- package/dist/scripts/accreditAndAuthorize/conformance/step1 +1 -1
- package/dist/scripts/accreditAndAuthorize/test/step1 +1 -1
- package/dist/scripts/accreditTI +1 -1
- package/dist/scripts/assets/CTRevocableCredential.json +1 -1
- package/dist/scripts/assets/CredentialToAttestVerifiableAuthorisationForTrustChain.json +2 -2
- package/dist/scripts/assets/TrustedNodesList.json +1 -1
- package/dist/scripts/assets/VerifiableAccreditationToAccredit.json +2 -2
- package/dist/scripts/assets/VerifiableAccreditationToAttest.json +2 -2
- package/dist/scripts/assets/VerifiableAuthorisationForTrustChain.json +1 -1
- package/dist/scripts/assets/VerifiableAuthorisationToInvoke.json +24 -0
- package/dist/scripts/assets/VerifiableAuthorisationToOnboard.json +1 -1
- package/dist/scripts/bootstrap/1-populateTPR +18 -15
- package/dist/scripts/bootstrap/6-setupConformanceIssuer +1 -1
- package/dist/scripts/issueVcInvoke +10 -0
- package/dist/scripts/issueVcOnboard +1 -1
- package/dist/scripts/issueVcRootTAO +1 -1
- package/dist/scripts/issueVcTAO +2 -2
- package/dist/scripts/issueVcTI +2 -2
- package/dist/scripts/issueVcTnl +1 -1
- package/dist/scripts/issue_CTRevocableCredential +1 -1
- package/dist/scripts/issue_SelfAttestationSupportOffice +2 -2
- package/dist/scripts/issue_VerifiableAccreditationToAccredit +2 -2
- package/dist/scripts/issue_VerifiableAccreditationToAttest +2 -2
- package/dist/scripts/issue_VerifiableAuthorisationForTrustChain +1 -1
- package/dist/scripts/issue_VerifiableAuthorisationToOnboard +1 -1
- package/dist/scripts/updateVcRootTAO +1 -1
- package/dist/scripts/updateVcTAO +2 -2
- package/dist/scripts/updateVcTI +2 -2
- package/dist/scripts/{wctv3 → wct}/accreditAndAuthorize +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/utils/Client.js +81 -68
- package/dist/utils/Client.js.map +1 -1
- package/dist/utils/HardwareWallet.js +169 -165
- package/dist/utils/HardwareWallet.js.map +1 -1
- package/dist/utils/http.js +24 -27
- package/dist/utils/http.js.map +1 -1
- package/dist/utils/index.js +3 -3
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/jsonrpc.js +14 -14
- package/dist/utils/jsonrpc.js.map +1 -1
- package/dist/utils/print.js +19 -19
- package/dist/utils/print.js.map +1 -1
- package/dist/utils/utils.js +180 -173
- package/dist/utils/utils.js.map +1 -1
- package/package.json +70 -46
- package/dist/abi/pilot/DidRegistryV3.js +0 -1082
- package/dist/abi/pilot/DidRegistryV3.js.map +0 -1
- package/dist/abi/pilot/DidRegistryV4.js +0 -942
- package/dist/abi/pilot/DidRegistryV4.js.map +0 -1
- package/dist/abi/pilot/SchemaSCRegistryV2.js +0 -474
- package/dist/abi/pilot/SchemaSCRegistryV2.js.map +0 -1
- package/dist/abi/pilot/TimestampV2.js +0 -1128
- package/dist/abi/pilot/TimestampV2.js.map +0 -1
- package/dist/abi/pilot/TimestampV3.js +0 -995
- package/dist/abi/pilot/TimestampV3.js.map +0 -1
- package/dist/abi/pilot/TirV3.js +0 -496
- package/dist/abi/pilot/TirV3.js.map +0 -1
- package/dist/abi/pilot/TirV4.js.map +0 -1
- package/dist/abi/pilot/TnTV1.js +0 -1375
- package/dist/abi/pilot/TnTV1.js.map +0 -1
- package/dist/abi/pilot/TprV2.js +0 -889
- package/dist/abi/pilot/TprV2.js.map +0 -1
- package/dist/abi/pilot/TprV3.js.map +0 -1
- package/dist/abi/pilot/TsrV3.js +0 -571
- package/dist/abi/pilot/TsrV3.js.map +0 -1
- package/dist/abi/test/DidRegistryV3.js +0 -1089
- package/dist/abi/test/DidRegistryV3.js.map +0 -1
- package/dist/abi/test/DidRegistryV4.js +0 -960
- package/dist/abi/test/DidRegistryV4.js.map +0 -1
- package/dist/abi/test/SchemaSCRegistryV2.js +0 -474
- package/dist/abi/test/SchemaSCRegistryV2.js.map +0 -1
- package/dist/abi/test/TimestampV2.js +0 -1128
- package/dist/abi/test/TimestampV2.js.map +0 -1
- package/dist/abi/test/TimestampV3.js +0 -995
- package/dist/abi/test/TimestampV3.js.map +0 -1
- package/dist/abi/test/TirV3.js +0 -496
- package/dist/abi/test/TirV3.js.map +0 -1
- package/dist/abi/test/TirV4.js.map +0 -1
- package/dist/abi/test/TnTV1.js +0 -1375
- package/dist/abi/test/TnTV1.js.map +0 -1
- package/dist/abi/test/TprV2.js +0 -889
- package/dist/abi/test/TprV2.js.map +0 -1
- package/dist/abi/test/TprV3.js.map +0 -1
- package/dist/abi/test/TsrV3.js +0 -571
- package/dist/abi/test/TsrV3.js.map +0 -1
- package/dist/buildParam/didV3.js.map +0 -1
- package/dist/buildParam/didV4.js +0 -326
- package/dist/buildParam/didV4.js.map +0 -1
- package/dist/buildParam/timestampV2.js +0 -317
- package/dist/buildParam/timestampV2.js.map +0 -1
- package/dist/buildParam/timestampV3.js.map +0 -1
- package/dist/buildParam/tirV3.js.map +0 -1
- package/dist/buildParam/tirV4.js +0 -119
- package/dist/buildParam/tirV4.js.map +0 -1
- package/dist/buildParam/tntV1.js.map +0 -1
- package/dist/buildParam/tntV2.js +0 -185
- package/dist/buildParam/tntV2.js.map +0 -1
- package/dist/buildParam/tprV2.js.map +0 -1
- package/dist/buildParam/tprV3.js +0 -82
- package/dist/buildParam/tprV3.js.map +0 -1
- package/dist/buildParam/tsrV2.js.map +0 -1
- package/dist/buildParam/tsrV3.js +0 -110
- package/dist/buildParam/tsrV3.js.map +0 -1
- package/dist/commands/authorisation-v4.js +0 -119
- package/dist/commands/authorisation-v4.js.map +0 -1
- package/dist/commands/authorisation-v5.js.map +0 -1
- package/dist/commands/conformance-v3.js.map +0 -1
- package/dist/commands/ledger-v4.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- /package/dist/scripts/{wctv3 → wct}/holderWallet +0 -0
- /package/dist/scripts/{wctv3 → wct}/issueToHolder +0 -0
- /package/dist/scripts/{wctv3 → wct}/pda1 +0 -0
- /package/dist/scripts/{wctv3 → wct}/verifier +0 -0
package/dist/utils/Client.js
CHANGED
|
@@ -1,24 +1,16 @@
|
|
|
1
1
|
import { exportJWK, generateKeyPair, importJWK, SignJWT } from "jose";
|
|
2
|
-
import { encodePublicKey } from "./utils.js";
|
|
3
|
-
export async function generateKeys(alg) {
|
|
4
|
-
const keys = await generateKeyPair(alg);
|
|
5
|
-
return {
|
|
6
|
-
publicKeyJwk: await exportJWK(keys.publicKey),
|
|
7
|
-
privateKeyJwk: await exportJWK(keys.privateKey),
|
|
8
|
-
};
|
|
9
|
-
}
|
|
2
|
+
import { encodePrivateKey, encodePublicKey } from "./utils.js";
|
|
10
3
|
export class Client {
|
|
11
|
-
keys;
|
|
12
|
-
ethWallet;
|
|
13
|
-
hardwareWallet;
|
|
14
|
-
privateKeyHex;
|
|
15
|
-
did;
|
|
16
|
-
didVersion;
|
|
17
|
-
clientId;
|
|
18
4
|
accreditationId;
|
|
19
5
|
accreditationUrl;
|
|
20
|
-
|
|
6
|
+
clientId;
|
|
7
|
+
did;
|
|
8
|
+
didVersion;
|
|
9
|
+
ethWallet;
|
|
10
|
+
hardwareWallet;
|
|
21
11
|
issuerState;
|
|
12
|
+
keys;
|
|
13
|
+
proxyId;
|
|
22
14
|
constructor() {
|
|
23
15
|
this.keys = {};
|
|
24
16
|
}
|
|
@@ -26,26 +18,6 @@ export class Client {
|
|
|
26
18
|
const { privateKeyJwk } = await generateKeys(alg);
|
|
27
19
|
this.setJwk(alg, privateKeyJwk);
|
|
28
20
|
}
|
|
29
|
-
setJwk(alg, privateKeyJwk) {
|
|
30
|
-
const publicKeyJwk = encodePublicKey({
|
|
31
|
-
key: privateKeyJwk,
|
|
32
|
-
format: "jwk",
|
|
33
|
-
});
|
|
34
|
-
const publicKeyPem = encodePublicKey({
|
|
35
|
-
key: publicKeyJwk,
|
|
36
|
-
alg,
|
|
37
|
-
sourceType: "publicJwk",
|
|
38
|
-
format: "pem",
|
|
39
|
-
});
|
|
40
|
-
this.keys[alg] = {
|
|
41
|
-
id: "",
|
|
42
|
-
kid: "",
|
|
43
|
-
privateKeyJwk,
|
|
44
|
-
publicKeyJwk,
|
|
45
|
-
publicKeyPem,
|
|
46
|
-
isHardwareWallet: false,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
21
|
generateDidDocument() {
|
|
50
22
|
const context = [
|
|
51
23
|
"https://www.w3.org/ns/did/v1",
|
|
@@ -53,35 +25,87 @@ export class Client {
|
|
|
53
25
|
];
|
|
54
26
|
const didDocument = {
|
|
55
27
|
"@context": context,
|
|
56
|
-
id: this.did,
|
|
57
|
-
verificationMethod: [],
|
|
58
|
-
authentication: [],
|
|
59
28
|
assertionMethod: [],
|
|
29
|
+
authentication: [],
|
|
60
30
|
capabilityInvocation: [],
|
|
31
|
+
id: this.did,
|
|
32
|
+
verificationMethod: [],
|
|
61
33
|
};
|
|
62
|
-
Object.keys(this.keys)
|
|
34
|
+
for (const alg of Object.keys(this.keys)) {
|
|
63
35
|
const key = this.keys[alg];
|
|
64
36
|
if (!key)
|
|
65
|
-
|
|
37
|
+
continue;
|
|
66
38
|
didDocument.verificationMethod.push({
|
|
67
|
-
id: key.kid,
|
|
68
|
-
type: "JsonWebKey2020",
|
|
69
39
|
controller: this.did,
|
|
40
|
+
id: key.kid,
|
|
70
41
|
publicKeyJwk: key.publicKeyJwk,
|
|
42
|
+
type: "JsonWebKey2020",
|
|
71
43
|
});
|
|
72
44
|
didDocument.authentication.push(key.kid);
|
|
73
45
|
didDocument.assertionMethod.push(key.kid);
|
|
74
46
|
didDocument.capabilityInvocation.push(key.kid);
|
|
75
|
-
}
|
|
47
|
+
}
|
|
76
48
|
return didDocument;
|
|
77
49
|
}
|
|
50
|
+
privateKeysBase64() {
|
|
51
|
+
const keys = [];
|
|
52
|
+
for (const alg of Object.keys(this.keys)) {
|
|
53
|
+
const key = this.keys[alg];
|
|
54
|
+
if (!key)
|
|
55
|
+
continue;
|
|
56
|
+
keys.push({
|
|
57
|
+
alg,
|
|
58
|
+
id: key.kid,
|
|
59
|
+
privateKeyJwk: key.privateKeyJwk,
|
|
60
|
+
publicKeyJwk: key.publicKeyJwk,
|
|
61
|
+
type: "JsonWebKey2020",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return Buffer.from(JSON.stringify(keys)).toString("base64");
|
|
65
|
+
}
|
|
66
|
+
setJwk(alg, privateKeyJwk) {
|
|
67
|
+
const publicKeyJwk = encodePublicKey({
|
|
68
|
+
format: "jwk",
|
|
69
|
+
key: privateKeyJwk,
|
|
70
|
+
});
|
|
71
|
+
const publicKeyPem = encodePublicKey({
|
|
72
|
+
alg,
|
|
73
|
+
format: "pem",
|
|
74
|
+
key: publicKeyJwk,
|
|
75
|
+
sourceType: "publicJwk",
|
|
76
|
+
});
|
|
77
|
+
let publicKeyHex = "";
|
|
78
|
+
let privateKeyHex = "";
|
|
79
|
+
if (["ES256", "ES256K"].includes(alg)) {
|
|
80
|
+
privateKeyHex = encodePrivateKey({
|
|
81
|
+
alg,
|
|
82
|
+
format: "hex",
|
|
83
|
+
key: privateKeyJwk,
|
|
84
|
+
});
|
|
85
|
+
publicKeyHex = encodePublicKey({
|
|
86
|
+
alg,
|
|
87
|
+
format: "hex",
|
|
88
|
+
key: publicKeyJwk,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
this.keys[alg] = {
|
|
92
|
+
id: "",
|
|
93
|
+
isHardwareWallet: false,
|
|
94
|
+
kid: "",
|
|
95
|
+
...(privateKeyHex && { privateKeyHex }),
|
|
96
|
+
privateKeyJwk,
|
|
97
|
+
...(publicKeyHex && { publicKeyHex }),
|
|
98
|
+
publicKeyJwk,
|
|
99
|
+
publicKeyPem,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
78
102
|
async signJWT(payload, inputHeader, alg) {
|
|
79
103
|
if (!this.keys[alg])
|
|
80
104
|
throw new Error(`There is no key defined for alg ${alg}`);
|
|
81
105
|
const header = {
|
|
82
106
|
alg,
|
|
83
|
-
typ: "JWT",
|
|
84
107
|
kid: this.keys[alg].kid,
|
|
108
|
+
typ: "JWT",
|
|
85
109
|
...(this.didVersion === 2 && {
|
|
86
110
|
jwk: this.keys[alg].publicKeyJwk,
|
|
87
111
|
}),
|
|
@@ -98,37 +122,26 @@ export class Client {
|
|
|
98
122
|
.sign(privateKey);
|
|
99
123
|
return jwt;
|
|
100
124
|
}
|
|
101
|
-
privateKeysBase64() {
|
|
102
|
-
const keys = [];
|
|
103
|
-
Object.keys(this.keys).forEach((alg) => {
|
|
104
|
-
const key = this.keys[alg];
|
|
105
|
-
if (!key)
|
|
106
|
-
return;
|
|
107
|
-
keys.push({
|
|
108
|
-
type: "JsonWebKey2020",
|
|
109
|
-
id: key.kid,
|
|
110
|
-
alg,
|
|
111
|
-
privateKeyJwk: key.privateKeyJwk,
|
|
112
|
-
publicKeyJwk: key.publicKeyJwk,
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
return Buffer.from(JSON.stringify(keys)).toString("base64");
|
|
116
|
-
}
|
|
117
125
|
toJSON() {
|
|
118
126
|
return {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
publicKeyHex: this.ethWallet?.publicKey ?? "",
|
|
127
|
+
accreditationId: this.accreditationId,
|
|
128
|
+
accreditationUrl: this.accreditationUrl,
|
|
122
129
|
address: this.ethWallet?.address ?? "",
|
|
130
|
+
clientId: this.clientId,
|
|
123
131
|
did: this.did,
|
|
124
132
|
didVersion: this.didVersion,
|
|
125
|
-
clientId: this.clientId,
|
|
126
|
-
proxyId: this.proxyId,
|
|
127
|
-
accreditationId: this.accreditationId,
|
|
128
|
-
accreditationUrl: this.accreditationUrl,
|
|
129
133
|
issuerState: this.issuerState,
|
|
134
|
+
keys: this.keys,
|
|
135
|
+
proxyId: this.proxyId,
|
|
130
136
|
};
|
|
131
137
|
}
|
|
132
138
|
}
|
|
139
|
+
export async function generateKeys(alg) {
|
|
140
|
+
const keys = await generateKeyPair(alg);
|
|
141
|
+
return {
|
|
142
|
+
privateKeyJwk: await exportJWK(keys.privateKey),
|
|
143
|
+
publicKeyJwk: await exportJWK(keys.publicKey),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
133
146
|
export default Client;
|
|
134
147
|
//# sourceMappingURL=Client.js.map
|
package/dist/utils/Client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Client.js","sourceRoot":"","sources":["../../src/utils/Client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Client.js","sourceRoot":"","sources":["../../src/utils/Client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,48 +1,17 @@
|
|
|
1
1
|
import * as asn1 from "asn1js";
|
|
2
|
-
import * as pki from "pkijs";
|
|
3
|
-
import crypto from "crypto";
|
|
4
|
-
import { base64url } from "multiformats/bases/base64";
|
|
5
2
|
import Joi from "joi";
|
|
6
|
-
import {
|
|
3
|
+
import { base64url } from "multiformats/bases/base64";
|
|
4
|
+
import crypto from "node:crypto";
|
|
5
|
+
import * as pki from "pkijs";
|
|
6
|
+
import { red, yellow } from "./print.js";
|
|
7
7
|
import { askQuestion } from "./utils.js";
|
|
8
|
-
function convertRawSignatureToDER(rawSignature) {
|
|
9
|
-
if (rawSignature.length !== 64) {
|
|
10
|
-
throw new Error("Raw signature must be 64 bytes (32 bytes for r and 32 bytes for s)");
|
|
11
|
-
}
|
|
12
|
-
// Split raw signature into r and s
|
|
13
|
-
const r = rawSignature.subarray(0, 32);
|
|
14
|
-
const s = rawSignature.subarray(32);
|
|
15
|
-
// Function to add leading zero if needed
|
|
16
|
-
function toDERInteger(value) {
|
|
17
|
-
if (value[0] & 0x80) {
|
|
18
|
-
// If the first byte is >= 0x80, prepend 0x00 to indicate a positive integer
|
|
19
|
-
return Buffer.concat([Buffer.from([0x00]), value]);
|
|
20
|
-
}
|
|
21
|
-
return value;
|
|
22
|
-
}
|
|
23
|
-
// Convert r and s to DER integers
|
|
24
|
-
const rDER = toDERInteger(r);
|
|
25
|
-
const sDER = toDERInteger(s);
|
|
26
|
-
// Create DER-encoded SEQUENCE containing the r and s values
|
|
27
|
-
const derSignature = Buffer.concat([
|
|
28
|
-
Buffer.from([0x30]), // ASN.1 SEQUENCE tag
|
|
29
|
-
Buffer.from([rDER.length + sDER.length + 4]), // Total length of SEQUENCE
|
|
30
|
-
Buffer.from([0x02]), // ASN.1 INTEGER tag for r
|
|
31
|
-
Buffer.from([rDER.length]), // Length of r
|
|
32
|
-
rDER, // r value
|
|
33
|
-
Buffer.from([0x02]), // ASN.1 INTEGER tag for s
|
|
34
|
-
Buffer.from([sDER.length]), // Length of s
|
|
35
|
-
sDER, // s value
|
|
36
|
-
]);
|
|
37
|
-
return derSignature;
|
|
38
|
-
}
|
|
39
8
|
export class HardwareWallet {
|
|
40
9
|
graphene;
|
|
41
10
|
mod;
|
|
42
|
-
|
|
11
|
+
session;
|
|
43
12
|
slot;
|
|
44
13
|
slotNumber;
|
|
45
|
-
|
|
14
|
+
slots;
|
|
46
15
|
constructor(library) {
|
|
47
16
|
this.loadGraphene()
|
|
48
17
|
.then(() => {
|
|
@@ -52,69 +21,31 @@ export class HardwareWallet {
|
|
|
52
21
|
console.warn("Failed to load graphene-pk11");
|
|
53
22
|
});
|
|
54
23
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
init() {
|
|
63
|
-
if (!this.mod) {
|
|
64
|
-
throw new Error("Hardware wallet cannot be used because the graphene-pk11 package was not loaded");
|
|
65
|
-
}
|
|
66
|
-
this.endSession();
|
|
67
|
-
this.mod.initialize();
|
|
68
|
-
this.slotNumber = 0;
|
|
69
|
-
// get slots
|
|
70
|
-
this.slots = this.mod.getSlots(true);
|
|
71
|
-
if (this.slots.length === 0) {
|
|
72
|
-
this.mod.finalize();
|
|
73
|
-
throw new Error("No slots found. Make sure your Ledger is unlocked and the OpenPGP app is open.");
|
|
74
|
-
}
|
|
75
|
-
this.slot = this.slots.items(this.slotNumber);
|
|
76
|
-
if (!(this.slot.flags & this.graphene.SlotFlag.TOKEN_PRESENT)) {
|
|
77
|
-
this.mod.finalize();
|
|
78
|
-
throw new Error(`Slot ${this.slotNumber} is not initialized`);
|
|
79
|
-
}
|
|
80
|
-
this.session = this.slot.open(this.graphene.SessionFlag.RW_SESSION |
|
|
81
|
-
this.graphene.SessionFlag.SERIAL_SESSION);
|
|
24
|
+
static verify2(message, signature, publicKeyJwk) {
|
|
25
|
+
const derFormatSig = convertRawSignatureToDER(signature);
|
|
26
|
+
const isValid = crypto.verify("sha256", Buffer.from(message), {
|
|
27
|
+
format: "jwk",
|
|
28
|
+
key: publicKeyJwk,
|
|
29
|
+
}, derFormatSig);
|
|
30
|
+
return isValid;
|
|
82
31
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
validPin = true;
|
|
96
|
-
}
|
|
97
|
-
catch (error) {
|
|
98
|
-
validPin = false;
|
|
99
|
-
if (error instanceof Error) {
|
|
100
|
-
if (error.message === "CKR_PIN_LEN_RANGE") {
|
|
101
|
-
red("Invalid PIN length");
|
|
102
|
-
}
|
|
103
|
-
else if (error.message === "CKR_USER_NOT_LOGGED_IN") {
|
|
104
|
-
attemptsLeft -= 1;
|
|
105
|
-
red(`Invalid PIN. You have ${attemptsLeft} attempts before the PIN is locked`);
|
|
106
|
-
}
|
|
107
|
-
else if (error.message === "CKR_PIN_LOCKED") {
|
|
108
|
-
throw new Error(`The PIN is locked. If you want to reset it, open OpenPGP app, go to "Settings" > "Reset" and select "YES"`);
|
|
109
|
-
}
|
|
110
|
-
else if (error.message === "CKR_GENERAL_ERROR") {
|
|
111
|
-
throw new Error(`Hardware wallet error. Make sure your Ledger is unlocked and the OpenPGP app is open`);
|
|
112
|
-
}
|
|
113
|
-
throw error;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
32
|
+
static verifyJwt(jwt, publicKeyJwk) {
|
|
33
|
+
const jwtParts = jwt.split(".");
|
|
34
|
+
if (jwtParts.length !== 3)
|
|
35
|
+
throw new Error("Invalid JWT format");
|
|
36
|
+
const [headerBase64url, payloadBase64url, signatureBase64url] = jwtParts;
|
|
37
|
+
const message = `${headerBase64url}.${payloadBase64url}`;
|
|
38
|
+
const headerString = Buffer.from(base64url.baseDecode(headerBase64url)).toString();
|
|
39
|
+
const payloadString = Buffer.from(base64url.baseDecode(payloadBase64url)).toString();
|
|
40
|
+
const signature = Buffer.from(base64url.baseDecode(signatureBase64url));
|
|
41
|
+
const result = HardwareWallet.verify2(message, signature, publicKeyJwk);
|
|
42
|
+
if (!result) {
|
|
43
|
+
throw new Error("Invalid signature");
|
|
116
44
|
}
|
|
117
|
-
return
|
|
45
|
+
return {
|
|
46
|
+
header: JSON.parse(headerString),
|
|
47
|
+
payload: JSON.parse(payloadString),
|
|
48
|
+
};
|
|
118
49
|
}
|
|
119
50
|
endSession() {
|
|
120
51
|
try {
|
|
@@ -130,49 +61,6 @@ export class HardwareWallet {
|
|
|
130
61
|
// empty
|
|
131
62
|
}
|
|
132
63
|
}
|
|
133
|
-
async setPin(user) {
|
|
134
|
-
Joi.assert(user, Joi.string().valid("user", "admin"));
|
|
135
|
-
this.init();
|
|
136
|
-
const pin = await this.login(user, `Enter current pin for ${user}: `);
|
|
137
|
-
const newPin = await askQuestion("Enter new pin: ", true);
|
|
138
|
-
try {
|
|
139
|
-
this.session.setPin(pin, newPin);
|
|
140
|
-
this.endSession();
|
|
141
|
-
yellow(user === "user"
|
|
142
|
-
? "New pin configured!"
|
|
143
|
-
: "New pin configured for admin!");
|
|
144
|
-
}
|
|
145
|
-
catch (error) {
|
|
146
|
-
if (error instanceof Error) {
|
|
147
|
-
if (error.message === "CKR_PIN_LEN_RANGE") {
|
|
148
|
-
throw new Error("Invalid PIN length");
|
|
149
|
-
}
|
|
150
|
-
else if (error.message === "CKR_GENERAL_ERROR") {
|
|
151
|
-
throw new Error(`Hardware wallet error. Make sure your Ledger is unlocked and the OpenPGP app is open`);
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
throw error;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
getInfo() {
|
|
160
|
-
this.init();
|
|
161
|
-
const info = {
|
|
162
|
-
slot: this.slotNumber,
|
|
163
|
-
description: this.slot.slotDescription,
|
|
164
|
-
serial: this.slot.getToken().serialNumber,
|
|
165
|
-
password: {
|
|
166
|
-
min: this.slot.getToken().minPinLen,
|
|
167
|
-
max: this.slot.getToken().maxPinLen,
|
|
168
|
-
},
|
|
169
|
-
isHardware: Boolean(this.slot.flags & this.graphene.SlotFlag.HW_SLOT),
|
|
170
|
-
isRemovable: Boolean(this.slot.flags & this.graphene.SlotFlag.REMOVABLE_DEVICE),
|
|
171
|
-
isInitialized: Boolean(this.slot.flags & this.graphene.SlotFlag.TOKEN_PRESENT),
|
|
172
|
-
};
|
|
173
|
-
this.endSession();
|
|
174
|
-
return info;
|
|
175
|
-
}
|
|
176
64
|
async generateKeys() {
|
|
177
65
|
this.init();
|
|
178
66
|
await this.login("admin");
|
|
@@ -218,6 +106,23 @@ export class HardwareWallet {
|
|
|
218
106
|
yellow("Key pair generated successfully!");
|
|
219
107
|
this.endSession();
|
|
220
108
|
}
|
|
109
|
+
getInfo() {
|
|
110
|
+
this.init();
|
|
111
|
+
const info = {
|
|
112
|
+
description: this.slot.slotDescription,
|
|
113
|
+
isHardware: Boolean(this.slot.flags & this.graphene.SlotFlag.HW_SLOT),
|
|
114
|
+
isInitialized: Boolean(this.slot.flags & this.graphene.SlotFlag.TOKEN_PRESENT),
|
|
115
|
+
isRemovable: Boolean(this.slot.flags & this.graphene.SlotFlag.REMOVABLE_DEVICE),
|
|
116
|
+
password: {
|
|
117
|
+
max: this.slot.getToken().maxPinLen,
|
|
118
|
+
min: this.slot.getToken().minPinLen,
|
|
119
|
+
},
|
|
120
|
+
serial: this.slot.getToken().serialNumber,
|
|
121
|
+
slot: this.slotNumber,
|
|
122
|
+
};
|
|
123
|
+
this.endSession();
|
|
124
|
+
return info;
|
|
125
|
+
}
|
|
221
126
|
getPublicKey() {
|
|
222
127
|
this.init();
|
|
223
128
|
const publicKeys = this.session.find({
|
|
@@ -241,6 +146,100 @@ export class HardwareWallet {
|
|
|
241
146
|
this.endSession();
|
|
242
147
|
return { kty: "EC", ...publicKeyDecoded.toJSON() };
|
|
243
148
|
}
|
|
149
|
+
init() {
|
|
150
|
+
if (!this.mod) {
|
|
151
|
+
throw new Error("Hardware wallet cannot be used because the graphene-pk11 package was not loaded");
|
|
152
|
+
}
|
|
153
|
+
this.endSession();
|
|
154
|
+
this.mod.initialize();
|
|
155
|
+
this.slotNumber = 0;
|
|
156
|
+
// get slots
|
|
157
|
+
this.slots = this.mod.getSlots(true);
|
|
158
|
+
if (this.slots.length === 0) {
|
|
159
|
+
this.mod.finalize();
|
|
160
|
+
throw new Error("No slots found. Make sure your Ledger is unlocked and the OpenPGP app is open.");
|
|
161
|
+
}
|
|
162
|
+
this.slot = this.slots.items(this.slotNumber);
|
|
163
|
+
if (!(this.slot.flags & this.graphene.SlotFlag.TOKEN_PRESENT)) {
|
|
164
|
+
this.mod.finalize();
|
|
165
|
+
throw new Error(`Slot ${this.slotNumber} is not initialized`);
|
|
166
|
+
}
|
|
167
|
+
this.session = this.slot.open(this.graphene.SessionFlag.RW_SESSION |
|
|
168
|
+
this.graphene.SessionFlag.SERIAL_SESSION);
|
|
169
|
+
}
|
|
170
|
+
async loadGraphene() {
|
|
171
|
+
this.graphene = await import("graphene-pk11");
|
|
172
|
+
if (!this.graphene) {
|
|
173
|
+
throw new Error("Failed to load graphene-pk11");
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async login(userType, loginMessage) {
|
|
177
|
+
let attemptsLeft = 3;
|
|
178
|
+
const isAdmin = userType === "admin";
|
|
179
|
+
let pin = "";
|
|
180
|
+
let validPin = false;
|
|
181
|
+
let loginMsg = isAdmin ? "Enter admin pin: " : "Enter pin: ";
|
|
182
|
+
if (loginMessage)
|
|
183
|
+
loginMsg = loginMessage;
|
|
184
|
+
while (!validPin) {
|
|
185
|
+
try {
|
|
186
|
+
pin = await askQuestion(loginMsg, true);
|
|
187
|
+
this.session.login(pin, isAdmin ? this.graphene.UserType.SO : this.graphene.UserType.USER);
|
|
188
|
+
validPin = true;
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
validPin = false;
|
|
192
|
+
if (error instanceof Error) {
|
|
193
|
+
switch (error.message) {
|
|
194
|
+
case "CKR_PIN_LEN_RANGE": {
|
|
195
|
+
red("Invalid PIN length");
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
case "CKR_USER_NOT_LOGGED_IN": {
|
|
199
|
+
attemptsLeft -= 1;
|
|
200
|
+
red(`Invalid PIN. You have ${attemptsLeft} attempts before the PIN is locked`);
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
case "CKR_PIN_LOCKED": {
|
|
204
|
+
throw new Error(`The PIN is locked. If you want to reset it, open OpenPGP app, go to "Settings" > "Reset" and select "YES"`);
|
|
205
|
+
}
|
|
206
|
+
case "CKR_GENERAL_ERROR": {
|
|
207
|
+
throw new Error(`Hardware wallet error. Make sure your Ledger is unlocked and the OpenPGP app is open`);
|
|
208
|
+
}
|
|
209
|
+
// No default
|
|
210
|
+
}
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return pin;
|
|
216
|
+
}
|
|
217
|
+
async setPin(user) {
|
|
218
|
+
Joi.assert(user, Joi.string().valid("user", "admin"));
|
|
219
|
+
this.init();
|
|
220
|
+
const pin = await this.login(user, `Enter current pin for ${user}: `);
|
|
221
|
+
const newPin = await askQuestion("Enter new pin: ", true);
|
|
222
|
+
try {
|
|
223
|
+
this.session.setPin(pin, newPin);
|
|
224
|
+
this.endSession();
|
|
225
|
+
yellow(user === "user"
|
|
226
|
+
? "New pin configured!"
|
|
227
|
+
: "New pin configured for admin!");
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
if (error instanceof Error) {
|
|
231
|
+
if (error.message === "CKR_PIN_LEN_RANGE") {
|
|
232
|
+
throw new Error("Invalid PIN length");
|
|
233
|
+
}
|
|
234
|
+
else if (error.message === "CKR_GENERAL_ERROR") {
|
|
235
|
+
throw new Error(`Hardware wallet error. Make sure your Ledger is unlocked and the OpenPGP app is open`);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
244
243
|
async sign(message) {
|
|
245
244
|
this.init();
|
|
246
245
|
await this.login("user");
|
|
@@ -290,32 +289,37 @@ export class HardwareWallet {
|
|
|
290
289
|
this.endSession();
|
|
291
290
|
return isValid;
|
|
292
291
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
key: publicKeyJwk,
|
|
298
|
-
}, derFormatSig);
|
|
299
|
-
return isValid;
|
|
292
|
+
}
|
|
293
|
+
function convertRawSignatureToDER(rawSignature) {
|
|
294
|
+
if (rawSignature.length !== 64) {
|
|
295
|
+
throw new Error("Raw signature must be 64 bytes (32 bytes for r and 32 bytes for s)");
|
|
300
296
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
297
|
+
// Split raw signature into r and s
|
|
298
|
+
const r = rawSignature.subarray(0, 32);
|
|
299
|
+
const s = rawSignature.subarray(32);
|
|
300
|
+
// Convert r and s to DER integers
|
|
301
|
+
const rDER = toDERInteger(r);
|
|
302
|
+
const sDER = toDERInteger(s);
|
|
303
|
+
// Create DER-encoded SEQUENCE containing the r and s values
|
|
304
|
+
const derSignature = Buffer.concat([
|
|
305
|
+
Buffer.from([0x30]), // ASN.1 SEQUENCE tag
|
|
306
|
+
Buffer.from([rDER.length + sDER.length + 4]), // Total length of SEQUENCE
|
|
307
|
+
Buffer.from([0x02]), // ASN.1 INTEGER tag for r
|
|
308
|
+
Buffer.from([rDER.length]), // Length of r
|
|
309
|
+
rDER, // r value
|
|
310
|
+
Buffer.from([0x02]), // ASN.1 INTEGER tag for s
|
|
311
|
+
Buffer.from([sDER.length]), // Length of s
|
|
312
|
+
sDER, // s value
|
|
313
|
+
]);
|
|
314
|
+
return derSignature;
|
|
315
|
+
}
|
|
316
|
+
// Function to add leading zero if needed
|
|
317
|
+
function toDERInteger(value) {
|
|
318
|
+
if (value[0] & 0x80) {
|
|
319
|
+
// If the first byte is >= 0x80, prepend 0x00 to indicate a positive integer
|
|
320
|
+
return Buffer.concat([Buffer.from([0x00]), value]);
|
|
318
321
|
}
|
|
322
|
+
return value;
|
|
319
323
|
}
|
|
320
324
|
export default HardwareWallet;
|
|
321
325
|
//# sourceMappingURL=HardwareWallet.js.map
|