1 | "use strict";
|
2 |
|
3 | const ASN_LONG_LEN = 0x80;
|
4 | const SSH_RSA = 'ssh-rsa';
|
5 |
|
6 | function ASN_len(s) {
|
7 | var len = s.length;
|
8 | if(len < ASN_LONG_LEN)
|
9 | return new Buffer([len]);
|
10 |
|
11 | var data = len.toString(16);
|
12 |
|
13 | if(data.length & 1)
|
14 | data = "0" + data;
|
15 | data = new Buffer(data, 'hex');
|
16 | return Buffer.concat([new Buffer([data.length | ASN_LONG_LEN]), data]);
|
17 | }
|
18 |
|
19 | var unpack = function(data, start) {
|
20 | var slice = data.slice(start, 4);
|
21 | var out = (slice[0] << 24) + (slice[1] << 16) + (slice[2] << 8) + slice[3];
|
22 | return [out];
|
23 | };
|
24 |
|
25 | var asnf = function(type, body) {
|
26 | return Buffer.concat([new Buffer([type]), ASN_len(body), body]);
|
27 | };
|
28 |
|
29 | module.exports = function(openssh_data) {
|
30 | if(openssh_data.substr(0, SSH_RSA.length) == SSH_RSA)
|
31 | openssh_data = openssh_data.substr(SSH_RSA.length);
|
32 |
|
33 | var data = new Buffer(openssh_data, 'base64');
|
34 | var alg_len = unpack(data, 0)[0];
|
35 | var i = 4;
|
36 | var alg = data.slice(i, i += alg_len).toString('ascii');
|
37 |
|
38 | if(alg !== SSH_RSA)
|
39 | throw "Not rsa";
|
40 |
|
41 | var e_len = unpack(data.slice(i, i += 4))[0];
|
42 | var e = data.slice(i, i += e_len);
|
43 | var n_len = unpack(data.slice(i, i += 4))[0];
|
44 | var n = data.slice(i, i += n_len);
|
45 | var algid = new Buffer('06092a864886f70d0101010500', 'hex');
|
46 |
|
47 | algid = asnf(0x30, algid);
|
48 | data = asnf(0x02, n);
|
49 |
|
50 | data = Buffer.concat([data, asnf(0x02, e)]);
|
51 | data = asnf(0x30, data);
|
52 | data = Buffer.concat([new Buffer([0]), data]);
|
53 | data = asnf(0x03, data);
|
54 | data = Buffer.concat([algid, data]);
|
55 | data = asnf(0x30, data);
|
56 |
|
57 | return data.toString('base64');
|
58 | };
|