Improved support for provisioning certificates with different length chains

mprimros committed May 24, 2019 at 16:06 UTC 8d2e87685c7fe08825f4c13b311327a74d79f565
1 file changed +43 -48
agents/meshcmd.js
+43 -48
@@ -833,37 +833,35 @@ function activeToACMEx(fwNonce) {
833 if (message.provCertObj !== undefined) {
834 activeToACMEx1(message, function (stack, name, responses, status, message) {
835 if (status !== 200) {
836 - if (status == 2) {
837 - console.log((new Date()) + ' AMT already provisioned.Exiting ' + status);
838 - socket.write({ "Type": "finish", "Body": "failed" });
839 - } else {
840 - console.log((new Date()) + ' Failed to fetch activation status, status ' + status);
841 - socket.write({ "Type": "finish", "Body": "failed" });
836 + if (status == 2) {
837 + console.log((new Date()) + ' AMT already provisioned.Exiting ' + status);
838 + socket.write({ "Type": "finish", "Body": "failed" });
839 + }
840 + else {
841 + console.log((new Date()) + ' Failed to fetch activation status, status ' + status);
842 + socket.write({ "Type": "finish", "Body": "failed" });
843 }
844 socket.end();
845 exit(status);
845 - }
846 - else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) {
847 - console.log((new Date()) + ' Admin control mode activation not allowed');
846 + } else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) {
847 + console.log((new Date()) + ' Admin control mode activation not allowed');
848 socket.write({ "Type": "finish", "Body": "failed" });
849 socket.end();
850 exit(status);
851 - } else {
852 - console.log((new Date()) + ' Certificate Injection Successful');
851 + } else {
852 + console.log((new Date()) + ' Certificate Injection Successful');
853 activeToACMEx2(message.digitalSignature, message.mcNonce, message.amtPassword, responses, function(stack, name, responses, status){
854 - if (status != 200) {
855 - console.log((new Date()) + ' Failed to activate, status ' + status);
856 - console.log(JSON.stringify(responses));
857 - socket.write({ "Type": "finish", "Body": "failed" });
858 - }
859 - else if (responses.Body.ReturnValue != 0) {
854 + if (status != 200) {
855 + console.log((new Date()) + ' Failed to activate, status ' + status);
856 + console.log(JSON.stringify(responses));
857 + socket.write({ "Type": "finish", "Body": "failed" });
858 + } else if (responses.Body.ReturnValue != 0) {
859 console.log((new Date()) + ' Admin control mode activation failed: ' + responses.Body.ReturnValueStr);
861 - socket.write({ "Type": "finish", "Body": "failed" });
862 - }
863 - else {
860 + socket.write({ "Type": "finish", "Body": "failed" });
861 + } else {
862 console.log((new Date()) + ' AMT Provisioning Success');
865 - socket.write({"Type":"finish", "Body": "success"});
866 - socket.end();
863 + socket.write({"Type":"finish", "Body": "success"});
864 + socket.end();
865 exit(0);
866 }
867 socket.end();
@@ -888,36 +886,14 @@ function activeToACMEx(fwNonce) {
886 // Detects AMT provisioning state and injects the certificate chain into AMT firmware
887 function activeToACMEx1(data, callback) {
888 if (mestate.ProvisioningState.state == 0) {
891 - console.log((new Date()) + ' Performing full provisioning flow.');
889 + console.log((new Date()) + ' Performing ACM provisioning.');
890 // Perform full provisioning -- AMT was fully unprovisioned
893 - osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(data.provCertObj.leaf, true, false, function (stack, name, responses, status) {
891 + injectCert(0, data, function (stack, name, responses, status, data) {
892 if (status !== 200) { exit(status); return; }
893 else if (responses['Body']['ReturnValue'] !== 0) { exit(responses['Body']['ReturnValueStr']); return; }
894 else if (responses['Body']['ReturnValue'] == 0) {
897 - console.log((new Date()) + ' Leaf Cert Injection: ' + responses['Body']['ReturnValueStr']);
898 - osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(data.provCertObj.inter3, false, false, function (stack, name, responses, status) {
899 - if (status !== 200) { exit(status); return; }
900 - else if (responses['Body']['ReturnValue'] !== 0) { exit(responses['Body']['ReturnValueStr']); return; }
901 - else if (responses['Body']['ReturnValue'] == 0) {
902 - console.log((new Date()) + ' Intermediate 3 Cert Injection: ' + responses['Body']['ReturnValueStr']);
903 - osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(data.provCertObj.inter2, false, false, function (stack, name, responses, status) {
904 - if (status !== 200) { exit(status); return; }
905 - else if (responses['Body']['ReturnValue'] !== 0) { exit(responses['Body']['ReturnValueStr']); return; }
906 - else if (responses['Body']['ReturnValue'] == 0) {
907 - console.log((new Date()) + ' Intermediate 2 Cert Injection: ' + responses['Body']['ReturnValueStr']);
908 - osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(data.provCertObj.root, false, true, function (stack, name, responses, status) {
909 - if (status !== 200) { exit(status); return; }
910 - else if (responses['Body']['ReturnValue'] !== 0) { exit(responses['Body']['ReturnValueStr']); return; }
911 - else if (responses['Body']['ReturnValue'] == 0) {
912 - console.log((new Date()) + ' Root Cert Injection: ' + responses['Body']['ReturnValueStr']);
913 - osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], function(stack, name, responses, status){
914 - callback(stack, name, responses, status, data);
915 - });
916 - } else { console.log((new Date()) + ' Oops, I fell through the world!'); exit(1); }
917 - });
918 - }
919 - });
920 - }
895 + osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], function (stack, name, responses, status) {
896 + callback(stack, name, responses, status, data);
897 });
898 }
899 });
@@ -934,6 +910,25 @@ function activeToACMEx1(data, callback) {
910 }
911 }
912
913 +function injectCert(index, cert, callback, stack, name, responses, status) {
914 + var leaf = false;
915 + var root = false;
916 + if (index == 0) { leaf = true; }
917 + if (index == cert.provCertObj.certChain.length - 1) { root = true; }
918 + if (index < cert.provCertObj.certChain.length){
919 + if (cert.provCertObj.certChain[index] !== undefined){
920 + osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(cert.provCertObj.certChain[index], leaf, root, function (stack, name, responses, status) {
921 + if (status !== 200) { exit(status); return; }
922 + else if (responses['Body']['ReturnValue'] !== 0) { exit(responses['Body']['ReturnValueStr']); return; }
923 + else if (responses['Body']['ReturnValue'] == 0) {
924 + index++;
925 + injectCert(index, cert, callback, stack, name, responses, status);
926 + }
927 + });
928 + }
929 + } else { callback(stack, name, responses, status, cert); }
930 +}
931 +
932 // Sends the password hash, mcnonce, and digital signature to complete the admin control mode provisioning
933 function activeToACMEx2(signature, mcnonce, amtpassword, responses, callback) {
934 var passwordhash = md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + amtpassword).substring(0, 32);