@tdxvolt/volt-client-grpc 0.16.0-beta.9 → 0.18.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.
@@ -1,16 +1,19 @@
1
1
  /* eslint-disable no-underscore-dangle */
2
2
  import debug from "debug";
3
3
  import fs from "fs";
4
- import forge from "node-forge";
5
- import jwt from "jsonwebtoken";
6
- import crypto from "crypto";
7
- import * as voltUtils from "./utils.js";
8
4
  import { constants } from "./constants.js";
5
+ import { voltUtils as voltClientUtils } from "@tdxvolt/volt-client-web/js";
6
+
7
+ const {
8
+ createSigningKey,
9
+ fingerprintFromPem,
10
+ getIdentityToken,
11
+ keyFromPem,
12
+ privateKeyToPem,
13
+ publicKeyToPem
14
+ } = voltClientUtils;
9
15
 
10
- const { pki } = forge;
11
16
  const log = debug("volt-client-grpc:volt-credential");
12
- const aesAlgorithm = "aes-256-cbc";
13
- const rs256Algorithm = "RS256";
14
17
 
15
18
  export class VoltCredential {
16
19
  constructor(config, configPath) {
@@ -34,14 +37,13 @@ export class VoltCredential {
34
37
  }
35
38
 
36
39
  // Need to unencrypt the private key.
37
- const decrypted = pki.decryptRsaPrivateKey(
38
- this._cryptoCache.key,
39
- config.p
40
- );
40
+ const decrypted = keyFromPem(this._cryptoCache.key, config.p);
41
+
41
42
  if (!decrypted) {
42
43
  throw new Error("failed to decrypt key - check passphrase");
43
44
  }
44
- this._cryptoCache.key = pki.privateKeyToPem(decrypted);
45
+
46
+ this._cryptoCache.key = privateKeyToPem(decrypted.privateKey);
45
47
  }
46
48
 
47
49
  if (this._voltConfig.ca_pem) {
@@ -50,14 +52,11 @@ export class VoltCredential {
50
52
  this._cryptoCache.ca = this._voltConfig.ca_pem;
51
53
  }
52
54
 
53
- // Pre-cache the target Volt public key by extracting it from the signing certificate.
54
- const voltCert = forge.pki.certificateFromPem(this._voltConfig.ca_pem);
55
-
56
55
  // Extract Volt public key (used for encrypting Relay payloads).
57
- this._voltPublicKey = forge.pki.publicKeyToPem(voltCert.publicKey);
58
- this._voltFingerprint = voltUtils.createPublicKeyFingerprint(
59
- this._voltPublicKey
60
- );
56
+ this._voltPublicKey = this._voltConfig.public_key;
57
+
58
+ const voltKey = keyFromPem(this._voltPublicKey).publicKey;
59
+ this._voltFingerprint = fingerprintFromPem(voltKey);
61
60
  }
62
61
  }
63
62
 
@@ -78,7 +77,7 @@ export class VoltCredential {
78
77
  }
79
78
 
80
79
  get identityId() {
81
- return this._cryptoCache.identity_id;
80
+ return this._cryptoCache.identity_did;
82
81
  }
83
82
 
