More work on AMT 802.1x support.

Ylian Saint-Hilaire committed Apr 6, 2022 at 19:55 UTC 90d2d7b21b9b93668311c41988563e5346873de7
2 files changed +158 -50
amt/amt.js
+4 -1
@@ -304,7 +304,10 @@ function AmtStackCreateService(wsmanStack) {
304 obj.AMT_TimeSynchronizationService_SetHighAccuracyTimeSynch = function (Ta0, Tm1, Tm2, callback_func, tag) { obj.Exec("AMT_TimeSynchronizationService", "SetHighAccuracyTimeSynch", { "Ta0": Ta0, "Tm1": Tm1, "Tm2": Tm2 }, callback_func, tag); }
305 obj.AMT_UserInitiatedConnectionService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_UserInitiatedConnectionService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
306 obj.AMT_WebUIService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func, tag) { obj.Exec("AMT_WebUIService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func, tag); }
307 - obj.AMT_WiFiPortConfigurationService_AddWiFiSettings = function (WiFiEndpoint, WiFiEndpointSettingsInput, IEEE8021xSettingsInput, ClientCredential, CACredential, callback_func) { obj.ExecWithXml("AMT_WiFiPortConfigurationService", "AddWiFiSettings", { "WiFiEndpoint": WiFiEndpoint, "WiFiEndpointSettingsInput": WiFiEndpointSettingsInput, "IEEE8021xSettingsInput": IEEE8021xSettingsInput, "ClientCredential": ClientCredential, "CACredential": CACredential }, callback_func); }
307 + obj.AMT_WiFiPortConfigurationService_AddWiFiSettings = function (WiFiEndpoint, WiFiEndpointSettingsInput, IEEE8021xSettingsInput, ClientCredential, CACredential, callback_func) {
308 + console.log(JSON.stringify({ "WiFiEndpoint": WiFiEndpoint, "WiFiEndpointSettingsInput": WiFiEndpointSettingsInput, "IEEE8021xSettingsInput": IEEE8021xSettingsInput, "ClientCredential": ClientCredential, "CACredential": CACredential }, null, 2));
309 + obj.ExecWithXml("AMT_WiFiPortConfigurationService", "AddWiFiSettings", { "WiFiEndpoint": WiFiEndpoint, "WiFiEndpointSettingsInput": WiFiEndpointSettingsInput, "IEEE8021xSettingsInput": IEEE8021xSettingsInput, "ClientCredential": ClientCredential, "CACredential": CACredential }, callback_func);
310 + }
311 obj.AMT_WiFiPortConfigurationService_UpdateWiFiSettings = function (WiFiEndpointSettings, WiFiEndpointSettingsInput, IEEE8021xSettingsInput, ClientCredential, CACredential, callback_func) { obj.ExecWithXml("AMT_WiFiPortConfigurationService", "UpdateWiFiSettings", { "WiFiEndpointSettings": WiFiEndpointSettings, "WiFiEndpointSettingsInput": WiFiEndpointSettingsInput, "IEEE8021xSettingsInput": IEEE8021xSettingsInput, "ClientCredential": ClientCredential, "CACredential": CACredential }, callback_func); }
312 obj.AMT_WiFiPortConfigurationService_DeleteAllITProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllITProfiles", { "_method_dummy": _method_dummy }, callback_func); }
313 obj.AMT_WiFiPortConfigurationService_DeleteAllUserProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllUserProfiles", { "_method_dummy": _method_dummy }, callback_func); }
amtmanager.js
+154 -49
@@ -737,23 +737,26 @@ module.exports.CreateAmtManager = function (parent) {
737 attemptCiraSync(dev, function (dev) {
738 // Check Intel AMT settings
739 attemptSettingsSync(dev, function (dev) {
740 - // See if we need to get hardware inventory
741 - attemptFetchHardwareInventory(dev, function (dev) {
742 - dev.consoleMsg('Done.');
743 -
744 - // Remove from task limiter if needed
745 - if (dev.taskid != null) { obj.parent.taskLimiter.completed(dev.taskid); delete dev.taskLimiter; }
746 -
747 - if (dev.connType != 2) {
748 - // Start power polling if not connected to LMS
749 - var ppfunc = function powerPoleFunction() { fetchPowerState(powerPoleFunction.dev); }
750 - ppfunc.dev = dev;
751 - dev.polltimer = new setTimeout(ppfunc, 290000); // Poll for power state every 4 minutes 50 seconds.
752 - fetchPowerState(dev);
753 - } else {
754 - // For LMS connections, close now.
755 - dev.controlMsg({ action: 'close' });
756 - }
740 + // Clean unused certificates
741 + attemptCleanCertsSync(dev, function (dev) {
742 + // See if we need to get hardware inventory
743 + attemptFetchHardwareInventory(dev, function (dev) {
744 + dev.consoleMsg('Done.');
745 +
746 + // Remove from task limiter if needed
747 + if (dev.taskid != null) { obj.parent.taskLimiter.completed(dev.taskid); delete dev.taskLimiter; }
748 +
749 + if (dev.connType != 2) {
750 + // Start power polling if not connected to LMS
751 + var ppfunc = function powerPoleFunction() { fetchPowerState(powerPoleFunction.dev); }
752 + ppfunc.dev = dev;
753 + dev.polltimer = new setTimeout(ppfunc, 290000); // Poll for power state every 4 minutes 50 seconds.
754 + fetchPowerState(dev);
755 + } else {
756 + // For LMS connections, close now.
757 + dev.controlMsg({ action: 'close' });
758 + }
759 + });
760 });
761 });
762 });
@@ -1394,9 +1397,7 @@ module.exports.CreateAmtManager = function (parent) {
1397 // Remove any unlinked private keys
1398 for (var i in xxCertPrivateKeys) {
1399 if (!xxCertPrivateKeys[i].XCert) {
1397 - console.log('PrivateKey-Removing');
1400 dev.amtstack.Delete('AMT_PublicPrivateKeyPair', { 'InstanceID': xxCertPrivateKeys[i]['InstanceID'] }, function (stack, name, response, status) {
1399 - console.log('PrivateKey-Removed');
1401 //if (status == 200) { dev.consoleMsg("Removed unassigned private key pair."); }
1402 });
1403 }
@@ -1550,6 +1551,8 @@ module.exports.CreateAmtManager = function (parent) {
1551
1552 // Check 802.1x root certificate
1553 function perform8021xRootCertCheck(dev) {
1554 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1555 +
1556 // Check if there is a root certificate to add, if we already have it, get the instance id.
1557 if (dev.netAuthCredentials.rootcert) {
1558 var matchingRootCertId = null;
@@ -1586,6 +1589,8 @@ module.exports.CreateAmtManager = function (parent) {
1589
1590 // Check 802.1x client certificate
1591 function perform8021xClientCertCheck(dev) {
1592 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1593 +
1594 if (dev.netAuthCredentials.certificate) {
1595 // The new 802.1x profile includes a new certificate, add it now before adding the 802.1x profiles
1596 // dev.netAuthCredentials.certificate must be in DER encoded format
@@ -1618,6 +1623,8 @@ module.exports.CreateAmtManager = function (parent) {
1623
1624 // Set the 802.1x wired profile
1625 function attempt8021xSyncEx(dev, devNetAuthData) {
1626 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1627 +
1628 // Unpack
1629 const domain = devNetAuthData.domain;
1630 const devNetAuthProfile = devNetAuthData.devNetAuthProfile;
@@ -1677,12 +1684,9 @@ module.exports.CreateAmtManager = function (parent) {
1684 }
1685 }
1686
1680 - console.log('netAuthProfile', netAuthProfile);
1681 -
1687 dev.amtstack.Put('AMT_8021XProfile', netAuthProfile, function (stack, name, responses, status) {
1688 const dev = stack.dev;
1689 if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1685 - console.log('AMT_8021XProfile-PUT', responses);
1690 if (status == 200) { dev.consoleMsg("802.1x wired profile set."); } else { dev.consoleMsg("Unable to set 802.1x wired profile."); }
1691 attemptWifiSyncEx(dev, devNetAuthData);
1692 });
@@ -1693,6 +1697,8 @@ module.exports.CreateAmtManager = function (parent) {
1697 }
1698
1699 function attemptWifiSyncEx(dev, devNetAuthData) {
1700 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1701 +
1702 // Unpack
1703 const domain = devNetAuthData.domain;
1704 const devNetAuthProfile = devNetAuthData.devNetAuthProfile;
@@ -1705,7 +1711,7 @@ module.exports.CreateAmtManager = function (parent) {
1711
1712 if (wirelessConfig) {
1713 // Add missing WIFI profiles
1708 - var nextPriority = 0;
1714 + var nextPriority = 1;
1715 for (var i in profilesToAdd) {
1716 while (prioritiesInUse.indexOf(nextPriority) >= 0) { nextPriority++; } // Figure out the next available priority slot.
1717 var profileToAdd = profilesToAdd[i];
@@ -1741,8 +1747,26 @@ module.exports.CreateAmtManager = function (parent) {
1747 if (domain.amtmanager['802.1x'].password) { netAuthProfile['Password'] = domain.amtmanager['802.1x'].password; }
1748 if (domain.amtmanager['802.1x'].domain) { netAuthProfile['Domain'] = domain.amtmanager['802.1x'].domain; }
1749 if (domain.amtmanager['802.1x'].authenticationprotocol > 3) { domain.amtmanager['ProtectedAccessCredential'] = profileToAdd['802.1x'].protectedaccesscredentialhex; netAuthProfile['PACPassword'] = profileToAdd['802.1x'].pacpassword; }
1744 - //if (parseInt(Q('idx_d12clientcert').value) >= 0) { netAuthSettingsClientCert = '<Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing"><ResourceURI xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">http://intel.com/wbem/wscim/1/amt-schema/1/AMT_PublicKeyCertificate</ResourceURI><SelectorSet xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"><Selector Name="InstanceID">' + xxCertificates[parseInt(Q('idx_d12clientcert').value)]['InstanceID'] + '</Selector></SelectorSet></ReferenceParameters>'; }
1745 - //if (parseInt(Q('idx_d12servercert').value) >= 0) { netAuthSettingsServerCaCert = '<Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing"><ResourceURI xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">http://intel.com/wbem/wscim/1/amt-schema/1/AMT_PublicKeyCertificate</ResourceURI><SelectorSet xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"><Selector Name="InstanceID">' + xxCertificates[parseInt(Q('idx_d12servercert').value)]['InstanceID'] + '</Selector></SelectorSet></ReferenceParameters>'; }
1750 +
1751 + /*
1752 + // Setup Client Certificate
1753 + if (devNetAuthData.certInstanceId) {
1754 + netAuthSettingsClientCert = '<a:Address>/wsman</a:Address><a:ReferenceParameters><w:ResourceURI>' + dev.amtstack.CompleteName('AMT_PublicKeyCertificate') + '</w:ResourceURI><w:SelectorSet><w:Selector Name="InstanceID">' + devNetAuthData.certInstanceId + '</w:Selector></w:SelectorSet></a:ReferenceParameters>';
1755 + }
1756 + // Setup Server Certificate
1757 + if (devNetAuthData.rootCertInstanceId) {
1758 + netAuthSettingsServerCaCert = '<a:Address>/wsman</a:Address><a:ReferenceParameters><w:ResourceURI>' + dev.amtstack.CompleteName('AMT_PublicKeyCertificate') + '</w:ResourceURI><w:SelectorSet><w:Selector Name="InstanceID">' + devNetAuthData.rootCertInstanceId + '</w:Selector></w:SelectorSet></a:ReferenceParameters>';
1759 + }
1760 + */
1761 +
1762 + // Setup Client Certificate
1763 + if (devNetAuthData.certInstanceId) {
1764 + netAuthSettingsClientCert = '<Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing"><ResourceURI xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">http://intel.com/wbem/wscim/1/amt-schema/1/AMT_PublicKeyCertificate</ResourceURI><SelectorSet xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"><Selector Name="InstanceID">' + devNetAuthData.certInstanceId + '</Selector></SelectorSet></ReferenceParameters>';
1765 + }
1766 + // Setup Server Certificate
1767 + if (devNetAuthData.rootCertInstanceId) {
1768 + netAuthSettingsServerCaCert = '<Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing"><ResourceURI xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">http://intel.com/wbem/wscim/1/amt-schema/1/AMT_PublicKeyCertificate</ResourceURI><SelectorSet xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"><Selector Name="InstanceID">' + devNetAuthData.rootCertInstanceId + '</Selector></SelectorSet></ReferenceParameters>';
1769 + }
1770
1771 // If we have credentials from MeshCentral Satelite, use that
1772 if (dev.netAuthCredentials != null) {
@@ -1753,43 +1777,64 @@ module.exports.CreateAmtManager = function (parent) {
1777 }
1778 }
1779 prioritiesInUse.push(nextPriority); // Occupy the priority slot and add the WIFI profile.
1756 - dev.amtstack.AMT_WiFiPortConfigurationService_AddWiFiSettings(wifiep, wifiepsettinginput, netAuthProfile, netAuthSettingsClientCert, netAuthSettingsServerCaCert, function (stack, name, responses, status) { });
1757 - }
1780 + console.log('AddWiFiSettings1');
1781
1759 - // Check if local WIFI profile sync is enabled, if not, enabled it.
1760 - if ((responses['AMT_WiFiPortConfigurationService'] != null) && (responses['AMT_WiFiPortConfigurationService'].response != null) && (responses['AMT_WiFiPortConfigurationService'].response['localProfileSynchronizationEnabled'] == 0)) {
1761 - responses['AMT_WiFiPortConfigurationService'].response['localProfileSynchronizationEnabled'] = 1;
1762 - dev.amtstack.Put('AMT_WiFiPortConfigurationService', responses['AMT_WiFiPortConfigurationService'].response, function (stack, name, response, status) {
1763 - if (status != 200) { dev.consoleMsg("Unable to enable local WIFI profile sync."); } else { dev.consoleMsg("Enabled local WIFI profile sync."); }
1782 + dev.amtstack.AMT_WiFiPortConfigurationService_AddWiFiSettings(wifiep, wifiepsettinginput, netAuthProfile, netAuthSettingsClientCert, netAuthSettingsServerCaCert, function (stack, name, response, status) {
1783 + if (status != 200) { dev.consoleMsg("Unable to set WIFI profile."); }
1784 + console.log('AddWiFiSettings2', status, response);
1785 });
1786 }
1787
1767 - // Change the WIFI state if needed. Right now, we always enable it.
1768 - // WifiState = { 3: "Disabled", 32768: "Enabled in S0", 32769: "Enabled in S0, Sx/AC" };
1769 - var wifiState = 32769; // For now, always enable WIFI
1770 - if (responses['CIM_WiFiPort'].responses.Body.EnabledState != 32769) {
1771 - if (wifiState == 3) {
1772 - dev.amtstack.CIM_WiFiPort_RequestStateChange(wifiState, null, function (stack, name, responses, status) {
1773 - const dev = stack.dev;
1774 - if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1775 - if (status == 200) { dev.consoleMsg("Disabled WIFI."); }
1776 - });
1777 - } else {
1778 - dev.amtstack.CIM_WiFiPort_RequestStateChange(wifiState, null, function (stack, name, responses, status) {
1779 - const dev = stack.dev;
1780 - if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1781 - if (status == 200) { dev.consoleMsg("Enabled WIFI."); }
1782 - });
1783 - }
1788 + // Complete WIFI configuration
1789 + attemptWifiSyncEx2(dev, devNetAuthData);
1790 + } else {
1791 + // Done
1792 + devTaskCompleted(dev);
1793 + }
1794 + }
1795 +
1796 + function attemptWifiSyncEx2(dev, devNetAuthData) {
1797 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1798 +
1799 + const responses = devNetAuthData.responses;
1800 +
1801 + // Check if local WIFI profile sync is enabled, if not, enabled it.
1802 + if ((responses['AMT_WiFiPortConfigurationService'] != null) && (responses['AMT_WiFiPortConfigurationService'].response != null) && (responses['AMT_WiFiPortConfigurationService'].response['localProfileSynchronizationEnabled'] == 0)) {
1803 + responses['AMT_WiFiPortConfigurationService'].response['localProfileSynchronizationEnabled'] = 1;
1804 + dev.amtstack.Put('AMT_WiFiPortConfigurationService', responses['AMT_WiFiPortConfigurationService'].response, function (stack, name, response, status) {
1805 + if (status != 200) { dev.consoleMsg("Unable to enable local WIFI profile sync."); } else { dev.consoleMsg("Enabled local WIFI profile sync."); }
1806 + });
1807 + }
1808 +
1809 + // Change the WIFI state if needed. Right now, we always enable it.
1810 + // WifiState = { 3: "Disabled", 32768: "Enabled in S0", 32769: "Enabled in S0, Sx/AC" };
1811 + var wifiState = 32769; // For now, always enable WIFI
1812 + if (responses['CIM_WiFiPort'].responses.Body.EnabledState != 32769) {
1813 + if (wifiState == 3) {
1814 + dev.amtstack.CIM_WiFiPort_RequestStateChange(wifiState, null, function (stack, name, responses, status) {
1815 + const dev = stack.dev;
1816 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1817 + if (status == 200) { dev.consoleMsg("Disabled WIFI."); }
1818 + });
1819 + } else {
1820 + dev.amtstack.CIM_WiFiPort_RequestStateChange(wifiState, null, function (stack, name, responses, status) {
1821 + const dev = stack.dev;
1822 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1823 + if (status == 200) { dev.consoleMsg("Enabled WIFI."); }
1824 + });
1825 }
1826 }
1827
1828 + console.log('ALL GOOD');
1829 +
1830 // Done
1831 devTaskCompleted(dev);
1832 }
1833
1834 // Request for a RSA key pair generation. This will be used to generate the 802.1x certificate
1835 function attempt8021xKeyGeneration(dev) {
1836 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1837 +
1838 dev.amtstack.AMT_PublicKeyManagementService_GenerateKeyPair(0, 2048, function (stack, name, response, status) {
1839 if ((status != 200) || (response.Body['ReturnValue'] != 0)) {
1840 // Failed to generate a key pair
@@ -1820,6 +1865,8 @@ module.exports.CreateAmtManager = function (parent) {
1865
1866 // 802.1x request to process a Certificate Signing Request, we ask Intel AMT to sign the request
1867 function attempt8021xCRSRequest(dev, event) {
1868 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1869 +
1870 if ((event.response == null) || (event.response.keyInstanceId == null)) return;
1871 var keyPair = '<a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address><a:ReferenceParameters><w:ResourceURI>http://intel.com/wbem/wscim/1/amt-schema/1/AMT_PublicPrivateKeyPair</w:ResourceURI><w:SelectorSet><w:Selector Name="InstanceID">' + event.response.keyInstanceId + '</w:Selector></w:SelectorSet></a:ReferenceParameters>'; // keyPair EPR Reference
1872 var signingAlgorithm = 1; // 0 = SHA1-RSA, 1 = SHA256-RSA
@@ -2214,6 +2261,64 @@ module.exports.CreateAmtManager = function (parent) {
2261 }
2262
2263
2264 + //
2265 + // Intel AMT Certificate cleanup
2266 + //
2267 +
2268 + // Remove any unused, non-trusted certificates
2269 + function attemptCleanCertsSync(dev, func) {
2270 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
2271 + dev.amtstack.BatchEnum(null, ['AMT_PublicKeyCertificate', 'AMT_PublicPrivateKeyPair'], function (stack, name, responses, status) {
2272 + const dev = stack.dev;
2273 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
2274 + const domain = parent.config.domains[dev.domainid];
2275 + if ((responses['AMT_PublicKeyCertificate'].status != 200) || (responses['AMT_PublicKeyCertificate'].status != 200)) { func(dev); return; } // We can't get the certificate list, fail and carry on.
2276 +
2277 + // Sort out the certificates
2278 + var xxCertificates = responses['AMT_PublicKeyCertificate'].responses;
2279 + var xxCertPrivateKeys = responses['AMT_PublicPrivateKeyPair'].responses;
2280 + for (var i in xxCertificates) {
2281 + xxCertificates[i].TrustedRootCertficate = (xxCertificates[i]['TrustedRootCertficate'] == true);
2282 + xxCertificates[i].X509CertificateBin = Buffer.from(xxCertificates[i]['X509Certificate'], 'base64').toString('binary');
2283 + xxCertificates[i].XIssuer = parseCertName(xxCertificates[i]['Issuer']);
2284 + xxCertificates[i].XSubject = parseCertName(xxCertificates[i]['Subject']);
2285 + }
2286 + amtcert_linkCertPrivateKey(xxCertificates, xxCertPrivateKeys); // This links all certificates and private keys
2287 + dev.certDeleteTasks = 0;
2288 +
2289 + // Remove any unlinked private keys
2290 + for (var i in xxCertPrivateKeys) {
2291 + if (!xxCertPrivateKeys[i].XCert) {
2292 + dev.certDeleteTasks++;
2293 + dev.amtstack.Delete('AMT_PublicPrivateKeyPair', { 'InstanceID': xxCertPrivateKeys[i]['InstanceID'] }, function (stack, name, response, status) {
2294 + //if (status == 200) { dev.consoleMsg("Removed unassigned private key pair."); }
2295 + if (--dev.certDeleteTasks == 0) { delete dev.certDeleteTasks; func(dev); }
2296 + });
2297 + }
2298 + }
2299 +
2300 + // Try to remove all untrusted certificates
2301 + for (var i in xxCertificates) {
2302 + if (xxCertificates[i].TrustedRootCertficate == false) {
2303 + var privateKeyInstanceId = null;
2304 + if (xxCertificates[i].XPrivateKey) { privateKeyInstanceId = { 'InstanceID': xxCertificates[i].XPrivateKey['InstanceID'] }; }
2305 + dev.certDeleteTasks++;
2306 + dev.amtstack.Delete('AMT_PublicKeyCertificate', { 'InstanceID': xxCertificates[i]['InstanceID'] }, function (stack, name, response, status, tag) {
2307 + if ((status == 200) && (tag != null)) {
2308 + // If there is a private key, delete it.
2309 + dev.amtstack.Delete('AMT_PublicPrivateKeyPair', tag, function () {
2310 + if (--dev.certDeleteTasks == 0) { delete dev.certDeleteTasks; func(dev); }
2311 + }, 0, 1);
2312 + } else {
2313 + if (--dev.certDeleteTasks == 0) { delete dev.certDeleteTasks; func(dev); }
2314 + }
2315 + }, privateKeyInstanceId);
2316 + }
2317 + }
2318 + });
2319 + }
2320 +
2321 +
2322 //
2323 // Intel AMT Hardware Inventory and Networking
2324 //