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];