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 += "/";