node-firebird 0.9.9 → 1.1.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/serialize.js CHANGED
@@ -111,11 +111,11 @@ BlrWriter.prototype.addBuffer = function (b) {
111
111
 
112
112
  BlrWriter.prototype.addString2 = function (c, s, encoding) {
113
113
  this.addByte(c);
114
-
114
+
115
115
  var len = Buffer.byteLength(s, encoding);
116
116
  if (len > MAX_STRING_SIZE* MAX_STRING_SIZE)
117
117
  throw new Error('blr string is too big');
118
-
118
+
119
119
  this.ensure(len + 2);
120
120
  this.buffer.writeUInt16LE(len, this.pos);
121
121
  this.pos += 2;
@@ -135,6 +135,7 @@ BlrWriter.prototype.addMultiblockPart = function (c, s, encoding) {
135
135
  this.addByte(toWrite + 1);
136
136
  this.addByte(step);
137
137
 
138
+ this.ensure(toWrite);
138
139
  buff.copy(this.buffer, this.pos, step * 254, (step * 254) + toWrite);
139
140
 
140
141
  step++;
package/lib/srp.js ADDED
@@ -0,0 +1,281 @@
1
+ var BigInt = require('big-integer'),
2
+ crypto = require('crypto');
3
+
4
+ const SRP_KEY_SIZE = 128,
5
+ SRP_KEY_MAX = BigInt('340282366920938463463374607431768211456'), // 1 << SRP_KEY_SIZE
6
+ SRP_SALT_SIZE = 32;
7
+
8
+ const DEBUG = false;
9
+ const DEBUG_PRIVATE_KEY = BigInt('84316857F47914F838918D5C12CE3A3E7A9B2D7C9486346809E9EEFCE8DE7CD4259D8BE4FD0BCC2D259553769E078FA61EE2977025E4DA42F7FD97914D8A33723DFAFBC00770B7DA0C2E3778A05790F0C0F33C32A19ED88A12928567749021B3FD45DCD1CE259C45325067E3DDC972F87867349BA82C303CCCAA9B207218007B', 16);
10
+
11
+ /**
12
+ * Prime values.
13
+ *
14
+ * @type {{g: (bigInt.BigInteger), k: (bigInt.BigInteger), N: (bigInt.BigInteger)}}
15
+ */
16
+ const PRIME = {
17
+ N: BigInt('E67D2E994B2F900C3F41F08F5BB2627ED0D49EE1FE767A52EFCD565CD6E768812C3E1E9CE8F0A8BEA6CB13CD29DDEBF7A96D4A93B55D488DF099A15C89DCB0640738EB2CBDD9A8F7BAB561AB1B0DC1C6CDABF303264A08D1BCA932D1F1EE428B619D970F342ABA9A65793B8B2F041AE5364350C16F735F56ECBCA87BD57B29E7', 16),
18
+ g: BigInt(2),
19
+ k: BigInt('1277432915985975349439481660349303019122249719989')
20
+ };
21
+
22
+ /**
23
+ * Generate a client key pair.
24
+ *
25
+ * @param a bigInt.BigInteger Client private key.
26
+ * @returns {{private: bigInt.BigInteger, public: bigInt.BigInteger}}
27
+ */
28
+ exports.clientSeed = function(a = toBigInt(crypto.randomBytes(SRP_KEY_SIZE))) {
29
+ var A = PRIME.g.modPow(a, PRIME.N);
30
+
31
+ dump('a', a);
32
+ dump('A', A);
33
+
34
+ return {
35
+ public: A,
36
+ private: a
37
+ };
38
+ }
39
+
40
+ /**
41
+ * Generate a server key pair.
42
+ *
43
+ * @param user string Connection username.
44
+ * @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}}
48
+ */
49
+ exports.serverSeed = function(user, password, salt, b = toBigInt(crypto.randomBytes(SRP_KEY_SIZE))) {
50
+ 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);
54
+
55
+ dump('v', v);
56
+ dump('b', b);
57
+ dump('gb', b);
58
+ dump('kv', v);
59
+ dump('B', B);
60
+
61
+ return {
62
+ public: B,
63
+ private: b
64
+ };
65
+ }
66
+
67
+ /**
68
+ * Server session secret.
69
+ *
70
+ * @param user string Connection username.
71
+ * @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}
77
+ */
78
+ exports.serverSession = function(user, password, salt, A, B, b) {
79
+ var u = getScramble(A, B);
80
+ 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);
84
+ var K = getHash('sha1', toBuffer(sessionSecret));
85
+
86
+ dump('server sessionSecret', sessionSecret);
87
+ dump('server K', K);
88
+
89
+ return BigInt(K, 16);
90
+ };
91
+
92
+ /**
93
+ * M = H(H(N) xor H(g), H(I), s, A, B, K)
94
+ */
95
+ exports.clientProof = function(user, password, salt, A, B, a, hashAlgo) {
96
+ var K = clientSession(user, password, salt, A, B, a);
97
+ var n1, n2;
98
+
99
+ n1 = toBigInt(getHash('sha1', toBuffer(PRIME.N)));
100
+ n2 = toBigInt(getHash('sha1', toBuffer(PRIME.g)));
101
+
102
+ dump('n1', n1);
103
+ dump('n2', n2);
104
+
105
+ n1 = n1.modPow(n2, PRIME.N);
106
+ n2 = toBigInt(getHash('sha1', user));
107
+ var M = toBigInt(getHash(hashAlgo, toBuffer(n1), toBuffer(n2), salt, toBuffer(A), toBuffer(B), toBuffer(K)));
108
+
109
+ dump('n1-2', n1);
110
+ dump('n2-2', n2);
111
+ dump('proof:M', M);
112
+
113
+ return {
114
+ clientSessionKey: K,
115
+ authData: M,
116
+ };
117
+ }
118
+
119
+ /**
120
+ * Pad hex string.
121
+ */
122
+ function hexPad(hex) {
123
+ if (hex.length % 2 !== 0) {
124
+ hex = '0' + hex;
125
+ }
126
+
127
+ return hex;
128
+ }
129
+ exports.hexPad = hexPad;
130
+
131
+ /**
132
+ * Pad key with SRP_KEY_SIZE.
133
+ *
134
+ * @param n BigInt Key to pad.
135
+ * @returns Buffer
136
+ */
137
+ function pad(n) {
138
+ var buff = Buffer.from(hexPad(n.toString(16)), 'hex');
139
+
140
+ if (buff.length > SRP_KEY_SIZE) {
141
+ buff = buff.slice(buff.length - SRP_KEY_SIZE, buff.length);
142
+ }
143
+
144
+ return buff;
145
+ }
146
+
147
+ /**
148
+ * Scramble keys.
149
+ *
150
+ * @param A bigInt.BigInteger Client public key.
151
+ * @param B bigInt.BigInteger Server public key.
152
+ * @returns {bigInt.BigInteger}
153
+ */
154
+ function getScramble(A, B) {
155
+ return BigInt(getHash('sha1', pad(A), pad(B)), 16);
156
+ }
157
+
158
+ /**
159
+ * Client session secret.
160
+ *
161
+ * Both: u = H(A, B)
162
+ * User: x = H(s, p) (user enters password)
163
+ * User: S = (B - kg^x) ^ (a + ux) (computes session key)
164
+ * User: K = H(S)
165
+ *
166
+ * @param user string Connection username.
167
+ * @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.
172
+ */
173
+ function clientSession(user, password, salt, A, B, a) {
174
+ var u = getScramble(A, B);
175
+ 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);
179
+
180
+ if (diff.lesser(0)) {
181
+ diff = diff.add(PRIME.N);
182
+ }
183
+
184
+ var ux = u.multiply(x).mod(PRIME.N);
185
+ var aux = a.add(ux).mod(PRIME.N);
186
+ var sessionSecret = diff.modPow(aux, PRIME.N);
187
+ var K = toBigInt(getHash('sha1', toBuffer(sessionSecret)));
188
+
189
+ dump('B', B);
190
+ dump('u', u);
191
+ dump('x', x);
192
+ dump('gx', gx);
193
+ dump('kgx', kgx);
194
+ dump('diff', diff);
195
+ dump('ux', ux);
196
+ dump('aux', aux);
197
+ dump('sessionSecret', sessionSecret);
198
+ dump('sessionKey(K)', K);
199
+
200
+ return K;
201
+ }
202
+
203
+ /**
204
+ * Compute user hash.
205
+ *
206
+ * @param user string Connection username.
207
+ * @param salt bigInt.BigInteger Connection salt.
208
+ * @param password string Connection password.
209
+ * @returns {bigInt.BigInteger}
210
+ */
211
+ function getUserHash(user, salt, password) {
212
+ var hash1 = getHash('sha1', user.toUpperCase(), ':', password);
213
+ var hash2 = getHash('sha1', salt, toBuffer(hash1));
214
+
215
+ return toBigInt(hash2);
216
+ }
217
+
218
+ /**
219
+ * Verifier of user hash.
220
+ *
221
+ * @param user string Connection username.
222
+ * @param password string Connection password.
223
+ * @param salt bigInt.BigInteger Connection salt.
224
+ * @returns {bigInt.BigInteger}
225
+ */
226
+ function getVerifier(user, password, salt) {
227
+ return PRIME.g.modPow(getUserHash(user, salt, password), PRIME.N);
228
+ }
229
+
230
+ /**
231
+ * Hash data and return hex string.
232
+ *
233
+ * @param algo string Algorithm to use.
234
+ * @param data any[] Data to hash.
235
+ * @returns {string}
236
+ */
237
+ function getHash(algo, ...data) {
238
+ var hash = crypto.createHash(algo);
239
+
240
+ for (var d of data) {
241
+ hash.update(d);
242
+ }
243
+
244
+ return hash.digest('hex');
245
+ }
246
+
247
+ /**
248
+ * Convert BigInt to buffer.
249
+ *
250
+ * @param bigInt
251
+ * @returns {*}
252
+ */
253
+ function toBuffer(bigInt) {
254
+ return Buffer.from(BigInt.isInstance(bigInt) ? hexPad(bigInt.toString(16)) : bigInt, 'hex');
255
+ }
256
+
257
+ /**
258
+ * Convert hex buffer or string to BigInt.
259
+ *
260
+ * @param hex
261
+ * @returns {bigInt.BigInteger}
262
+ */
263
+ function toBigInt(hex) {
264
+ return BigInt(Buffer.isBuffer(hex) ? hex.toString('hex') : hex, 16);
265
+ }
266
+
267
+ /**
268
+ * Dump value in debug mode.
269
+ *
270
+ * @param key
271
+ * @param value
272
+ */
273
+ function dump(key, value) {
274
+ if (DEBUG) {
275
+ if (BigInt.isInstance(value)) {
276
+ value = value.toString(16);
277
+ }
278
+
279
+ console.log(key + '=' + value);
280
+ }
281
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-firebird",
3
- "version": "0.9.9",
3
+ "version": "1.1.0",
4
4
  "description": "Pure JavaScript and Asynchronous Firebird client for Node.js.",
5
5
  "keywords": [
6
6
  "firebird",
@@ -33,6 +33,7 @@
33
33
  "test": "mocha"
34
34
  },
35
35
  "dependencies": {
36
+ "big-integer": "^1.6.48",
36
37
  "long": "^4.0.0"
37
38
  },
38
39
  "devDependencies": {
@@ -1,47 +0,0 @@
1
- # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
- # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3
-
4
- name: Node.js Package
5
-
6
- on:
7
- release:
8
- types: [created]
9
-
10
- jobs:
11
- build:
12
- runs-on: ubuntu-latest
13
- steps:
14
- - uses: actions/checkout@v2
15
- - uses: actions/setup-node@v1
16
- with:
17
- node-version: 12
18
- - run: npm ci
19
- - run: npm test
20
-
21
- publish-npm:
22
- needs: build
23
- runs-on: ubuntu-latest
24
- steps:
25
- - uses: actions/checkout@v2
26
- - uses: actions/setup-node@v1
27
- with:
28
- node-version: 12
29
- registry-url: https://registry.npmjs.org/
30
- - run: npm ci
31
- - run: npm publish
32
- env:
33
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}
34
-
35
- publish-gpr:
36
- needs: build
37
- runs-on: ubuntu-latest
38
- steps:
39
- - uses: actions/checkout@v2
40
- - uses: actions/setup-node@v1
41
- with:
42
- node-version: 12
43
- registry-url: https://npm.pkg.github.com/
44
- - run: npm ci
45
- - run: npm publish
46
- env:
47
- NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
package/git DELETED
File without changes