]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/utils.js
Adding integrated tile server
[simantics/district.git] / org.simantics.maps.server / node / node-v4.8.0-win-x64 / node_modules / npm / node_modules / request / node_modules / http-signature / node_modules / sshpk / lib / utils.js
1 // Copyright 2015 Joyent, Inc.
2
3 module.exports = {
4         bufferSplit: bufferSplit,
5         addRSAMissing: addRSAMissing,
6         calculateDSAPublic: calculateDSAPublic,
7         mpNormalize: mpNormalize,
8         ecNormalize: ecNormalize,
9         countZeros: countZeros,
10         assertCompatible: assertCompatible,
11         isCompatible: isCompatible,
12         opensslKeyDeriv: opensslKeyDeriv
13 };
14
15 var assert = require('assert-plus');
16 var PrivateKey = require('./private-key');
17 var crypto = require('crypto');
18
19 var MAX_CLASS_DEPTH = 3;
20
21 function isCompatible(obj, klass, needVer) {
22         if (obj === null || typeof (obj) !== 'object')
23                 return (false);
24         if (needVer === undefined)
25                 needVer = klass.prototype._sshpkApiVersion;
26         if (obj instanceof klass &&
27             klass.prototype._sshpkApiVersion[0] == needVer[0])
28                 return (true);
29         var proto = Object.getPrototypeOf(obj);
30         var depth = 0;
31         while (proto.constructor.name !== klass.name) {
32                 proto = Object.getPrototypeOf(proto);
33                 if (!proto || ++depth > MAX_CLASS_DEPTH)
34                         return (false);
35         }
36         if (proto.constructor.name !== klass.name)
37                 return (false);
38         var ver = proto._sshpkApiVersion;
39         if (ver === undefined)
40                 ver = klass._oldVersionDetect(obj);
41         if (ver[0] != needVer[0] || ver[1] < needVer[1])
42                 return (false);
43         return (true);
44 }
45
46 function assertCompatible(obj, klass, needVer, name) {
47         if (name === undefined)
48                 name = 'object';
49         assert.ok(obj, name + ' must not be null');
50         assert.object(obj, name + ' must be an object');
51         if (needVer === undefined)
52                 needVer = klass.prototype._sshpkApiVersion;
53         if (obj instanceof klass &&
54             klass.prototype._sshpkApiVersion[0] == needVer[0])
55                 return;
56         var proto = Object.getPrototypeOf(obj);
57         var depth = 0;
58         while (proto.constructor.name !== klass.name) {
59                 proto = Object.getPrototypeOf(proto);
60                 assert.ok(proto && ++depth <= MAX_CLASS_DEPTH,
61                     name + ' must be a ' + klass.name + ' instance');
62         }
63         assert.strictEqual(proto.constructor.name, klass.name,
64             name + ' must be a ' + klass.name + ' instance');
65         var ver = proto._sshpkApiVersion;
66         if (ver === undefined)
67                 ver = klass._oldVersionDetect(obj);
68         assert.ok(ver[0] == needVer[0] && ver[1] >= needVer[1],
69             name + ' must be compatible with ' + klass.name + ' klass ' +
70             'version ' + needVer[0] + '.' + needVer[1]);
71 }
72
73 var CIPHER_LEN = {
74         'des-ede3-cbc': { key: 7, iv: 8 },
75         'aes-128-cbc': { key: 16, iv: 16 }
76 };
77 var PKCS5_SALT_LEN = 8;
78
79 function opensslKeyDeriv(cipher, salt, passphrase, count) {
80         assert.buffer(salt, 'salt');
81         assert.buffer(passphrase, 'passphrase');
82         assert.number(count, 'iteration count');
83
84         var clen = CIPHER_LEN[cipher];
85         assert.object(clen, 'supported cipher');
86
87         salt = salt.slice(0, PKCS5_SALT_LEN);
88
89         var D, D_prev, bufs;
90         var material = new Buffer(0);
91         while (material.length < clen.key + clen.iv) {
92                 bufs = [];
93                 if (D_prev)
94                         bufs.push(D_prev);
95                 bufs.push(passphrase);
96                 bufs.push(salt);
97                 D = Buffer.concat(bufs);
98                 for (var j = 0; j < count; ++j)
99                         D = crypto.createHash('md5').update(D).digest();
100                 material = Buffer.concat([material, D]);
101                 D_prev = D;
102         }
103
104         return ({
105             key: material.slice(0, clen.key),
106             iv: material.slice(clen.key, clen.key + clen.iv)
107         });
108 }
109
110 /* Count leading zero bits on a buffer */
111 function countZeros(buf) {
112         var o = 0, obit = 8;
113         while (o < buf.length) {
114                 var mask = (1 << obit);
115                 if ((buf[o] & mask) === mask)
116                         break;
117                 obit--;
118                 if (obit < 0) {
119                         o++;
120                         obit = 8;
121                 }
122         }
123         return (o*8 + (8 - obit) - 1);
124 }
125
126 function bufferSplit(buf, chr) {
127         assert.buffer(buf);
128         assert.string(chr);
129
130         var parts = [];
131         var lastPart = 0;
132         var matches = 0;
133         for (var i = 0; i < buf.length; ++i) {
134                 if (buf[i] === chr.charCodeAt(matches))
135                         ++matches;
136                 else if (buf[i] === chr.charCodeAt(0))
137                         matches = 1;
138                 else
139                         matches = 0;
140
141                 if (matches >= chr.length) {
142                         var newPart = i + 1;
143                         parts.push(buf.slice(lastPart, newPart - matches));
144                         lastPart = newPart;
145                         matches = 0;
146                 }
147         }
148         if (lastPart <= buf.length)
149                 parts.push(buf.slice(lastPart, buf.length));
150
151         return (parts);
152 }
153
154 function ecNormalize(buf, addZero) {
155         assert.buffer(buf);
156         if (buf[0] === 0x00 && buf[1] === 0x04) {
157                 if (addZero)
158                         return (buf);
159                 return (buf.slice(1));
160         } else if (buf[0] === 0x04) {
161                 if (!addZero)
162                         return (buf);
163         } else {
164                 while (buf[0] === 0x00)
165                         buf = buf.slice(1);
166                 if (buf[0] === 0x02 || buf[0] === 0x03)
167                         throw (new Error('Compressed elliptic curve points ' +
168                             'are not supported'));
169                 if (buf[0] !== 0x04)
170                         throw (new Error('Not a valid elliptic curve point'));
171                 if (!addZero)
172                         return (buf);
173         }
174         var b = new Buffer(buf.length + 1);
175         b[0] = 0x0;
176         buf.copy(b, 1);
177         return (b);
178 }
179
180 function mpNormalize(buf) {
181         assert.buffer(buf);
182         while (buf.length > 1 && buf[0] === 0x00 && (buf[1] & 0x80) === 0x00)
183                 buf = buf.slice(1);
184         if ((buf[0] & 0x80) === 0x80) {
185                 var b = new Buffer(buf.length + 1);
186                 b[0] = 0x00;
187                 buf.copy(b, 1);
188                 buf = b;
189         }
190         return (buf);
191 }
192
193 function bigintToMpBuf(bigint) {
194         var buf = new Buffer(bigint.toByteArray());
195         buf = mpNormalize(buf);
196         return (buf);
197 }
198
199 function calculateDSAPublic(g, p, x) {
200         assert.buffer(g);
201         assert.buffer(p);
202         assert.buffer(x);
203         try {
204                 var bigInt = require('jsbn').BigInteger;
205         } catch (e) {
206                 throw (new Error('To load a PKCS#8 format DSA private key, ' +
207                     'the node jsbn library is required.'));
208         }
209         g = new bigInt(g);
210         p = new bigInt(p);
211         x = new bigInt(x);
212         var y = g.modPow(x, p);
213         var ybuf = bigintToMpBuf(y);
214         return (ybuf);
215 }
216
217 function addRSAMissing(key) {
218         assert.object(key);
219         assertCompatible(key, PrivateKey, [1, 1]);
220         try {
221                 var bigInt = require('jsbn').BigInteger;
222         } catch (e) {
223                 throw (new Error('To write a PEM private key from ' +
224                     'this source, the node jsbn lib is required.'));
225         }
226
227         var d = new bigInt(key.part.d.data);
228         var buf;
229
230         if (!key.part.dmodp) {
231                 var p = new bigInt(key.part.p.data);
232                 var dmodp = d.mod(p.subtract(1));
233
234                 buf = bigintToMpBuf(dmodp);
235                 key.part.dmodp = {name: 'dmodp', data: buf};
236                 key.parts.push(key.part.dmodp);
237         }
238         if (!key.part.dmodq) {
239                 var q = new bigInt(key.part.q.data);
240                 var dmodq = d.mod(q.subtract(1));
241
242                 buf = bigintToMpBuf(dmodq);
243                 key.part.dmodq = {name: 'dmodq', data: buf};
244                 key.parts.push(key.part.dmodq);
245         }
246 }