Fixed certificate generation.
Ylian Saint-Hilaire committed
Oct 18, 2017 at 16:28 UTC
5108b344be781d426cb3acbd97367630f7e855c1
10 files changed
+82
-64
agents/MeshService.exe
Binary files a/agents/MeshService.exe and b/agents/MeshService.exe differ
agents/MeshService64.exe
Binary files a/agents/MeshService64.exe and b/agents/MeshService64.exe differ
agents/meshcore.js
+1
-1
@@ -385,7 +385,7 @@ function createMeshCore(agent) {
385
}
386
387
// Tunnel callback operations
388
- function onTunnelUpgrade(response, s, head) { this.s = s; s.httprequest = this; s.end = onTunnelClosed; s.data = onTunnelData; }
388
+ function onTunnelUpgrade(response, s, head) { sendConsoleText('onTunnelUpgrade'); this.s = s; s.httprequest = this; s.end = onTunnelClosed; s.data = onTunnelData; }
389
function onTunnelClosed() {
390
sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid);
391
if (this.httprequest.protocol == 1) { this.httprequest.process.end(); delete this.httprequest.process; }
certoperations.js
+37
-21
@@ -20,8 +20,8 @@ module.exports.CertificateOperations = function () {
20
}
21
22
// Create a self-signed certificate
23
- obj.GenerateRootCertificate = function (addThumbPrintToName, commonName, country, organization) {
24
- var keys = obj.pki.rsa.generateKeyPair(3072);
23
+ obj.GenerateRootCertificate = function (addThumbPrintToName, commonName, country, organization, strong) {
24
+ var keys = obj.pki.rsa.generateKeyPair((strong == true) ? 3072 : 2048);
25
var cert = obj.pki.createCertificate();
26
cert.publicKey = keys.publicKey;
27
cert.serialNumber = '' + Math.floor((Math.random() * 100000) + 1); ;
@@ -128,6 +128,7 @@ module.exports.CertificateOperations = function () {
128
// Returns the web server TLS certificate and private key, if not present, create demonstration ones.
129
obj.GetMeshServerCertificate = function (directory, args, func) {
130
var certargs = args.cert;
131
+ var strongCertificate = (args.fastcert ? false : true);
132
// commonName, country, organization
133
134
// If the certificates directory does not exist, create it.
@@ -225,12 +226,23 @@ module.exports.CertificateOperations = function () {
226
if (xorganizationField != null) { xorganization = xorganizationField.value; }
227
if ((r.CommonName == commonName) && (xcountry == country) && (xorganization == organization) && (r.AmtMpsName == commonName)) { if (func != undefined) { func(r); } return r; } else { forceWebCertGen = 1; } // If the certificate matches what we want, keep it.
228
}
228
- console.log('Generating certificates, may take a few minutes...');
229
-
229
+ //console.log('Generating certificates, may take a few minutes...');
230
+
231
+ // If a certificate is missing, but web certificate is present and --cert is not used, set the names to be the same as the web certificate
232
+ if ((certargs == null) && (r.web != null)) {
233
+ var webCertificate = obj.pki.certificateFromPem(r.web.cert);
234
+ commonName = webCertificate.subject.getField('CN').value;
235
+ var xcountryField = webCertificate.subject.getField('C');
236
+ if (xcountryField != null) { country = xcountryField.value; }
237
+ var xorganizationField = webCertificate.subject.getField('O');
238
+ if (xorganizationField != null) { organization = xorganizationField.value; }
239
+ }
240
+
241
var rootCertAndKey, rootCertificate, rootPrivateKey, rootName;
242
if (r.root == undefined) {
243
// If the root certificate does not exist, create one
233
- rootCertAndKey = obj.GenerateRootCertificate(true, 'MeshCentralRoot');
244
+ console.log('Generating root certificate...');
245
+ rootCertAndKey = obj.GenerateRootCertificate(true, 'MeshCentralRoot', null, null, strongCertificate);
246
rootCertificate = obj.pki.certificateToPem(rootCertAndKey.cert);
247
rootPrivateKey = obj.pki.privateKeyToPem(rootCertAndKey.key);
248
obj.fs.writeFileSync(directory + '/root-cert-public.crt', rootCertificate);
@@ -246,7 +258,8 @@ module.exports.CertificateOperations = function () {
258
// If the web certificate does not exist, create one
259
var webCertAndKey, webCertificate, webPrivateKey;
260
if ((r.web == null) || (forceWebCertGen == 1)) {
249
- webCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, commonName, country, organization, null, true);
261
+ console.log('Generating HTTPS certificate...');
262
+ webCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, commonName, country, organization, null, strongCertificate);
263
webCertificate = obj.pki.certificateToPem(webCertAndKey.cert);
264
webPrivateKey = obj.pki.privateKeyToPem(webCertAndKey.key);
265
obj.fs.writeFileSync(directory + '/webserver-cert-public.crt', webCertificate);
@@ -258,9 +271,26 @@ module.exports.CertificateOperations = function () {
271
webPrivateKey = r.web.key
272
}
273
274
+ // If the mesh agent server certificate does not exist, create one
275
+ var agentCertAndKey, agentCertificate, agentPrivateKey;
276
+ if (r.agent == null) {
277
+ console.log('Generating MeshAgent certificate...');
278
+ agentCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, true, 'MeshCentralAgentServer', null, strongCertificate);
279
+ agentCertificate = obj.pki.certificateToPem(agentCertAndKey.cert);
280
+ agentPrivateKey = obj.pki.privateKeyToPem(agentCertAndKey.key);
281
+ obj.fs.writeFileSync(directory + '/agentserver-cert-public.crt', agentCertificate);
282
+ obj.fs.writeFileSync(directory + '/agentserver-cert-private.key', agentPrivateKey);
283
+ } else {
284
+ // Keep the mesh agent server certificate we have
285
+ agentCertAndKey = { cert: obj.pki.certificateFromPem(r.agent.cert), key: obj.pki.privateKeyFromPem(r.agent.key) };
286
+ agentCertificate = r.agent.cert
287
+ agentPrivateKey = r.agent.key
288
+ }
289
+
290
// If the Intel AMT MPS certificate does not exist, create one
291
var mpsCertAndKey, mpsCertificate, mpsPrivateKey;
292
if ((r.mps == null) || (forceWebCertGen == 1)) {
293
+ console.log('Generating Intel AMT MPS certificate...');
294
mpsCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, commonName, country, organization, null, false);
295
mpsCertificate = obj.pki.certificateToPem(mpsCertAndKey.cert);
296
mpsPrivateKey = obj.pki.privateKeyToPem(mpsCertAndKey.key);
@@ -276,6 +306,7 @@ module.exports.CertificateOperations = function () {
306
// If the Intel AMT console certificate does not exist, create one
307
var consoleCertAndKey, consoleCertificate, consolePrivateKey, amtConsoleName = 'MeshCentral';
308
if (r.console == null) {
309
+ console.log('Generating Intel AMT console certificate...');
310
consoleCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, amtConsoleName, country, organization, { name: 'extKeyUsage', clientAuth: true, '2.16.840.1.113741.1.2.1': true, '2.16.840.1.113741.1.2.2': true, '2.16.840.1.113741.1.2.3': true }, false); // Intel AMT Remote, Agent and Activation usages
311
consoleCertificate = obj.pki.certificateToPem(consoleCertAndKey.cert);
312
consolePrivateKey = obj.pki.privateKeyToPem(consoleCertAndKey.key);
@@ -289,21 +320,6 @@ module.exports.CertificateOperations = function () {
320
amtConsoleName = consoleCertAndKey.cert.subject.getField('CN').value;
321
}
322
292
- // If the mesh agent server certificate does not exist, create one
293
- var agentCertAndKey, agentCertificate, agentPrivateKey;
294
- if (r.agent == null) {
295
- agentCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, true, 'MeshCentralAgentServer', null, true);
296
- agentCertificate = obj.pki.certificateToPem(agentCertAndKey.cert);
297
- agentPrivateKey = obj.pki.privateKeyToPem(agentCertAndKey.key);
298
- obj.fs.writeFileSync(directory + '/agentserver-cert-public.crt', agentCertificate);
299
- obj.fs.writeFileSync(directory + '/agentserver-cert-private.key', agentPrivateKey);
300
- } else {
301
- // Keep the mesh agent server certificate we have
302
- agentCertAndKey = { cert: obj.pki.certificateFromPem(r.agent.cert), key: obj.pki.privateKeyFromPem(r.agent.key) };
303
- agentCertificate = r.agent.cert
304
- agentPrivateKey = r.agent.key
305
- }
306
-
323
var r = { root: { cert: rootCertificate, key: rootPrivateKey }, web: { cert: webCertificate, key: webPrivateKey }, mps: { cert: mpsCertificate, key: mpsPrivateKey }, agent: { cert: agentCertificate, key: agentPrivateKey }, console: { cert: consoleCertificate, key: consolePrivateKey }, calist: calist, CommonName: commonName, RootName: rootName, AmtConsoleName: amtConsoleName };
324
if (func != undefined) { func(r); }
325
return r;
meshagent.js
+7
-7
@@ -151,8 +151,8 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
151
if ((msg.length != 98) || ((obj.receivedCommands & 1) != 0)) return;
152
obj.receivedCommands += 1; // Agent can't send the same command twice on the same connection ever. Block DOS attack path.
153
154
- // Check that the server hash matches out own web certificate hash (SHA386)
155
- if (obj.parent.webCertificatHash != msg.substring(2, 50)) { obj.close(); return; }
154
+ // Check that the server hash matches our own web certificate hash (SHA386)
155
+ if (obj.parent.webCertificateHash != msg.substring(2, 50)) { console.log('Agent connected with bad web certificate hash, holding connection (' + obj.remoteaddr + ').'); return; }
156
157
// Use our server private key to sign the ServerHash + AgentNonce + ServerNonce
158
var privateKey = obj.forge.pki.privateKeyFromPem(obj.parent.certificates.agent.key);
@@ -162,11 +162,11 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
162
obj.agentnonce = msg.substring(50);
163
164
// Send back our certificate + signature
165
- obj.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(parent.agentCertificatAsn1.length) + parent.agentCertificatAsn1 + privateKey.sign(md)); // Command 2, certificate + signature
165
+ obj.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(parent.agentCertificateAsn1.length) + parent.agentCertificateAsn1 + privateKey.sign(md)); // Command 2, certificate + signature
166
167
// Check the agent signature if we can
168
if (obj.unauthsign != null) {
169
- if (processAgentSignature(obj.unauthsign) == false) { disonnect(); return; } else { completeAgentConnection(); }
169
+ if (processAgentSignature(obj.unauthsign) == false) { console.log('Agent connected with bad signature, holding connection (' + obj.remoteaddr + ').'); return; } else { completeAgentConnection(); }
170
}
171
}
172
else if (cmd == 2) {
@@ -182,7 +182,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
182
obj.unauth.nodeid = new Buffer(obj.forge.pki.getPublicKeyFingerprint(obj.unauth.nodeCert.publicKey, { md: obj.forge.md.sha384.create() }).data, 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
183
184
// Check the agent signature if we can
185
- if (obj.agentnonce == null) { obj.unauthsign = msg.substring(4 + certlen); } else { if (processAgentSignature(msg.substring(4 + certlen)) == false) { console.log('Bad Agent Signature'); obj.close(); return; } }
185
+ if (obj.agentnonce == null) { obj.unauthsign = msg.substring(4 + certlen); } else { if (processAgentSignature(msg.substring(4 + certlen)) == false) { console.log('Agent connected with bad signature, holding connection (' + obj.remoteaddr + ').'); return; } }
186
completeAgentConnection();
187
}
188
else if (cmd == 3) {
@@ -217,7 +217,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
217
// Start authenticate the mesh agent by sending a auth nonce & server TLS cert hash.
218
// Send 384 bits SHA384 hash of TLS cert public key + 384 bits nonce
219
obj.nonce = obj.forge.random.getBytesSync(48);
220
- obj.send(obj.common.ShortToStr(1) + parent.webCertificatHash + obj.nonce); // Command 1, hash + nonce
220
+ obj.send(obj.common.ShortToStr(1) + parent.webCertificateHash + obj.nonce); // Command 1, hash + nonce
221
222
// Once we get all the information about an agent, run this to hook everything up to the server
223
function completeAgentConnection() {
@@ -334,7 +334,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
334
// Verify the agent signature
335
function processAgentSignature(msg) {
336
var md = obj.forge.md.sha384.create(); // TODO: Switch this to SHA384 on node instead of forge.
337
- md.update(obj.parent.webCertificatHash, 'binary');
337
+ md.update(obj.parent.webCertificateHash, 'binary');
338
md.update(obj.nonce, 'binary');
339
md.update(obj.agentnonce, 'binary');
340
if (obj.unauth.nodeCert.publicKey.verify(md.digest().bytes(), msg) == false) { return false; }
meshcentral.js
+1
-1
@@ -64,7 +64,7 @@ function CreateMeshCentralServer() {
64
try { require('./pass').hash('test', function () { }); } catch (e) { console.log('Old version of node, must upgrade.'); return; } // TODO: Not sure if this test works or not.
65
66
// Check for invalid arguments
67
- var validArguments = ['_', 'notls', 'user', 'port', 'mpsport', 'redirport', 'cert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'shownodes', 'showmeshes', 'showevents', 'showpower', 'showiplocations', 'help', 'exactports', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpsdebug', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbimport', 'selfupdate', 'tlsoffload', 'userallowedip'];
67
+ var validArguments = ['_', 'notls', 'user', 'port', 'mpsport', 'redirport', 'cert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'shownodes', 'showmeshes', 'showevents', 'showpower', 'showiplocations', 'help', 'exactports', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpsdebug', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbimport', 'selfupdate', 'tlsoffload', 'userallowedip', 'fastcert'];
68
for (var arg in obj.args) { obj.args[arg.toLocaleLowerCase()] = obj.args[arg]; if (validArguments.indexOf(arg.toLocaleLowerCase()) == -1) { console.log('Invalid argument "' + arg + '", use --help.'); return; } }
69
if (obj.args.mongodb == true) { console.log('Must specify: --mongodb [connectionstring] \r\nSee https://docs.mongodb.com/manual/reference/connection-string/ for MongoDB connection string.'); return; }
70
meshscanner.js
+11
-10
@@ -17,13 +17,13 @@ module.exports.CreateMeshScanner = function (parent) {
17
var periodicScanTime = (60000 * 20); // Interval between scans, 20 minutes.
18
var membershipIPv4 = '239.255.255.235';
19
var membershipIPv6 = 'FF02:0:0:0:0:0:0:FE';
20
- obj.agentCertificatHashHex = parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(parent.certificates.agent.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'hex' }).toUpperCase();
20
+ obj.agentCertificateHashHex = parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(parent.certificates.agent.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'hex' }).toUpperCase();
21
obj.error = 0;
22
23
// Get a list of IPv4 and IPv6 interface addresses
24
function getInterfaceList() {
25
var ipv4 = ['*'], ipv6 = ['*']; // Bind to IN_ADDR_ANY always
26
- if (parent.platform == 'win32') { // On Windows, also bind to each interface seperatly
26
+ //if (parent.platform == 'win32') { // On Windows, also bind to each interface seperatly (TODO: REMOVE THIS AND TEST ON LINUX!!!!!!!!!!!!!!!!!!)
27
var interfaces = require('os').networkInterfaces();
28
for (var i in interfaces) {
29
var interface = interfaces[i];
@@ -35,7 +35,7 @@ module.exports.CreateMeshScanner = function (parent) {
35
}
36
}
37
}
38
- }
38
+ //}
39
return { ipv4: ipv4, ipv6: ipv6 };
40
}
41
@@ -52,7 +52,7 @@ module.exports.CreateMeshScanner = function (parent) {
52
} else {
53
// Create a new IPv4 server
54
try {
55
- var server4 = obj.dgram.createSocket("udp4");
55
+ var server4 = obj.dgram.createSocket({ type: 'udp4', reuseAddr: true });
56
server4.xxclear = false;
57
server4.xxtype = 4;
58
server4.xxlocal = localAddress;
@@ -64,8 +64,8 @@ module.exports.CreateMeshScanner = function (parent) {
64
this.setBroadcast(true);
65
this.setMulticastTTL(128);
66
this.addMembership(membershipIPv4);
67
- server4.on('error', function (error) { console.log('Error: ' + error); });
68
- server4.on('message', function (msg, info) { onUdpPacket(msg, info, server4); });
67
+ this.on('error', function (error) { console.log('Error: ' + error); });
68
+ this.on('message', function (msg, info) { onUdpPacket(msg, info, this); });
69
obj.performScan(this);
70
obj.performScan(this);
71
} catch (e) { }
@@ -84,7 +84,7 @@ module.exports.CreateMeshScanner = function (parent) {
84
obj.servers6[localAddress].xxclear = false;
85
} else {
86
// Create a new IPv6 server
87
- var server6 = obj.dgram.createSocket("udp6", localAddress);
87
+ var server6 = obj.dgram.createSocket({ type: 'udp6', reuseAddr: true });
88
server6.xxclear = false;
89
server6.xxtype = 6;
90
server6.xxlocal = localAddress;
@@ -105,6 +105,7 @@ module.exports.CreateMeshScanner = function (parent) {
105
obj.servers6[localAddress] = server6;
106
}
107
}
108
+
109
for (var i in obj.servers4) { if (obj.servers4[i].xxclear == true) { obj.servers4[i].close(); delete obj.servers4[i]; }; }
110
for (var i in obj.servers6) { if (obj.servers6[i].xxclear == true) { obj.servers6[i].close(); delete obj.servers6[i]; }; }
111
}
@@ -119,9 +120,9 @@ module.exports.CreateMeshScanner = function (parent) {
120
obj.start = function () {
121
if (obj.server4 != null) return;
122
var url = (parent.args.notls ? 'ws' : 'wss') + '://%s:' + parent.args.port + '/agent.ashx';
122
- obj.multicastPacket4 = Buffer.from("MeshCentral2|" + obj.agentCertificatHashHex + '|' + url, 'ascii');
123
+ obj.multicastPacket4 = Buffer.from("MeshCentral2|" + obj.agentCertificateHashHex + '|' + url, 'ascii');
124
url = (parent.args.notls ? 'ws' : 'wss') + '://[%s]:' + parent.args.port + '/agent.ashx';
124
- obj.multicastPacket6 = Buffer.from("MeshCentral2|" + obj.agentCertificatHashHex + '|' + url, 'ascii');
125
+ obj.multicastPacket6 = Buffer.from("MeshCentral2|" + obj.agentCertificateHashHex + '|' + url, 'ascii');
126
setupServers();
127
obj.mainTimer = setInterval(obj.performScan, periodicScanTime);
128
return obj;
@@ -150,7 +151,7 @@ module.exports.CreateMeshScanner = function (parent) {
151
// Called when a UDP packet is received from an agent.
152
function onUdpPacket(msg, info, server) {
153
//console.log('Received ' + msg.length + ' bytes from ' + info.address + ':' + info.port + ', on interface: ' + server.xxlocal + '.');
153
- if ((msg.length == 96) && (msg.toString('ascii') == obj.agentCertificatHashHex)) {
154
+ if ((msg.length == 96) && (msg.toString('ascii') == obj.agentCertificateHashHex)) {
155
if (server.xxtype == 4) { try { server.send(obj.multicastPacket4, 0, obj.multicastPacket4.length, info.port, info.address); } catch (e) { } }
156
if (server.xxtype == 6) { try { server.send(obj.multicastPacket6, 0, obj.multicastPacket6.length, info.port, info.address); } catch (e) { } }
157
}
mpsserver.js
+2
-1
@@ -463,7 +463,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
463
var RecipientChannel = common.ReadInt(data, 1);
464
var LengthOfData = common.ReadInt(data, 5);
465
if (len < (9 + LengthOfData)) return 0;
466
- Debug(3, 'MPS:CHANNEL_DATA', RecipientChannel, LengthOfData);
466
+ Debug(4, 'MPS:CHANNEL_DATA', RecipientChannel, LengthOfData);
467
var cirachannel = socket.tag.channels[RecipientChannel];
468
if (cirachannel == undefined) { console.log("MPS Error in CHANNEL_DATA: Unable to find channelid " + RecipientChannel); return; }
469
cirachannel.amtpendingcredits += LengthOfData;
@@ -553,6 +553,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
553
}
554
555
function SendChannelWindowAdjust(socket, channelid, bytestoadd) {
556
+ Debug(3, 'MPS:SendChannelWindowAdjust', channelid, bytestoadd);
557
Write(socket, String.fromCharCode(APFProtocol.CHANNEL_WINDOW_ADJUST) + common.IntToStr(channelid) + common.IntToStr(bytestoadd));
558
}
559
multiserver.js
+17
-17
@@ -32,9 +32,9 @@ module.exports.CreateMultiServer = function (parent, args) {
32
obj.retryTimer = null;
33
obj.retryBackoff = 0;
34
obj.connectHandler = null;
35
- obj.webCertificatHash = obj.parent.parent.webserver.webCertificatHash;
36
- obj.agentCertificatHashBase64 = obj.parent.parent.webserver.agentCertificatHashBase64;
37
- obj.agentCertificatAsn1 = obj.parent.parent.webserver.agentCertificatAsn1;
35
+ obj.webCertificateHash = obj.parent.parent.webserver.webCertificateHash;
36
+ obj.agentCertificateHashBase64 = obj.parent.parent.webserver.agentCertificateHashBase64;
37
+ obj.agentCertificateAsn1 = obj.parent.parent.webserver.agentCertificateAsn1;
38
obj.peerServerId = null;
39
obj.authenticated = 0;
40
obj.serverCertHash = null;
@@ -99,8 +99,8 @@ module.exports.CreateMultiServer = function (parent, args) {
99
md.update(obj.nonce, 'binary');
100
101
// Send back our certificate + signature
102
- agentRootCertificatAsn1 = obj.forge.asn1.toDer(obj.forge.pki.certificateToAsn1(obj.forge.pki.certificateFromPem(obj.certificates.agent.cert))).getBytes();
103
- obj.ws.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(agentRootCertificatAsn1.length) + agentRootCertificatAsn1 + privateKey.sign(md)); // Command 3, signature
102
+ agentRootCertificateAsn1 = obj.forge.asn1.toDer(obj.forge.pki.certificateToAsn1(obj.forge.pki.certificateFromPem(obj.certificates.agent.cert))).getBytes();
103
+ obj.ws.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(agentRootCertificateAsn1.length) + agentRootCertificatAsn1 + privateKey.sign(md)); // Command 3, signature
104
break;
105
}
106
case 2: {
@@ -109,7 +109,7 @@ module.exports.CreateMultiServer = function (parent, args) {
109
try { serverCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))); } catch (e) { }
110
if (serverCert == null) { obj.parent.parent.debug(1, 'OutPeer: Invalid server certificate.'); disconnect(); return; }
111
var serverid = new Buffer(obj.forge.pki.getPublicKeyFingerprint(serverCert.publicKey, { encoding: 'binary', md: obj.forge.md.sha384.create() }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
112
- if (serverid !== obj.agentCertificatHashBase64) { obj.parent.parent.debug(1, 'OutPeer: Server hash mismatch.'); disconnect(); return; }
112
+ if (serverid !== obj.agentCertificateHashBase64) { obj.parent.parent.debug(1, 'OutPeer: Server hash mismatch.'); disconnect(); return; }
113
114
// Server signature, verify it
115
var md = obj.forge.md.sha384.create();
@@ -127,14 +127,14 @@ module.exports.CreateMultiServer = function (parent, args) {
127
obj.parent.parent.debug(1, 'OutPeer ' + obj.serverid + ': Verified peer connection to ' + obj.url);
128
129
// Send information about our server to the peer
130
- if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificatHashBase64 })); }
130
+ if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificateHashBase64 })); }
131
//if ((obj.connectionState == 15) && (obj.connectHandler != null)) { obj.connectHandler(1); }
132
break;
133
}
134
case 4: {
135
// Server confirmed authentication, we are allowed to send commands to the server
136
obj.connectionState |= 8;
137
- if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificatHashBase64 })); }
137
+ if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificateHashBase64 })); }
138
//if ((obj.connectionState == 15) && (obj.connectHandler != null)) { obj.connectHandler(1); }
139
break;
140
}
@@ -212,9 +212,9 @@ module.exports.CreateMultiServer = function (parent, args) {
212
obj.authenticated = 0;
213
obj.remoteaddr = obj.ws._socket.remoteAddress;
214
obj.receivedCommands = 0;
215
- obj.webCertificatHash = obj.parent.parent.webserver.webCertificatHash;
216
- obj.agentCertificatHashBase64 = obj.parent.parent.webserver.agentCertificatHashBase64;
217
- obj.agentCertificatAsn1 = obj.parent.parent.webserver.agentCertificatAsn1;
215
+ obj.webCertificateHash = obj.parent.parent.webserver.webCertificateHash;
216
+ obj.agentCertificateHashBase64 = obj.parent.parent.webserver.agentCertificateHashBase64;
217
+ obj.agentCertificateAsn1 = obj.parent.parent.webserver.agentCertificateAsn1;
218
obj.infoSent = 0;
219
obj.peerServerId = null;
220
obj.serverCertHash = null;
@@ -256,7 +256,7 @@ module.exports.CreateMultiServer = function (parent, args) {
256
obj.receivedCommands += 1; // Peer server can't send the same command twice on the same connection ever. Block DOS attack path.
257
258
// Check that the server hash matches out own web certificate hash
259
- if (obj.webCertificatHash != msg.substring(2, 50)) { obj.close(); return; }
259
+ if (obj.webCertificateHash != msg.substring(2, 50)) { obj.close(); return; }
260
261
// Use our server private key to sign the ServerHash + PeerNonce + ServerNonce
262
var privateKey = obj.forge.pki.privateKeyFromPem(obj.parent.parent.certificates.agent.key);
@@ -266,7 +266,7 @@ module.exports.CreateMultiServer = function (parent, args) {
266
obj.peernonce = msg.substring(50);
267
268
// Send back our certificate + signature
269
- obj.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(obj.agentCertificatAsn1.length) + obj.agentCertificatAsn1 + privateKey.sign(md)); // Command 2, certificate + signature
269
+ obj.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(obj.agentCertificateAsn1.length) + obj.agentCertificateAsn1 + privateKey.sign(md)); // Command 2, certificate + signature
270
271
// Check the peer server signature if we can
272
if (obj.unauthsign != null) {
@@ -307,24 +307,24 @@ module.exports.CreateMultiServer = function (parent, args) {
307
// Start authenticate the peer server by sending a auth nonce & server TLS cert hash.
308
// Send 384 bits SHA382 hash of TLS cert public key + 384 bits nonce
309
obj.nonce = obj.forge.random.getBytesSync(48);
310
- obj.send(obj.common.ShortToStr(1) + obj.webCertificatHash + obj.nonce); // Command 1, hash + nonce
310
+ obj.send(obj.common.ShortToStr(1) + obj.webCertificateHash + obj.nonce); // Command 1, hash + nonce
311
312
// Once we get all the information about an peer server, run this to hook everything up to the server
313
function completePeerServerConnection() {
314
if (obj.authenticated != 1) return;
315
obj.send(obj.common.ShortToStr(4));
316
- obj.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificatHashBase64 }));
316
+ obj.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificateHashBase64 }));
317
obj.authenticated = 2;
318
}
319
320
// Verify the peer server signature
321
function processPeerSignature(msg) {
322
var md = obj.forge.md.sha384.create(); // TODO: Switch this to SHA384 on node instead of forge.
323
- md.update(obj.parent.parent.webserver.webCertificatHash, 'binary');
323
+ md.update(obj.parent.parent.webserver.webCertificateHash, 'binary');
324
md.update(obj.nonce, 'binary');
325
md.update(obj.peernonce, 'binary');
326
if (obj.unauth.nodeCert.publicKey.verify(md.digest().bytes(), msg) == false) { return false; }
327
- if (obj.unauth.nodeid !== obj.agentCertificatHashBase64) { return false; }
327
+ if (obj.unauth.nodeid !== obj.agentCertificateHashBase64) { return false; }
328
329
// Connection is a success, clean up
330
obj.nodeid = obj.unauth.nodeid;
webserver.js
+6
-6
@@ -69,10 +69,10 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
69
obj.userAllowedIp = args.userallowedip; // List of allowed IP addresses for users
70
71
// Perform hash on web certificate and agent certificate
72
- obj.webCertificatHash = parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.web.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'binary' });
73
- obj.webCertificatHashBase64 = new Buffer(parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.web.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'binary' }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
74
- obj.agentCertificatHashBase64 = new Buffer(parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.agent.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'binary' }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
75
- obj.agentCertificatAsn1 = parent.certificateOperations.forge.asn1.toDer(parent.certificateOperations.forge.pki.certificateToAsn1(parent.certificateOperations.forge.pki.certificateFromPem(parent.certificates.agent.cert))).getBytes();
72
+ obj.webCertificateHash = parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.web.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'binary' });
73
+ obj.webCertificateHashBase64 = new Buffer(parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.web.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'binary' }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
74
+ obj.agentCertificateHashBase64 = new Buffer(parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.agent.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'binary' }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
75
+ obj.agentCertificateAsn1 = parent.certificateOperations.forge.asn1.toDer(parent.certificateOperations.forge.pki.certificateToAsn1(parent.certificateOperations.forge.pki.certificateFromPem(parent.certificates.agent.cert))).getBytes();
76
77
// Main lists
78
obj.wsagents = {};
@@ -813,7 +813,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
813
}
814
815
ws.forwardclient.onData = function (ciraconn, data) {
816
- Debug(3, 'Relay CIRA data', data.length);
816
+ Debug(4, 'Relay CIRA data', data.length);
817
if (ws.interceptor) { data = ws.interceptor.processAmtData(data); } // Run data thru interceptor
818
if (data.length > 0) { try { ws.send(data); } catch (e) { } } // TODO: Add TLS support
819
}
@@ -1942,7 +1942,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
1942
//if (domain.id != mesh.domain) { res.sendStatus(401); return; }
1943
1944
var meshidhex = new Buffer(req.query.id.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
1945
- var serveridhex = new Buffer(obj.agentCertificatHashBase64.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
1945
+ var serveridhex = new Buffer(obj.agentCertificateHashBase64.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
1946
1947
var xdomain = domain.id;
1948
if (xdomain != '') xdomain += "/";