-
Notifications
You must be signed in to change notification settings - Fork 3
/
parse.js
76 lines (69 loc) · 1.65 KB
/
parse.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
function reader(buf, pos) {
return {buf: buf, pos: pos || 0}
}
function U32(inst) {
var ret = inst.buf.readUInt32BE(inst.pos);
inst.pos += 4;
return ret;
}
function U16(inst) {
var ret = inst.buf.readUInt16BE(inst.pos);
inst.pos += 2;
return ret;
}
function BIN(inst, len) {
var ret = inst.buf.slice(inst.pos, inst.pos + len);
inst.pos += len;
return ret;
}
function STR(inst, len) {
return BIN(inst, len).toString();
}
function readCert(_jks) {
var type = STR(_jks, U16(_jks));
var data = BIN(_jks, U32(_jks));
return {type: type, data: data};
}
function readKey(_jks) {
var name = STR(_jks, U16(_jks));
U32(_jks); // skip timestamp high
U32(_jks); // skip timestamp low
var key_data = BIN(_jks, U32(_jks)).slice(0x18); // drop header
var chain = U32(_jks);
var certs = [];
for (var j=0; j<chain; j++) {
var cert = readCert(_jks);
if (cert.type === 'X.509') {
certs.push(cert.data);
}
}
return {key: key_data, certs: certs, name: name};
}
var MAGIC_JKS = 0xfeedfeed;
function parse(jks) {
var _jks = reader(jks);
var magic = U32(_jks);
if (magic !== MAGIC_JKS) {
return null;
}
var version = U32(_jks);
if (version !== 2) {
return null;
}
var entries = U32(_jks);
var material = [];
for(var i=0; i<entries; i++) {
var tag = U32(_jks);
if (tag === 1) {
material.push(readKey(_jks));
}
if (tag === 2) {
material.push(readCert(_jks));
}
}
return {
format: 'jks',
material: material,
};
}
module.exports = parse;