Ejemplo n.º 1
0
        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;
            }
        }
Ejemplo n.º 2
0
 public static void ParseAlgorithmTest(string algorithm, bool hasParseExcpetion, string expectedAlgoScheme, HashAlgorithmName expectedHashAlgo)
 {
     if (!hasParseExcpetion)
     {
         KeyValuePair <string, HashAlgorithmName> actualResult   = SignatureValidator.ParseAlgorithm(algorithm);
         KeyValuePair <string, HashAlgorithmName> expectedResult = new KeyValuePair <string, HashAlgorithmName>(expectedAlgoScheme, expectedHashAlgo);
         Assert.Equal(actualResult, expectedResult);
     }
     else
     {
         Assert.Throws <TwinSignatureAlgorithmException>(() => SignatureValidator.ParseAlgorithm(algorithm));
     }
 }
Ejemplo n.º 3
0
        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;
            }
        }
Ejemplo n.º 4
0
        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;
            }
        }
Ejemplo n.º 5
0
        static void Main()
        {
            // Initialize & Check if the given signer cert is issued by root CA
            try
            {
                // Check launch settings and display it
                CheckInputAndDisplayLaunchSettings();
                // Verify certificate chaining
                if (!VerifyCertificate())
                {
                    throw new Exception("Please provide a signer cert issued by the given root CA");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Environment.Exit(0);
            }

            // Read the deployment manifest file and get signature of each modules's desired properties
            try
            {
                var manifestFileHandle            = File.OpenText(DeploymentManifestFilePath);
                var deploymentManifestContentJson = JObject.Parse(manifestFileHandle.ReadToEnd());
                if (deploymentManifestContentJson["modulesContent"] != null)
                {
                    // Get the DSA and SHA algorithm
                    KeyValuePair <string, HashAlgorithmName> algoResult = SignatureValidator.ParseAlgorithm(DsaAlgorithm.ToString());

                    // Read the signer certificate and manifest version number and create integrity header object
                    var header = GetIntegrityHeader(SignerCertPath);

                    // Read each module's content and its desired properties
                    var     modulesContentJson    = deploymentManifestContentJson["modulesContent"];
                    JObject modulesContentJobject = JObject.Parse(modulesContentJson.ToString());

                    foreach (JProperty property in modulesContentJobject.Properties())
                    {
                        if (modulesContentJson[property.Name] != null)
                        {
                            if (modulesContentJson[property.Name]["properties.desired"] != null)
                            {
                                var modulesDesired = modulesContentJson[property.Name]["properties.desired"];
                                var moduleName     = property.Name.ToString();

                                if (moduleName != "$edgeAgent" && moduleName != "$edgeHub")
                                {
                                    Console.WriteLine($"Do you want to sign the desired properties of the module - {moduleName}? - Type Y or N to continue");
                                    Console.WriteLine("!!! Important Note !!! - If the module's desired properties are signed then the module's application code has to be rewritten to verify signatures");
                                    string userSigningChoice = Console.ReadLine();
                                    if (userSigningChoice != "Y" && userSigningChoice != "y")
                                    {
                                        Console.WriteLine($"{moduleName} will not be signed");
                                        continue;
                                    }
                                }

                                Console.WriteLine($"Signing Module: {property.Name}");
                                object signature = new
                                {
                                    bytes     = CertificateUtil.GetJsonSignature(algoResult.Key, algoResult.Value, modulesDesired.ToString(), header, SignerPrivateKeyPath),
                                    algorithm = DsaAlgorithm
                                };
                                deploymentManifestContentJson["modulesContent"][property.Name]["properties.desired"]["integrity"] = JObject.FromObject(new { header, signature });
                            }
                            else
                            {
                                throw new Exception($"Could not find {property.Name}'s desired properties in the manifest file");
                            }
                        }
                        else
                        {
                            throw new Exception($"Could not find {property.Name} in the manifest file");
                        }
                    }

                    using var signedDeploymentfile = File.CreateText(SignedDeploymentManifestFilePath);
                    signedDeploymentfile.Write(deploymentManifestContentJson);
                }
                else
                {
                    throw new Exception("Could not find modulesContent in the manifest file");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Environment.Exit(0);
            }
        }