Auto-fix certs with empty serial number.

Ylian Saint-Hilaire committed Sep 23, 2020 at 10:13 UTC 397c0142c764dbe4628617fef685f1d0b5c5be75
1 file changed +18 -7
certoperations.js
+18 -7
@@ -397,6 +397,14 @@ module.exports.CertificateOperations = function (parent) {
397 return false;
398 }
399
400 + // Return true if the certificate is valid
401 + obj.checkCertificate = function (pem, key) {
402 + var cert = null;
403 + try { cert = obj.pki.certificateFromPem(pem); } catch (ex) { return false; } // Unable to decode certificate
404 + if (cert.serialNumber == '') return false; // Empty serial number is not allowed.
405 + return true;
406 + }
407 +
408 // Returns the web server TLS certificate and private key, if not present, create demonstration ones.
409 obj.GetMeshServerCertificate = function (args, config, func) {
410 var i = 0;
@@ -426,11 +434,11 @@ module.exports.CertificateOperations = function (parent) {
434 // This option is required for newer versions of Intel AMT for CIRA/WS-EVENTS.
435 var xroot = obj.pki.certificateFromPem(rootCertificate);
436 var xext = xroot.getExtension('keyUsage');
429 - if ((xext == null) || (xext.keyCertSign !== true)) {
437 + if ((xext == null) || (xext.keyCertSign !== true) || (xroot.serialNumber == '')) {
438 // We need to fix this certificate
431 - console.log("Fixing root certificate to add signing key usage...");
439 obj.fs.writeFileSync(parent.getConfigFilePath('root-cert-public-backup.crt'), rootCertificate);
433 - xroot.setExtensions([{ name: 'basicConstraints', cA: true }, { name: 'subjectKeyIdentifier' }, { name: 'keyUsage', keyCertSign: true }]);
440 + if (xroot.serialNumber == '') { console.log("Fixing root certificate to add serial number..."); xroot.serialNumber = '' + require('crypto').randomBytes(4).readUInt32BE(0); }
441 + if ((xext == null) || (xext.keyCertSign !== true)) { console.log("Fixing root certificate to add signing key usage..."); xroot.setExtensions([{ name: 'basicConstraints', cA: true }, { name: 'subjectKeyIdentifier' }, { name: 'keyUsage', keyCertSign: true }]); }
442 var xrootPrivateKey = obj.pki.privateKeyFromPem(rootPrivateKey);
443 xroot.sign(xrootPrivateKey, obj.forge.md.sha384.create());
444 r.root.cert = obj.pki.certificateToPem(xroot);
@@ -441,42 +449,45 @@ module.exports.CertificateOperations = function (parent) {
449 // If web certificate exist, load it as default. This is useful for agent-only port. Load both certificate and private key
450 if (obj.fileExists('webserver-cert-public.crt') && obj.fileExists('webserver-cert-private.key')) {
451 r.webdefault = { cert: obj.fileLoad('webserver-cert-public.crt', 'utf8'), key: obj.fileLoad('webserver-cert-private.key', 'utf8') };
452 + if (obj.checkCertificate(r.webdefault.cert, r.webdefault.key) == false) { delete r.webdefault; }
453 }
454
455 if (args.tlsoffload) {
456 // If the web certificate already exist, load it. Load just the certificate since we are in TLS offload situation
457 if (obj.fileExists('webserver-cert-public.crt')) {
458 r.web = { cert: obj.fileLoad('webserver-cert-public.crt', 'utf8') };
450 - rcount++;
459 + if (obj.checkCertificate(r.web.cert, null) == false) { delete r.web; } else { rcount++; }
460 }
461 } else {
462 // If the web certificate already exist, load it. Load both certificate and private key
463 if (obj.fileExists('webserver-cert-public.crt') && obj.fileExists('webserver-cert-private.key')) {
464 r.web = { cert: obj.fileLoad('webserver-cert-public.crt', 'utf8'), key: obj.fileLoad('webserver-cert-private.key', 'utf8') };
456 - rcount++;
465 + if (obj.checkCertificate(r.web.cert, r.web.key) == false) { delete r.web; } else { rcount++; }
466 }
467 }
468
469 // If the mps certificate already exist, load it
470 if (obj.fileExists('mpsserver-cert-public.crt') && obj.fileExists('mpsserver-cert-private.key')) {
471 r.mps = { cert: obj.fileLoad('mpsserver-cert-public.crt', 'utf8'), key: obj.fileLoad('mpsserver-cert-private.key', 'utf8') };
463 - rcount++;
472 + if (obj.checkCertificate(r.mps.cert, r.mps.key) == false) { delete r.mps; } else { rcount++; }
473 }
474
475 // If the agent certificate already exist, load it
476 if (obj.fileExists("agentserver-cert-public.crt") && obj.fileExists("agentserver-cert-private.key")) {
477 r.agent = { cert: obj.fileLoad("agentserver-cert-public.crt", 'utf8'), key: obj.fileLoad("agentserver-cert-private.key", 'utf8') };
469 - rcount++;
478 + if (obj.checkCertificate(r.agent.cert, r.agent.key) == false) { delete r.agent; } else { rcount++; }
479 }
480
481 // If the swarm server certificate exist, load it (This is an optional certificate)
482 if (obj.fileExists('swarmserver-cert-public.crt') && obj.fileExists('swarmserver-cert-private.key')) {
483 r.swarmserver = { cert: obj.fileLoad('swarmserver-cert-public.crt', 'utf8'), key: obj.fileLoad('swarmserver-cert-private.key', 'utf8') };
484 + if (obj.checkCertificate(r.swarmserver.cert, r.swarmserver.key) == false) { delete r.swarmserver; }
485 }
486
487 // If the swarm server root certificate exist, load it (This is an optional certificate)
488 if (obj.fileExists('swarmserverroot-cert-public.crt')) {
489 r.swarmserverroot = { cert: obj.fileLoad('swarmserverroot-cert-public.crt', 'utf8') };
490 + if (obj.checkCertificate(r.swarmserverroot.cert, null) == false) { delete r.swarmserverroot; }
491 }
492
493 // If CA certificates are present, load them