84
83
  get voltPublicKey() {
@@ -86,7 +85,7 @@ export class VoltCredential {
86
85
  }
87
86
 
88
87
  get publicKey() {
89
- return pki.publicKeyToPem(this.getKey().publicKey);
88
+ return publicKeyToPem(this.getKey().publicKey);
90
89
  }
91
90
 
92
91
  get voltFingerprint() {
@@ -94,9 +93,8 @@ export class VoltCredential {
94
93
  }
95
94
 
96
95
  getKey() {
97
- const privateKey = pki.privateKeyFromPem(this._cryptoCache.key);
98
- const publicKey = pki.rsa.setPublicKey(privateKey.n, privateKey.e);
99
- return { privateKey, publicKey };
96
+ const key = keyFromPem(this._cryptoCache.key);
97
+ return key;
100
98
  }
101
99
 
102
100
  /**
@@ -109,17 +107,10 @@ export class VoltCredential {
109
107
  return Promise.resolve(this.getKey());
110
108
  } else {
111
109
  log("creating key");
112
- return voltUtils
113
- .createRSAKey()
114
- .then((keyInfo) => {
115
- log("successfully created key");
116
- this._cryptoCache.key = keyInfo.pem;
117
- return keyInfo.keypair;
118
- })
119
- .catch((err) => {
120
- log("failure creating key [%s]", err.message);
121
- return Promise.reject(err);
122
- });
110
+ this._cryptoCache.key = createSigningKey();
111
+ const key = keyFromPem(this._cryptoCache.key);
112
+ log("successfully created key");
113
+ return Promise.resolve(key);
123
114
  }
124
115
  }
125
116
 
@@ -144,55 +135,6 @@ export class VoltCredential {
144
135
  return !!this._cryptoCache.cert;
145
136
  }
146
137
 
147
- /**
148
- * Signs the identity resource id using the private key.
149
- * @param {*} audience the token audience (usually the target volt)
150
- * @param {*} tunnelling flag indicating if the token is required for a tunnelled connection
151
- * @param {*} ttl time to live in seconds (default to 1 minute)
152
- */
153
- getIdentityToken(audience, publicKey, tunnelling = false, ttl = 60) {
154
- if (!this._cryptoCache.key) {
155
- throw new Error("crypto cache invalid");
156
- }
157
-
158
- const keyPair = this.getKey();
159
- const publicKeyPem = pki.publicKeyToPem(keyPair.publicKey);
160
- const base58Key = voltUtils.createPublicKeyFingerprint(publicKeyPem);
161
-
162
- log("base58 key is %s", base58Key);
163
-
164
- // Allow TTL either side of the current time.
165
- // @todo - fix with server time sync on volt connection.
166
- const payload = {
167
- aud: audience,
168
- iat: Math.floor(Date.now() / 1000) - ttl,
169
- exp: Math.floor(Date.now() / 1000) + ttl,
170
- sub: this._cryptoCache.session_id
171
- };
172
-
173
- let sharedKey;
174
- if (tunnelling) {
175
- // Initialise the Relay encryption key.
176
- sharedKey = VoltCredential.aesCreateKey();
177
-
178
- // Encrypt the key details using the target Volt public key and include this in the JWT payload.
179
- payload.sk = VoltCredential.rsaEncrypt(publicKey, sharedKey.key);
180
- payload.iv = VoltCredential.rsaEncrypt(publicKey, sharedKey.iv);
181
- }
182
-
183
- // Sign synchronously.
184
- const token = jwt.sign(payload, this._cryptoCache.key, {
185
- algorithm: rs256Algorithm,
186
- keyid: base58Key
187
- });
188
-
189
- // Return the token along with any encryption key details.
190
- return {
191
- token,
192
- sharedKey
193
- };
194
- }
195
-
196
138
  /**
197
139
  * Creates the metadata required for a grpc call, including the Volt authentication token
198
140
  * and optionally tunnel encryption parameters.
@@ -203,9 +145,12 @@ export class VoltCredential {
203
145
  * @returns
204
146
  */
205
147
  getIdentityMetadata(grpc, audience, publicKey, tunnelling = false, ttl = 60) {
206
- const identityToken = this.getIdentityToken(
148
+ const key = keyFromPem(this._cryptoCache.key);
149
+
150
+ const identityToken = getIdentityToken(
151
+ this.sessionId,
152
+ key,
207
153
  audience || this._voltConfig.id,
208
- publicKey,
209
154
  tunnelling,
210
155
  ttl
211
156
  );
@@ -215,47 +160,17 @@ export class VoltCredential {
215
160
  }
216
161
 
217
162
  saveCache() {
163
+ const clone = { ...this._config, credential: { ...this._cryptoCache } };
164
+ if (this._config.p) {
165
+ // A passphrase option exists => encrypt the key before writing the cache file.
166
+ const key = keyFromPem(this._cryptoCache.key);
167
+ clone.credential.key = privateKeyToPem(key.privateKey, this._config.p);
168
+ }
169
+
218
170
  if (this._persistCache) {
219
- const clone = { ...this._config, credential: { ...this._cryptoCache } };
220
- if (this._config.p) {
221
- // A passphrase option exists => encrypt the key before writing the cache file.
222
- const privateKey = pki.privateKeyFromPem(this._cryptoCache.key);
223
- clone.credential.key = pki.encryptRsaPrivateKey(
224
- privateKey,
225
- this._config.p
226
- );
227
- }
228
171
  fs.writeFileSync(this._configPath, JSON.stringify(clone, null, 2));
229
172
  }
230
- }
231
-
232
- static aesCreateKey() {
233
- // Generate random key for the AES-256 algorithm (32 bytes = 256 bits).
234
- const key = crypto.randomBytes(32);
235
- const iv = crypto.randomBytes(16);
236
- return { key, iv };
237
- }
238
-
239
- static aesEncrypt(buffer, key, iv) {
240
- const cipher = crypto.createCipheriv(aesAlgorithm, key, iv);
241
- const crypted = Buffer.concat([cipher.update(buffer), cipher.final()]);
242
- return crypted;
243
- }
244
-
245
- static aesDecrypt(buffer, key, iv) {
246
- const cipher = crypto.createDecipheriv(aesAlgorithm, key, iv);
247
- const decrypted = Buffer.concat([cipher.update(buffer), cipher.final()]);
248
- return decrypted;
249
- }
250
-
251
- static rsaEncrypt(key, buffer) {
252
- const cipher = crypto.publicEncrypt(key, buffer);
253
- return cipher.toString("base64url");
254
- }
255
173
 
256
- static rsaDecrypt(key, buffer) {
257
- const keyObj = crypto.createPrivateKey(key);
258
- const cipher = Buffer.from(buffer, "base64url");
259
- return Buffer.from(crypto.privateDecrypt(keyObj, cipher));
174
+ return clone;
260
175
  }
261
176
  }