node-firebird 2.0.2 → 2.3.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/lib/srp.js CHANGED
@@ -1,20 +1,19 @@
1
- var BigInt = require('big-integer'),
2
- crypto = require('crypto');
1
+ var crypto = require('crypto');
3
2
 
4
3
  const SRP_KEY_SIZE = 128,
5
4
  SRP_KEY_MAX = BigInt('340282366920938463463374607431768211456'), // 1 << SRP_KEY_SIZE
6
5
  SRP_SALT_SIZE = 32;
7
6
 
8
7
  const DEBUG = false;
9
- const DEBUG_PRIVATE_KEY = BigInt('84316857F47914F838918D5C12CE3A3E7A9B2D7C9486346809E9EEFCE8DE7CD4259D8BE4FD0BCC2D259553769E078FA61EE2977025E4DA42F7FD97914D8A33723DFAFBC00770B7DA0C2E3778A05790F0C0F33C32A19ED88A12928567749021B3FD45DCD1CE259C45325067E3DDC972F87867349BA82C303CCCAA9B207218007B', 16);
8
+ const DEBUG_PRIVATE_KEY = BigInt('0x84316857F47914F838918D5C12CE3A3E7A9B2D7C9486346809E9EEFCE8DE7CD4259D8BE4FD0BCC2D259553769E078FA61EE2977025E4DA42F7FD97914D8A33723DFAFBC00770B7DA0C2E3778A05790F0C0F33C32A19ED88A12928567749021B3FD45DCD1CE259C45325067E3DDC972F87867349BA82C303CCCAA9B207218007B');
10
9
 
11
10
  /**
12
11
  * Prime values.
13
12
  *
14
- * @type {{g: (bigInt.BigInteger), k: (bigInt.BigInteger), N: (bigInt.BigInteger)}}
13
+ * @type {{g: BigInt, k: BigInt, N: BigInt}}
15
14
  */
16
15
  const PRIME = {
17
- N: BigInt('E67D2E994B2F900C3F41F08F5BB2627ED0D49EE1FE767A52EFCD565CD6E768812C3E1E9CE8F0A8BEA6CB13CD29DDEBF7A96D4A93B55D488DF099A15C89DCB0640738EB2CBDD9A8F7BAB561AB1B0DC1C6CDABF303264A08D1BCA932D1F1EE428B619D970F342ABA9A65793B8B2F041AE5364350C16F735F56ECBCA87BD57B29E7', 16),
16
+ N: BigInt('0xE67D2E994B2F900C3F41F08F5BB2627ED0D49EE1FE767A52EFCD565CD6E768812C3E1E9CE8F0A8BEA6CB13CD29DDEBF7A96D4A93B55D488DF099A15C89DCB0640738EB2CBDD9A8F7BAB561AB1B0DC1C6CDABF303264A08D1BCA932D1F1EE428B619D970F342ABA9A65793B8B2F041AE5364350C16F735F56ECBCA87BD57B29E7'),
18
17
  g: BigInt(2),
19
18
  k: BigInt('1277432915985975349439481660349303019122249719989')
20
19
  };
