-
Notifications
You must be signed in to change notification settings - Fork 0
/
oracle.js
140 lines (125 loc) · 3.72 KB
/
oracle.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
var http = require("http")
, url = require("url")
, path = require("path")
, xmlenc = require("./lib/xml-encryption")
, fs = require('fs')
, querystring = require("querystring")
, xmldom = require('./lib/xmldom')
, config = require('./config/config')
var port = config.oracle.port;
var verify = config.oracle.verification_path;
var encrypt = config.oracle.encryption_path;
var host = config.oracle.host;
var encrypt_options = {
rsa_pub: config.oracle.rsa_pub
, pem: config.oracle.pem
, key: config.oracle.key
, encryptionAlgorithm: config.oracle.encryptionAlgorithm
, keyEncryptionAlgorighm: config.oracle.keyEncryptionAlgorighm
, autopadding: false
};
function isInvalidXML(xml, testFunc) {
var err = false;
function isInvalidXMLNode(node) {
var invalid = false;
if (node.childNodes) {
for (var i = 0; i < node.childNodes.length; i++) {
if (node.childNodes[i].data) {
if (testFunc(new Buffer(node.childNodes[i].data, 'binary'))) {
invalid = true;
}
}
if (isInvalidXMLNode (node.childNodes[i])) {
invalid = true;
}
}
}
return invalid;
}
var doc = new xmldom.DOMParser({
errorHandler:function(key,msg){
console.log("xxx3xxx", key, msg);
err = true;
}
}).parseFromString(xml, 'text/xml');
if (err) {
return true;
}
var root = doc.documentElement;
if (root) {
return isInvalidXMLNode(root);
} else {
return isInvalidXMLNode(doc);
}
}
function includeTypeAChar(buf) {
var isTypeAChar = function(c) {
if (c >= 0x00 && c <= 0x0F) {
if (c == 0x09 || c == 0x0A || c == 0x0D) {
return false;
} else {
return true;
}
} else if (c >= 0x10 && c <= 0x1F) {
return true;
} else if (c == 0x26 || c == 0x3C) {
return true;
} else {
return false;
}
}
for (var i = 0; i < buf.length; i++) {
if (isTypeAChar(buf.readUInt8(i)))
return true;
}
return false;
}
http.createServer(function(req, res) {
if (req.method === "POST") {
var fullBody = '';
req.on('data', function(chunk) {
// append the current chunk of data to the fullBody variable
fullBody += chunk.toString();
});
req.on('end', function() {
var decodedBody = querystring.parse(fullBody);
var uri = url.parse(req.url).pathname
, filename = path.join(process.cwd(), uri);
switch (uri) {
case verify:
res.writeHead(200, "OK", {'Content-Type': 'text/html'});
xmlenc.decrypt(fullBody, encrypt_options, function (err, decrypted) {
var verifyACK = function (v) {
if (v) {
res.write("Decrypt: OK\r\n");
} else {
res.write("Decrypt: ERROR\r\n");
}
res.end();
}
var valid = true;
var rawDecrytped = new Buffer(decrypted, 'binary');
var padding = rawDecrytped[rawDecrytped.length - 1];
console.log("======", rawDecrytped.toString('hex'), padding);
if (padding <= 0x10 && padding >= 0x01) {
var source = rawDecrytped.toString('binary', 0, rawDecrytped.length - padding);
if (source != "") {
if (isInvalidXML(source, includeTypeAChar)) {
valid = false;
}
}
} else {
valid = false;
}
verifyACK(valid);
});
case encrypt:
res.writeHead(200, "OK", {'Content-Type': 'text/xml'});
xmlenc.encrypt(fullBody, encrypt_options, function (err, result) {
res.write(result);
res.end();
});
}
});
}
}).listen(port);