Added new certificate for Intel AMT console authentication.

Ylian Saint-Hilaire committed Sep 29, 2017 at 14:26 UTC 5ced5c565e6efc0c934ea3ea660180688906dd28
3 files changed +142 -41
certoperations.js
+99 -38
@@ -19,6 +19,14 @@ module.exports.CertificateOperations = function () {
19 return obj.pki.getPublicKeyFingerprint(publickey, { encoding: 'hex', md: obj.forge.md.sha256.create() });
20 }
21
22 + // Return a random nonce (TODO: weak crypto)
23 + obj.xxRandomNonceX = "abcdef0123456789";
24 + obj.xxRandomNonce = function (length) {
25 + var r = "";
26 + for (var i = 0; i < length; i++) { r += obj.xxRandomNonceX.charAt(Math.floor(Math.random() * obj.xxRandomNonceX.length)); }
27 + return r;
28 + }
29 +
30 // Create a self-signed certificate
31 obj.GenerateRootCertificate = function (addThumbPrintToName, commonName, country, organization) {
32 var keys = obj.pki.rsa.generateKeyPair(2048);
@@ -54,7 +62,7 @@ module.exports.CertificateOperations = function () {
62 }
63
64 // Issue a certificate from a root
57 - obj.IssueWebServerCertificate = function (rootcert, addThumbPrintToName, commonName, country, organization) {
65 + obj.IssueWebServerCertificate = function (rootcert, addThumbPrintToName, commonName, country, organization, extKeyUsage) {
66 var keys = obj.pki.rsa.generateKeyPair(2048);
67 var cert = obj.pki.createCertificate();
68 cert.publicKey = keys.publicKey;
@@ -69,25 +77,45 @@ module.exports.CertificateOperations = function () {
77 if (organization != undefined) attrs.push({ name: 'organizationName', value: organization });
78 cert.setSubject(attrs);
79 cert.setIssuer(rootcert.cert.subject.attributes);
72 -
73 - cert.setExtensions([{
74 - name: 'basicConstraints',
75 - cA: false
76 - }, {
80 +
81 + if (extKeyUsage == null) { extKeyUsage = { name: 'extKeyUsage', serverAuth: true, } } else { extKeyUsage.name = 'extKeyUsage'; }
82 + var subjectAltName = null;
83 + if (extKeyUsage.serverAuth == true) {
84 + subjectAltName = {
85 + name: 'subjectAltName',
86 + altNames: [{
87 + type: 6, // URI
88 + value: 'http://' + commonName + '/'
89 + }, {
90 + type: 6, // URL
91 + value: 'http://localhost/'
92 + }]
93 + }
94 + }
95 +
96 + /*
97 + {
98 + name: 'extKeyUsage',
99 + serverAuth: true,
100 + clientAuth: true,
101 + codeSigning: true,
102 + emailProtection: true,
103 + timeStamping: true,
104 + '2.16.840.1.113741.1.2.1': true
105 + }
106 + */
107 +
108 + var extensions = [{
109 + name: 'basicConstraints',
110 + cA: false
111 + }, {
112 name: 'keyUsage',
113 keyCertSign: true,
114 digitalSignature: true,
115 nonRepudiation: true,
116 keyEncipherment: true,
117 dataEncipherment: true
83 - }, {
84 - name: 'extKeyUsage',
85 - serverAuth: true,
86 - clientAuth: false,
87 - codeSigning: false,
88 - emailProtection: false,
89 - timeStamping: false
90 - }, {
118 + }, extKeyUsage, {
119 name: 'nsCertType',
120 client: false,
121 server: true,
@@ -96,18 +124,11 @@ module.exports.CertificateOperations = function () {
124 sslCA: false,
125 emailCA: false,
126 objCA: false
99 - }, {
100 - name: 'subjectAltName',
101 - altNames: [{
102 - type: 6, // URI
103 - value: 'http://' + commonName + '/'
104 - }, {
105 - type: 6, // URL
106 - value: 'http://localhost/'
107 - }]
127 }, {
128 name: 'subjectKeyIdentifier'
110 - }]);
129 + }]
130 + if (subjectAltName != null) extensions.push(subjectAltName);
131 + cert.setExtensions(extensions);
132
133 cert.sign(rootcert.key, obj.forge.md.sha256.create());
134
@@ -155,6 +176,14 @@ module.exports.CertificateOperations = function () {
176 rcount++;
177 }
178
179 + // If the bin certificate already exist, load it
180 + if (obj.fileExists(directory + '/amtconsole-cert-public.crt') && obj.fileExists(directory + '/agentserver-cert-private.key')) {
181 + var amtConsoleCertificate = obj.fs.readFileSync(directory + '/amtconsole-cert-public.crt', 'utf8');
182 + var amtConsolePrivateKey = obj.fs.readFileSync(directory + '/amtconsole-cert-private.key', 'utf8');
183 + r.console = { cert: amtConsoleCertificate, key: amtConsolePrivateKey };
184 + rcount++;
185 + }
186 +
187 // If CA certificates are present, load them
188 var caok, caindex = 1, calist = [];
189 do {
@@ -177,7 +206,10 @@ module.exports.CertificateOperations = function () {
206 if (args.length > 2) organization = args[2];
207 }
208
180 - if (rcount == 4) {
209 + if (rcount == 5) {
210 + // Fetch the Intel AMT console name
211 + var consoleCertificate = obj.pki.certificateFromPem(r.console.cert);
212 + r.AmtConsoleName = consoleCertificate.subject.getField('CN').value;
213 // Fetch the name of the server
214 var webCertificate = obj.pki.certificateFromPem(r.web.cert);
215 r.CommonName = webCertificate.subject.getField('CN').value;
@@ -210,20 +242,49 @@ module.exports.CertificateOperations = function () {
242
243 // If the web certificate does not exist, create one
244 var webCertAndKey, webCertificate, webPrivateKey;
213 - webCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, commonName, country, organization);
214 - webCertificate = obj.pki.certificateToPem(webCertAndKey.cert);
215 - webPrivateKey = obj.pki.privateKeyToPem(webCertAndKey.key);
216 - obj.fs.writeFileSync(directory + '/webserver-cert-public.crt', webCertificate);
217 - obj.fs.writeFileSync(directory + '/webserver-cert-private.key', webPrivateKey);
218 -
245 + if (r.web == undefined) {
246 + webCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, commonName, country, organization);
247 + webCertificate = obj.pki.certificateToPem(webCertAndKey.cert);
248 + webPrivateKey = obj.pki.privateKeyToPem(webCertAndKey.key);
249 + obj.fs.writeFileSync(directory + '/webserver-cert-public.crt', webCertificate);
250 + obj.fs.writeFileSync(directory + '/webserver-cert-private.key', webPrivateKey);
251 + } else {
252 + // Keep the console certificate we have
253 + webCertAndKey = { cert: obj.pki.certificateFromPem(r.web.cert), key: obj.pki.privateKeyFromPem(r.web.key) };
254 + webCertificate = r.web.cert
255 + webPrivateKey = r.web.key
256 + }
257 +
258 // If the Intel AMT MPS certificate does not exist, create one
259 var mpsCertAndKey, mpsCertificate, mpsPrivateKey;
221 - mpsCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, commonName, country, organization);
222 - mpsCertificate = obj.pki.certificateToPem(mpsCertAndKey.cert);
223 - mpsPrivateKey = obj.pki.privateKeyToPem(mpsCertAndKey.key);
224 - obj.fs.writeFileSync(directory + '/mpsserver-cert-public.crt', mpsCertificate);
225 - obj.fs.writeFileSync(directory + '/mpsserver-cert-private.key', mpsPrivateKey);
226 -
260 + if (r.console == undefined) {
261 + mpsCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, commonName, country, organization);
262 + mpsCertificate = obj.pki.certificateToPem(mpsCertAndKey.cert);
263 + mpsPrivateKey = obj.pki.privateKeyToPem(mpsCertAndKey.key);
264 + obj.fs.writeFileSync(directory + '/mpsserver-cert-public.crt', mpsCertificate);
265 + obj.fs.writeFileSync(directory + '/mpsserver-cert-private.key', mpsPrivateKey);
266 + } else {
267 + // Keep the console certificate we have
268 + mpsCertAndKey = { cert: obj.pki.certificateFromPem(r.mps.cert), key: obj.pki.privateKeyFromPem(r.mps.key) };
269 + mpsCertificate = r.mps.cert
270 + mpsPrivateKey = r.mps.key
271 + }
272 +
273 + // If the Intel AMT console certificate does not exist, create one
274 + var consoleCertAndKey, consoleCertificate, consolePrivateKey, amtConsoleName = obj.xxRandomNonce(12);
275 + if (r.console == undefined) {
276 + 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 }); // Intel AMT Remote, Agent and Activation usages
277 + consoleCertificate = obj.pki.certificateToPem(consoleCertAndKey.cert);
278 + consolePrivateKey = obj.pki.privateKeyToPem(consoleCertAndKey.key);
279 + obj.fs.writeFileSync(directory + '/amtconsole-cert-public.crt', consoleCertificate);
280 + obj.fs.writeFileSync(directory + '/amtconsole-cert-private.key', consolePrivateKey);
281 + } else {
282 + // Keep the console certificate we have
283 + consoleCertAndKey = { cert: obj.pki.certificateFromPem(r.console.cert), key: obj.pki.privateKeyFromPem(r.console.key) };
284 + consoleCertificate = r.console.cert
285 + consolePrivateKey = r.console.key
286 + }
287 +
288 // If the mesh agent server certificate does not exist, create one
289 var agentCertAndKey, agentCertificate, agentPrivateKey;
290 if (r.agent == undefined) {
@@ -239,7 +300,7 @@ module.exports.CertificateOperations = function () {
300 agentPrivateKey = r.agent.key
301 }
302
242 - var r = { root: { cert: rootCertificate, key: rootPrivateKey }, web: { cert: webCertificate, key: webPrivateKey }, mps: { cert: mpsCertificate, key: mpsPrivateKey }, agent: { cert: agentCertificate, key: agentPrivateKey }, calist: calist, CommonName: commonName, RootName: rootName };
303 + 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 };
304 if (func != undefined) { func(r); }
305 return r;
306 }
mesherrors.txt
+38
@@ -151,3 +151,41 @@ ReferenceError: args is not defined
151 at InternalFieldObject.ondone (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshcentral.js:307:57)
152
153
154 +-------- 9/29/2017, 11:50:51 AM --------
155 +
156 +C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\node-forge\js\x509.js:2083
157 + throw error;
158 + ^
159 +
160 +Error: Extension ID not specified.
161 + at _fillMissingExtensionFields (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\node-forge\js\x509.js:2081:19)
162 + at Object.cert.setExtensions (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\node-forge\js\x509.js:983:7)
163 + at Object.obj.IssueWebServerCertificate (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\certoperations.js:108:14)
164 + at Object.obj.GetMeshServerCertificate (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\certoperations.js:256:33)
165 + at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshcentral.js:286:43
166 + at newArguments.(anonymous function) (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\executor.js:29:17)
167 + at Cursor.execFn (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:484:12)
168 + at callback (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\cursor.js:126:19)
169 + at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\cursor.js:193:12
170 + at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:329:14
171 +
172 +
173 +-------- 9/29/2017, 2:14:26 PM --------
174 +
175 +C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\webserver.js:866
176 + var tlsoptions = { secureProtocol: 'TLSv1_method', ciphers: 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AES:!aNULL:!MD5:!DSS', secureOptions: obj.constants.SSL_OP_NO_SSLv2 | obj.constants.SSL_OP_NO_SSLv3 | obj.constants.SSL_OP_NO_COMPRESSION | obj.constants.SSL_OP_CIPHER_SERVER_PREFERENCE, rejectUnauthorized: false, cert: obj.certificates.console.cert, key: obj.certificates.console.key };
177 + ^
178 +
179 +TypeError: Cannot read property 'SSL_OP_NO_SSLv2' of undefined
180 + at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\webserver.js:866:200
181 + at newArguments.(anonymous function) (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\executor.js:29:17)
182 + at Cursor.execFn (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:484:12)
183 + at callback (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\cursor.js:126:19)
184 + at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\cursor.js:193:12
185 + at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:329:14
186 + at Object.async.eachSeries (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\async\lib\async.js:130:20)
187 + at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:323:11
188 + at fn (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\async\lib\async.js:582:34)
189 + at Immediate._onImmediate (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\async\lib\async.js:498:34)
190 +
191 +
webserver.js
+5 -3
@@ -43,6 +43,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
43 obj.tls = require('tls');
44 obj.path = require('path');
45 obj.hash = require('./pass').hash;
46 + obj.constants = require('constants');
47 obj.bodyParser = require('body-parser');
48 obj.session = require('express-session');
49 obj.exphbs = require('express-handlebars');
@@ -751,7 +752,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
752
753 // TLSSocket to encapsulate TLS communication, which then tunneled via SerialTunnel an then wrapped through CIRA APF
754 var TLSSocket = require('tls').TLSSocket;
754 - var tlsock = new TLSSocket(ser, { secureProtocol: 'SSLv23_method', rejectUnauthorized: false }); // TLSv1_2_method
755 + var tlsoptions = { secureProtocol: 'TLSv1_method', ciphers: 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AES:!aNULL:!MD5:!DSS', secureOptions: obj.constants.SSL_OP_NO_SSLv2 | obj.constants.SSL_OP_NO_SSLv3 | obj.constants.SSL_OP_NO_COMPRESSION | obj.constants.SSL_OP_CIPHER_SERVER_PREFERENCE, rejectUnauthorized: false, cert: obj.certificates.console.cert, key: obj.certificates.console.key };
756 + var tlsock = new TLSSocket(ser, tlsoptions); // 'TLSv1_2_method' or 'SSLv23_method'
757 tlsock.on('error', function (err) { Debug(1, "CIRA TLS Connection Error ", err); });
758 tlsock.on('secureConnect', function () { Debug(2, "CIRA Secure TLS Connection"); ws.resume(); });
759
@@ -862,7 +864,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
864 ws.resume();
865 } else {
866 // If TLS is going to be used, setup a TLS socket
865 - ws.forwardclient = obj.tls.connect(port, node.host, { secureProtocol: 'TLSv1_method', rejectUnauthorized: false }, function () {
867 + var tlsoptions = { secureProtocol: 'TLSv1_method', ciphers: 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AES:!aNULL:!MD5:!DSS', secureOptions: obj.constants.SSL_OP_NO_SSLv2 | obj.constants.SSL_OP_NO_SSLv3 | obj.constants.SSL_OP_NO_COMPRESSION | obj.constants.SSL_OP_CIPHER_SERVER_PREFERENCE, rejectUnauthorized: false, cert: obj.certificates.console.cert, key: obj.certificates.console.key };
868 + ws.forwardclient = obj.tls.connect(port, node.host, tlsoptions, function () {
869 // The TLS connection method is the same as TCP, but located a bit differently.
870 Debug(2, 'TLS connected to ' + node.host + ':' + port + '.');
871 ws.forwardclient.xstate = 1;
@@ -1886,7 +1889,6 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
1889
1890 // Handle a request to download a mesh agent
1891 obj.handleMeshAgentRequest = function (req, res) {
1889 - if (checkUserIpAddress(req, res) == false) { return; }
1892 if (req.query.id != null) {
1893 // Send a specific mesh agent back
1894 var argentInfo = obj.parent.meshAgentBinaries[req.query.id];