@@ -22,11 +21,11 @@ const PRIME = {
22
21
  /**
23
22
  * Generate a client key pair.
24
23
  *
25
- * @param a bigInt.BigInteger Client private key.
26
- * @returns {{private: bigInt.BigInteger, public: bigInt.BigInteger}}
24
+ * @param a BigInt Client private key.
25
+ * @returns {{private: BigInt, public: BigInt}}
27
26
  */
28
27
  exports.clientSeed = function(a = toBigInt(crypto.randomBytes(SRP_KEY_SIZE))) {
29
- var A = PRIME.g.modPow(a, PRIME.N);
28
+ var A = modPow(PRIME.g, a, PRIME.N);
30
29
 
31
30
  dump('a', a);
32
31
  dump('A', A);
@@ -42,15 +41,15 @@ exports.clientSeed = function(a = toBigInt(crypto.randomBytes(SRP_KEY_SIZE))) {
42
41
  *
43
42
  * @param user string Connection username.
44
43
  * @param password string Connection password.
45
- * @param salt bigInt.BigInteger Connection salt.
46
- * @param b bigInt.BigInteger Server private key.
47
- * @returns {{private: bigInt.BigInteger, public: bigInt.BigInteger}}
44
+ * @param salt BigInt Connection salt.
45
+ * @param b BigInt Server private key.
46
+ * @returns {{private: BigInt, public: BigInt}}
48
47
  */
49
48
  exports.serverSeed = function(user, password, salt, b = toBigInt(crypto.randomBytes(SRP_KEY_SIZE))) {
50
49
  var v = getVerifier(user, password, salt);
51
- var gb = PRIME.g.modPow(b, PRIME.N);
52
- var kv = PRIME.k.multiply(v).mod(PRIME.N);
53
- var B = kv.add(gb).mod(PRIME.N);
50
+ var gb = modPow(PRIME.g, b, PRIME.N);
51
+ var kv = (PRIME.k * v) % PRIME.N;
52
+ var B = (kv + gb) % PRIME.N;
54
53
 
55
54
  dump('v', v);
56
55
  dump('b', b);
@@ -69,24 +68,24 @@ exports.serverSeed = function(user, password, salt, b = toBigInt(crypto.randomBy
69
68
  *
70
69
  * @param user string Connection username.
71
70
  * @param password string Connection password.
72
- * @param salt bigInt.BigInteger Connection salt.
73
- * @param A bigInt.BigInteger Client public key.
74
- * @param B bigInt.BigInteger Server public key.
75
- * @param b bigInt.BigInteger Server private key.
76
- * @returns {bigInt.BigInteger}
71
+ * @param salt BigInt Connection salt.
72
+ * @param A BigInt Client public key.
73
+ * @param B BigInt Server public key.
74
+ * @param b BigInt Server private key.
75
+ * @returns {BigInt}
77
76
  */
78
77
  exports.serverSession = function(user, password, salt, A, B, b) {
79
78
  var u = getScramble(A, B);
80
79
  var v = getVerifier(user, password, salt);
81
- var vu = v.modPow(u, PRIME.N);
82
- var Avu = A.multiply(vu).mod(PRIME.N);
83
- var sessionSecret = Avu.modPow(b, PRIME.N);
80
+ var vu = modPow(v, u, PRIME.N);
81
+ var Avu = (A * vu) % PRIME.N;
82
+ var sessionSecret = modPow(Avu, b, PRIME.N);
84
83
  var K = getHash('sha1', toBuffer(sessionSecret));
85
84
 
86
85
  dump('server sessionSecret', sessionSecret);
87
86
  dump('server K', K);
88
87
 
89
- return BigInt(K, 16);
88
+ return BigInt('0x' + K);
90
89
  };
91
90
 
92
91
  /**
@@ -102,7 +101,7 @@ exports.clientProof = function(user, password, salt, A, B, a, hashAlgo) {
102
101
  dump('n1', n1);
103
102
  dump('n2', n2);
104
103
 
105
- n1 = n1.modPow(n2, PRIME.N);
104
+ n1 = modPow(n1, n2, PRIME.N);
106
105
  n2 = toBigInt(getHash('sha1', user));
107
106
  var M = toBigInt(getHash(hashAlgo, toBuffer(n1), toBuffer(n2), salt, toBuffer(A), toBuffer(B), toBuffer(K)));
108
107
 
@@ -147,12 +146,12 @@ function pad(n) {
147
146
  /**
148
147
  * Scramble keys.
149
148
  *
150
- * @param A bigInt.BigInteger Client public key.
151
- * @param B bigInt.BigInteger Server public key.
152
- * @returns {bigInt.BigInteger}
149
+ * @param A BigInt Client public key.
150
+ * @param B BigInt Server public key.
151
+ * @returns {BigInt}
153
152
  */
154
153
  function getScramble(A, B) {
155
- return BigInt(getHash('sha1', pad(A), pad(B)), 16);
154
+ return BigInt('0x' + getHash('sha1', pad(A), pad(B)));
156
155
  }
157
156
 
158
157
  /**
@@ -165,28 +164,28 @@ function getScramble(A, B) {
165
164
  *
166
165
  * @param user string Connection username.
167
166
  * @param password string Connection password.
168
- * @param salt bigInt.BigInteger Connection salt.
169
- * @param A bigInt.BigInteger Client public key.
170
- * @param B bigInt.BigInteger Server public key.
171
- * @param a bigInt.BigInteger Client private key.
167
+ * @param salt BigInt Connection salt.
168
+ * @param A BigInt Client public key.
169
+ * @param B BigInt Server public key.
170
+ * @param a BigInt Client private key.
172
171
  */
173
172
  function clientSession(user, password, salt, A, B, a) {
174
173
  var u = getScramble(A, B);
175
174
  var x = getUserHash(user, salt, password);
176
- var gx = PRIME.g.modPow(x, PRIME.N);
177
- var kgx = PRIME.k.multiply(gx).mod(PRIME.N);
178
- var diff = B.subtract(kgx).mod(PRIME.N);
175
+ var gx = modPow(PRIME.g, x, PRIME.N);
176
+ var kgx = (PRIME.k * gx) % PRIME.N;
177
+ var diff = (B - kgx) % PRIME.N;
179
178
 
180
- if (diff.lesser(0)) {
181
- diff = diff.add(PRIME.N);
179
+ if (diff < 0n) {
180
+ diff = diff + PRIME.N;
182
181
  }
183
182
 
184
183
  // Note: While the SRP specification says exponents should not be reduced mod N,
185
184
  // the Firebird engine implementation does reduce these exponents mod N.
186
185
  // We must match the server's behavior for authentication to succeed.
187
- var ux = u.multiply(x).mod(PRIME.N);
188
- var aux = a.add(ux).mod(PRIME.N);
189
- var sessionSecret = diff.modPow(aux, PRIME.N);
186
+ var ux = (u * x) % PRIME.N;
187
+ var aux = (a + ux) % PRIME.N;
188
+ var sessionSecret = modPow(diff, aux, PRIME.N);
190
189
  var K = toBigInt(getHash('sha1', toBuffer(sessionSecret)));
191
190
 
192
191
  dump('B', B);
@@ -207,9 +206,9 @@ function clientSession(user, password, salt, A, B, a) {
207
206
  * Compute user hash.
208
207
  *
209
208
  * @param user string Connection username.
210
- * @param salt bigInt.BigInteger Connection salt.
209
+ * @param salt BigInt Connection salt.
211
210
  * @param password string Connection password.
212
- * @returns {bigInt.BigInteger}
211
+ * @returns {BigInt}
213
212
  */
214
213
  function getUserHash(user, salt, password) {
215
214
  var hash1 = getHash('sha1', user.toUpperCase(), ':', password);
@@ -223,11 +222,11 @@ function getUserHash(user, salt, password) {
223
222
  *
224
223
  * @param user string Connection username.
225
224
  * @param password string Connection password.
226
- * @param salt bigInt.BigInteger Connection salt.
227
- * @returns {bigInt.BigInteger}
225
+ * @param salt BigInt Connection salt.
226
+ * @returns {BigInt}
228
227
  */
229
228
  function getVerifier(user, password, salt) {
230
- return PRIME.g.modPow(getUserHash(user, salt, password), PRIME.N);
229
+ return modPow(PRIME.g, getUserHash(user, salt, password), PRIME.N);
231
230
  }
232
231
 
233
232
  /**
@@ -254,17 +253,17 @@ function getHash(algo, ...data) {
254
253
  * @returns {*}
255
254
  */
256
255
  function toBuffer(bigInt) {
257
- return Buffer.from(BigInt.isInstance(bigInt) ? hexPad(bigInt.toString(16)) : bigInt, 'hex');
256
+ return Buffer.from(typeof bigInt === 'bigint' ? hexPad(bigInt.toString(16)) : bigInt, 'hex');
258
257
  }
259
258
 
260
259
  /**
261
260
  * Convert hex buffer or string to BigInt.
262
261
  *
263
262
  * @param hex
264
- * @returns {bigInt.BigInteger}
263
+ * @returns {BigInt}
265
264
  */
266
265
  function toBigInt(hex) {
267
- return BigInt(Buffer.isBuffer(hex) ? hex.toString('hex') : hex, 16);
266
+ return BigInt('0x' + (Buffer.isBuffer(hex) ? hex.toString('hex') : hex));
268
267
  }
269
268
 
270
269
  /**
@@ -275,10 +274,26 @@ function toBigInt(hex) {
275
274
  */
276
275
  function dump(key, value) {
277
276
  if (DEBUG) {
278
- if (BigInt.isInstance(value)) {
277
+ if (typeof value === 'bigint') {
279
278
  value = value.toString(16);
280
279
  }
281
280
 
282
281
  console.log(key + '=' + value);
283
282
  }
284
- }
283
+ }
284
+
285
+ /**
286
+ * Calculates (base ^ exp) % mod using native BigInt.
287
+ */
288
+ function modPow(base, exp, mod) {
289
+ let result = 1n;
290
+ base = base % mod;
291
+ while (exp > 0n) {
292
+ if (exp & 1n) {
293
+ result = (result * base) % mod;
294
+ }
295
+ base = (base * base) % mod;
296
+ exp >>= 1n;
297
+ }
298
+ return result;
299
+ }