internal static bool CheckIfTwinPropertiesAreSigned(TwinCollection twinDesiredProperties) { // If there is no integrity section in the desired twin properties then it is unsigned twin JToken integrity = JObject.Parse(twinDesiredProperties.ToString())["integrity"]; return(integrity != null && integrity.HasValues != false); }
internal static bool ExtractHubTwinAndVerify(TwinCollection twinDesiredProperties) { try { // Extract Desired properties JObject desiredProperties = new JObject(); JObject twinJobject = JObject.Parse(twinDesiredProperties.ToString()); desiredProperties["routes"] = twinJobject["routes"]; desiredProperties["schemaVersion"] = twinJobject["schemaVersion"]; desiredProperties["storeAndForwardConfiguration"] = twinJobject["storeAndForwardConfiguration"]; // Extract Integrity section JToken integrity = twinJobject["integrity"]; JToken header = integrity["header"]; JToken signerCertJtoken = integrity["header"]["signercert"]; string combinedCert = signerCertJtoken.Aggregate(string.Empty, (res, next) => res + next); X509Certificate2 signerCert = new X509Certificate2(Convert.FromBase64String(combinedCert)); JToken signature = integrity["signature"]["bytes"]; // Extract Signature and algorithm byte[] signatureBytes = Convert.FromBase64String(signature.ToString()); JToken algo = integrity["signature"]["algorithm"]; KeyValuePair <string, HashAlgorithmName> algoResult = SignatureValidator.ParseAlgorithm(algo.ToString()); Events.ExtractHubTwinSucceeded(); return(SignatureValidator.VerifySignature(desiredProperties.ToString(), header.ToString(), signatureBytes, signerCert, algoResult.Key, algoResult.Value)); } catch (Exception ex) { Events.ExtractHubTwinAndVerifyFailed(ex); throw ex; } }
static Task OnDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext) { Console.WriteLine("Received TWIN: " + desiredProperties.ToString()); if (desiredProperties.Contains("RESTTargetURL")) { RESTTargetURL = (string)desiredProperties["RESTTargetURL"]; } if (desiredProperties.Contains("RESTTargetLocation")) { RESTTargetLocation = (string)desiredProperties["RESTTargetLocation"]; } if (desiredProperties.Contains("POLLINGInterval")) { POLLINGInterval = (int)desiredProperties["POLLINGInterval"]; } // also reporting our Reported properties JObject twinResponse = new JObject(); twinResponse["RESTTargetURL"] = RESTTargetURL; twinResponse["RESTTargetLocation"] = RESTTargetLocation; twinResponse["POLLINGInterval"] = POLLINGInterval; Console.WriteLine("Sending TWIN: " + twinResponse.ToString()); TwinCollection patch = new TwinCollection(twinResponse.ToString()); ioTHubModuleClient.UpdateReportedPropertiesAsync(patch); return(Task.CompletedTask); }
internal bool CheckIfManifestSigningIsEnabled(TwinCollection twinDesiredProperties) { // If there is no integrity section in the desired twin properties and the manifest trust bundle is not configured then manifest signing is turned off // If we have integrity section or the configuration of manifest trust bundle then manifest signing is turned on JToken integrity = JObject.Parse(twinDesiredProperties.ToString())["integrity"]; return(this.manifestTrustBundle.HasValue || (integrity != null && integrity.HasValues)); }
private Task OnReportedPropertyUpdate(TwinCollection reportedProperties) { Debug.WriteLine("Test - OnReportedPropertyUpdate() -- Received Start ----------------------------------"); Debug.WriteLine(reportedProperties.ToString()); Debug.WriteLine("Test - OnReportedPropertyUpdate() -- Received End ------------------------------------"); if (_actualReportedState == null) { // Create new... JObject reportedObject = new JObject(); foreach (KeyValuePair <string, object> pair in reportedProperties) { reportedObject[pair.Key] = (JToken)pair.Value; } JObject propertiesObject = new JObject(); propertiesObject.Add(JsonReported, reportedObject); JObject rootObject = new JObject(); rootObject.Add(JsonProperties, propertiesObject); _actualReportedState = rootObject; } else { // Merge to existing... JObject reportedObject = new JObject(); foreach (KeyValuePair <string, object> pair in reportedProperties) { reportedObject[pair.Key] = (JToken)pair.Value; } JObject reported = (JObject)_actualReportedState[JsonProperties][JsonReported]; /* * Debug.WriteLine("-- Merging ----------------------"); * Debug.WriteLine("-- -- Base:"); * Debug.WriteLine(reported); * Debug.WriteLine("-- -- New:"); * Debug.WriteLine(reportedObject); */ reported.Merge(reportedObject); /* * Debug.WriteLine("-- -- Result:"); * Debug.WriteLine(reported); * Debug.WriteLine("-- -- --"); */ } return(Task.CompletedTask); }
internal bool CheckIfManifestSigningIsEnabled(TwinCollection twinDesiredProperties) { // If there is no integrity section in the desired twin properties and the manifest trust bundle is not configured then manifest signing is turned off // If we have integrity section or the configuration of manifest trust bundle then manifest signing is turned on JToken integrity = JObject.Parse(twinDesiredProperties.ToString())["integrity"]; bool hasIntegrity = integrity != null && integrity.HasValues; bool hasManifestCA = this.manifestTrustBundle.HasValue; this.deploymentMetrics.ReportManifestIntegrity(hasManifestCA, hasIntegrity); return(hasManifestCA || hasIntegrity); }
internal bool ExtractHubTwinAndVerify(TwinCollection twinDesiredProperties) { try { // Extract Desired properties JObject desiredProperties = new JObject(); JObject twinJobject = JObject.Parse(twinDesiredProperties.ToString()); desiredProperties["routes"] = twinJobject["routes"]; desiredProperties["schemaVersion"] = twinJobject["schemaVersion"]; desiredProperties["storeAndForwardConfiguration"] = twinJobject["storeAndForwardConfiguration"]; if (desiredProperties["mqttBroker"] != null) { desiredProperties["mqttBroker"] = twinJobject["mqttBroker"]; } // Check if Manifest Trust Bundle is configured X509Certificate2 manifestTrustBundleRootCertificate; if (!this.manifestTrustBundle.HasValue && twinJobject["integrity"] == null) { // Actual code path would never get here as we check enablement before this. Added for Unit test purpose only. Events.ManifestSigningIsNotEnabled(); throw new ManifestSigningIsNotEnabledProperly("Manifest Signing is Disabled."); } else if (!this.manifestTrustBundle.HasValue && twinJobject["integrity"] != null) { Events.ManifestTrustBundleIsNotConfigured(); throw new ManifestSigningIsNotEnabledProperly("Deployment manifest is signed but the Manifest Trust bundle is not configured. Please configure in config.toml"); } else if (this.manifestTrustBundle.HasValue && twinJobject["integrity"] == null) { Events.DeploymentManifestIsNotSigned(); throw new ManifestSigningIsNotEnabledProperly("Manifest Trust bundle is configured but the Deployment manifest is not signed. Please sign it."); } else { // deployment manifest is signed and also the manifest trust bundle is configured manifestTrustBundleRootCertificate = this.manifestTrustBundle.OrDefault(); } // Extract Integrity header section JToken integrity = twinJobject["integrity"]; JToken header = integrity["header"]; // Extract Signer Cert section JToken signerCertJtoken = integrity["header"]["signercert"]; string signerCombinedCert = signerCertJtoken.Aggregate(string.Empty, (res, next) => res + next); X509Certificate2 signerCert = new X509Certificate2(Convert.FromBase64String(signerCombinedCert)); // Extract Intermediate CA Cert section JToken intermediatecacertJtoken = integrity["header"]["intermediatecacert"]; string intermediatecacertCombinedCert = signerCertJtoken.Aggregate(string.Empty, (res, next) => res + next); X509Certificate2 intermediatecacert = new X509Certificate2(Convert.FromBase64String(intermediatecacertCombinedCert)); // Extract Signature bytes and algorithm section JToken signature = integrity["signature"]["bytes"]; byte[] signatureBytes = Convert.FromBase64String(signature.ToString()); JToken algo = integrity["signature"]["algorithm"]; string algoStr = algo.ToString(); KeyValuePair <string, HashAlgorithmName> algoResult = SignatureValidator.ParseAlgorithm(algoStr); // Extract the manifest trust bundle certificate and verify chaining bool signatureVerified = false; using (IDisposable verificationTimer = Metrics.StartTwinSignatureTimer()) { // Currently not verifying the chaining as Manifest signer client already does that. // There is known bug in which the certs are not processed correctly which breaks the chaining verification. signatureVerified = SignatureValidator.VerifySignature(desiredProperties.ToString(), header.ToString(), signatureBytes, signerCert, algoResult.Key, algoResult.Value); } Metrics.ReportTwinSignatureResult(signatureVerified, algoStr); if (signatureVerified) { Events.ExtractHubTwinSucceeded(); } return(signatureVerified); } catch (Exception ex) { Metrics.ReportTwinSignatureResult(false); Events.ExtractHubTwinAndVerifyFailed(ex); throw ex; } }
internal static bool CheckIfTwinPropertiesAreSigned(TwinCollection twinDesiredProperties) { JToken integrity = JObject.Parse(twinDesiredProperties.ToString())["integrity"]; return(integrity != null && integrity.HasValues != false); }
internal bool ExtractHubTwinAndVerify(TwinCollection twinDesiredProperties) { try { // Extract Desired properties JObject desiredProperties = new JObject(); JObject twinJobject = JObject.Parse(twinDesiredProperties.ToString()); desiredProperties["routes"] = twinJobject["routes"]; desiredProperties["schemaVersion"] = twinJobject["schemaVersion"]; desiredProperties["storeAndForwardConfiguration"] = twinJobject["storeAndForwardConfiguration"]; if (desiredProperties["mqttBroker"] != null) { desiredProperties["mqttBroker"] = twinJobject["mqttBroker"]; } // Check if Manifest Trust Bundle is configured X509Certificate2 manifestTrustBundleRootCertificate; if (!this.manifestTrustBundle.HasValue && twinJobject["integrity"] == null) { // Actual code path would never get here as we check enablement before this. Added for Unit test purpose only. Events.ManifestSigningIsNotEnabled(); throw new ManifestSigningIsNotEnabledProperly("Manifest Signing is Disabled."); } else if (!this.manifestTrustBundle.HasValue && twinJobject["integrity"] != null) { Events.ManifestTrustBundleIsNotConfigured(); throw new ManifestSigningIsNotEnabledProperly("Deployment manifest is signed but the Manifest Trust bundle is not configured. Please configure in config.toml"); } else if (this.manifestTrustBundle.HasValue && twinJobject["integrity"] == null) { Events.DeploymentManifestIsNotSigned(); throw new ManifestSigningIsNotEnabledProperly("Manifest Trust bundle is configured but the Deployment manifest is not signed. Please sign it."); } else { // deployment manifest is signed and also the manifest trust bundle is configured manifestTrustBundleRootCertificate = this.manifestTrustBundle.OrDefault(); } // Extract Integrity header section JToken integrity = twinJobject["integrity"]; JToken header = integrity["header"]; // Extract Signer Cert section JToken signerCertJtoken = integrity["header"]["signercert"]; string signerCombinedCert = signerCertJtoken.Aggregate(string.Empty, (res, next) => res + next); X509Certificate2 signerCert = new X509Certificate2(Convert.FromBase64String(signerCombinedCert)); // Extract Intermediate CA Cert section JToken intermediatecacertJtoken = integrity["header"]["intermediatecacert"]; string intermediatecacertCombinedCert = signerCertJtoken.Aggregate(string.Empty, (res, next) => res + next); X509Certificate2 intermediatecacert = new X509Certificate2(Convert.FromBase64String(intermediatecacertCombinedCert)); // Extract the manifest trust bundle certificate and verify chaining if (!CertificateHelper.VerifyManifestTrustBunldeCertificateChaining(signerCert, intermediatecacert, manifestTrustBundleRootCertificate)) { throw new ManifestTrustBundleChainingFailedException("The signer cert with or without the intermediate CA cert in the twin does not chain up to the Manifest Trust Bundle Root CA configured in the device"); } // Extract Signature bytes and algorithm section JToken signature = integrity["signature"]["bytes"]; byte[] signatureBytes = Convert.FromBase64String(signature.ToString()); JToken algo = integrity["signature"]["algorithm"]; KeyValuePair <string, HashAlgorithmName> algoResult = SignatureValidator.ParseAlgorithm(algo.ToString()); Events.ExtractHubTwinSucceeded(); return(SignatureValidator.VerifySignature(desiredProperties.ToString(), header.ToString(), signatureBytes, signerCert, algoResult.Key, algoResult.Value)); } catch (Exception ex) { Events.ExtractHubTwinAndVerifyFailed(ex); throw ex; } }
static Task OnDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext) { try { Log.Information("New desired properties requested: {DesiredProperties}", desiredProperties.ToString()); //The majority of these have to be converted to JValue first because otherwise //they are interpreted as dynamics and cannot be converted to Double -> TimeSpan. //By converting to JValue, the are represented as objects which then are able //to convert. if (desiredProperties.Contains("backoffExp") && desiredProperties["backoffExp"] != null) { backoffExp = desiredProperties["backoffExp"]; } if (desiredProperties.Contains("startWindow") && desiredProperties["startWindow"] != null) { var rawStartWindow = desiredProperties["startWindow"] as JValue; startWindow = TimeSpan.FromSeconds(Convert.ToDouble(rawStartWindow.Value)); } if (desiredProperties.Contains("endWindow") && desiredProperties["endWindow"] != null) { var rawEndWindow = desiredProperties["endWindow"] as JValue; endWindow = TimeSpan.FromSeconds(Convert.ToDouble(rawEndWindow.Value)); } if (desiredProperties.Contains("defaultEndWindow") && desiredProperties["defaultEndWindow"] != null) { var rawDefaultEndWindow = desiredProperties["defaultEndWindow"] as JValue; defaultEndWindow = TimeSpan.FromSeconds(Convert.ToDouble(rawDefaultEndWindow.Value)); } if (desiredProperties.Contains("beatFrequency") && desiredProperties["beatFrequency"] != null) { var rawBeatFrequency = desiredProperties["beatFrequency"] as JValue; hartbeatFrequency = TimeSpan.FromSeconds(Convert.ToDouble(rawBeatFrequency.Value)); } if (desiredProperties.Contains("logEventLevel") && desiredProperties["logEventLevel"] != null) { switch (desiredProperties["logEventLevel"].ToString().ToLower()) { case "verbose": levelSwitch.MinimumLevel = LogEventLevel.Verbose; break; case "debug": levelSwitch.MinimumLevel = LogEventLevel.Debug; break; case "information": levelSwitch.MinimumLevel = LogEventLevel.Information; break; case "error": levelSwitch.MinimumLevel = LogEventLevel.Error; break; case "fatal": levelSwitch.MinimumLevel = LogEventLevel.Fatal; break; default: levelSwitch.MinimumLevel = LogEventLevel.Debug; Log.Debug("Level Switch cannot be changed to {DesiredProperty} and is now set to Level:Debug" , desiredProperties["logEventLevel"]); break; } } } catch (AggregateException ex) { foreach (Exception exception in ex.InnerExceptions) { Log.Error("Error when receiving desired property: {Exception}", exception); } } catch (Exception ex) { Log.Error("Error when receiving desired property: {Exception}", ex); } return(Task.CompletedTask); }
async Task OnDesiredPropertyUpdateAsync(TwinCollection desiredProperties, object userContext) { Logger.LogDebug($"Received desired property {desiredProperties.ToString()}"); await this.resultHandler.HandleDesiredPropertyReceivedAsync(desiredProperties); }
private async Task ReceiveDesiredConfiguration(TwinCollection desiredProperties, object userContext) { var deviceOutput = await GetAllOutputDevices(); var device = deviceOutput.Find(p => p.DeviceId == userContext.ToString()); device.Desired = JsonConvert.DeserializeObject <Dictionary <string, object> >(desiredProperties.ToString()); }