From 4c57bff261ab06090032f9c3d026199bdf26eb32 Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Thu, 14 Sep 2017 10:09:15 +0200
Subject: [PATCH] XMLHashProvider requires canonicalization method and digest
 method for hash computation, provides info about default methods and
 supported methods

---
 .../VectoHashing/Impl/XmlHashProvider.cs      |  76 +++++-
 VectoCommon/VectoHashingTest/VectoHashTest.cs |  18 +-
 .../XMLDeclarationInputDataProvider.cs        | 234 +++++++++---------
 3 files changed, 196 insertions(+), 132 deletions(-)

diff --git a/VectoCommon/VectoHashing/Impl/XmlHashProvider.cs b/VectoCommon/VectoHashing/Impl/XmlHashProvider.cs
index 9bdddd9523..aafcf4ddde 100644
--- a/VectoCommon/VectoHashing/Impl/XmlHashProvider.cs
+++ b/VectoCommon/VectoHashing/Impl/XmlHashProvider.cs
@@ -30,6 +30,8 @@
 */
 
 using System;
+using System.Collections.Generic;
+using System.Linq;
 using System.Security.Cryptography;
 using System.Security.Cryptography.Xml;
 using System.Xml;
@@ -38,18 +40,69 @@ namespace TUGraz.VectoHashing.Impl
 {
 	public class XMLHashProvider
 	{
-		public static XmlDocument ComputeHash(XmlDocument doc, string elementId)
+		public const string DigestMethodSha256 = "http://www.w3.org/2001/04/xmlenc#sha256";
+
+		public const string VectoDsigTransform = "urn:vecto:xml:2017:canonicalization";
+		public const string DsigExcC14NTransform = "http://www.w3.org/2001/10/xml-exc-c14n#";
+
+
+		public static ICollection<string> SupportedDigestMethods
+		{
+			get {
+				return new[] {
+					DigestMethodSha256
+				};
+			}
+		}
+
+		public static string DefaultDigestMethod
+		{
+			get { return DigestMethodSha256; }
+		}
+
+		public static ICollection<string> SupportedCanonicalizationMethods
+		{
+			get {
+				return new[] {
+					VectoDsigTransform,
+					DsigExcC14NTransform,
+				};
+			}
+		}
+
+		public static IEnumerable<string> DefaultCanonicalizationMethod
+		{
+			get {
+				return new[] {
+					VectoDsigTransform,
+					DsigExcC14NTransform
+				};
+			}
+		}
+
+		public static XmlDocument ComputeHash(XmlDocument doc, string elementId, IEnumerable<string> canonicalization,
+			string digestMethod)
 		{
 			if (doc == null) {
 				throw new Exception("Invalid Document");
 			}
+			var c14N = (canonicalization ?? DefaultCanonicalizationMethod).ToArray();
+			digestMethod = digestMethod ?? DefaultDigestMethod;
+			if (!SupportedDigestMethods.Contains(digestMethod)) {
+				throw new Exception(string.Format("DigestMethod '{0}' not supported.", digestMethod));
+			}
+			var unsupported = c14N.Where(c => !SupportedCanonicalizationMethods.Contains(c)).ToArray();
+			if (unsupported.Any()) {
+				throw new Exception(string.Format("CanonicalizationMethod(s) {0} not supported!", string.Join(", ", unsupported)));
+			}
+
 			var signedXml = new SignedXml(doc);
 			var reference = new Reference("#" + elementId) {
-				DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"
+				DigestMethod = digestMethod
 			};
-			reference.AddTransform(new XmlDsigVectoTransform());
-			reference.AddTransform(new XmlDsigExcC14NTransform());
-
+			foreach (var c in c14N) {
+				reference.AddTransform(GetTransform(c));
+			}
 
 			signedXml.AddReference(reference);
 			signedXml.ComputeSignature(HMAC.Create());
@@ -61,5 +114,16 @@ namespace TUGraz.VectoHashing.Impl
 
 			return sigdoc;
 		}
+
+		private static Transform GetTransform(string transformUrn)
+		{
+			switch (transformUrn) {
+				case VectoDsigTransform:
+					return new XmlDsigVectoTransform();
+				case DsigExcC14NTransform:
+					return new XmlDsigExcC14NTransform();
+			}
+			throw new Exception(string.Format("Unsupported CanonicalizationMethod {0}", transformUrn));
+		}
 	}
-}
\ No newline at end of file
+}
diff --git a/VectoCommon/VectoHashingTest/VectoHashTest.cs b/VectoCommon/VectoHashingTest/VectoHashTest.cs
index bf295e3ba5..986e32cb75 100644
--- a/VectoCommon/VectoHashingTest/VectoHashTest.cs
+++ b/VectoCommon/VectoHashingTest/VectoHashTest.cs
@@ -45,21 +45,21 @@ using Assert = NUnit.Framework.Assert;
 
 namespace VectoHashingTest
 {
-    
+	
 
-    [TestFixture]
+	[TestFixture]
 	public class VectoHashTest
 	{
 		public const string ReferenceXMLEngine = @"Testdata\XML\Reference\vecto_engine-sample.xml";
 		public const string ReferenceXMLVehicle = @"Testdata\XML\Reference\vecto_vehicle-sample_FULL.xml";
 
-        [OneTimeSetUp]
-        public void RunBeforeAnyTests()
-        {
-            Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
-        }
+		[OneTimeSetUp]
+		public void RunBeforeAnyTests()
+		{
+			Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
+		}
 
-        [TestCase]
+		[TestCase]
 		public void TestComponentsEngineFile()
 		{
 			var h = VectoHash.Load(ReferenceXMLEngine);
@@ -525,4 +525,4 @@ namespace VectoHashingTest
 			}
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs
index dbc91c985c..87fdd1356c 100644
--- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs
@@ -29,120 +29,120 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.Xml;
-using System.Xml.Linq;
-using System.Xml.Schema;
-using System.Xml.XPath;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.InputData;
-using TUGraz.VectoCore.Utils;
-using TUGraz.VectoHashing;
-
-namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration
-{
-	public class XMLDeclarationInputDataProvider : IDeclarationInputDataProvider
-	{
-		internal readonly XPathDocument Document;
-
-		private readonly IAuxiliariesDeclarationInputData XMLAuxiliaryData;
-		private readonly IDriverDeclarationInputData XMLDriverData;
-		private readonly IDeclarationJobInputData XMLJobData;
-		protected internal readonly XMLDeclarationVehicleDataProvider _vehicleInputData;
-
-		public XMLDeclarationInputDataProvider(XmlReader inputData, bool verifyXml)
-		{
-			if (verifyXml) {
-				var settings = new XmlReaderSettings {
-					ValidationType = ValidationType.Schema,
-					ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema |
-									//XmlSchemaValidationFlags.ProcessSchemaLocation |
-									XmlSchemaValidationFlags.ReportValidationWarnings
-				};
-				settings.ValidationEventHandler += ValidationCallBack;
-				settings.Schemas.Add(GetXMLSchema(""));
-
-				inputData = XmlReader.Create(inputData, settings);
-			}
-			//Document = new XPathDocument(inputData);
-
-			var xmldoc = new XmlDocument();
-			xmldoc.Load(inputData);
-			var h = VectoHash.Load(xmldoc);
-			XMLHash = h.ComputeXmlHash();
-
-			Document = new XPathDocument(new XmlNodeReader(xmldoc));
-
-			//CheckInputDocument();
-
-			XMLJobData = new XMLDeclarationJobInputDataProvider(this);
-			_vehicleInputData = new XMLDeclarationVehicleDataProvider(this);
-			AirdragInputData = new XMLDeclarationAirdragDataProvider(this);
-			AxleGearInputData = new XMLDeclarationAxlegearDataProvider(this);
-			AngledriveInputData = new XMLDeclarationAngledriveDataProvider(this);
-			EngineInputData = new XMLDeclarationEngineDataProvider(this);
-			GearboxInputData = new XMLDeclarationGearboxDataProvider(this);
-			TorqueConverterInputData = new XMLDeclarationTorqueConverterDataProvider(this);
-			RetarderInputData = new XMLDeclarationRetarderDataProvider(this);
-			XMLDriverData = new XMLDeclarationDriverDataProvider(this);
-			XMLAuxiliaryData = new XMLDeclarationAuxiliaryDataProvider(this);
-			PTOTransmissionInputData = _vehicleInputData.GetPTOData();
-		}
-
-		private static void ValidationCallBack(object sender, ValidationEventArgs args)
-		{
-			if (args.Severity == XmlSeverityType.Error) {
-				throw new VectoException("Validation error: {0}" + Environment.NewLine +
-										"Line: {1}", args.Message, args.Exception.LineNumber);
-			}
-		}
-
-		private static XmlSchemaSet GetXMLSchema(string version)
-		{
-			var resource = RessourceHelper.LoadResourceAsStream(RessourceHelper.ResourceType.XMLSchema, "VectoInput.xsd");
-			var xset = new XmlSchemaSet() { XmlResolver = new XmlResourceResolver() };
-			var reader = XmlReader.Create(resource, new XmlReaderSettings(), XmlResourceResolver.BaseUri);
-			xset.Add(XmlSchema.Read(reader, null));
-			xset.Compile();
-			return xset;
-		}
-
-		public IDeclarationJobInputData JobInputData()
-		{
-			return XMLJobData;
-		}
-
-		public IVehicleDeclarationInputData VehicleInputData
-		{
-			get { return _vehicleInputData; }
-		}
-
-		public IAirdragDeclarationInputData AirdragInputData { get; private set; }
-
-		public IGearboxDeclarationInputData GearboxInputData { get; private set; }
-
-		public ITorqueConverterDeclarationInputData TorqueConverterInputData { get; private set; }
-
-		public IAxleGearInputData AxleGearInputData { get; private set; }
-
-		public IAngledriveInputData AngledriveInputData { get; private set; }
-
-		public IEngineDeclarationInputData EngineInputData { get; private set; }
-
-		public IAuxiliariesDeclarationInputData AuxiliaryInputData()
-		{
-			return XMLAuxiliaryData;
-		}
-
-		public IRetarderInputData RetarderInputData { get; private set; }
-
-		public IDriverDeclarationInputData DriverInputData
-		{
-			get { return XMLDriverData; }
-		}
-
-		public IPTOTransmissionInputData PTOTransmissionInputData { get; private set; }
-
-		public XElement XMLHash { get; private set; }
-	}
-}
\ No newline at end of file
+using System;
+using System.Xml;
+using System.Xml.Linq;
+using System.Xml.Schema;
+using System.Xml.XPath;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCore.Utils;
+using TUGraz.VectoHashing;
+
+namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration
+{
+	public class XMLDeclarationInputDataProvider : IDeclarationInputDataProvider
+	{
+		internal readonly XPathDocument Document;
+
+		private readonly IAuxiliariesDeclarationInputData XMLAuxiliaryData;
+		private readonly IDriverDeclarationInputData XMLDriverData;
+		private readonly IDeclarationJobInputData XMLJobData;
+		protected internal readonly XMLDeclarationVehicleDataProvider _vehicleInputData;
+
+		public XMLDeclarationInputDataProvider(XmlReader inputData, bool verifyXml)
+		{
+			if (verifyXml) {
+				var settings = new XmlReaderSettings {
+					ValidationType = ValidationType.Schema,
+					ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema |
+									//XmlSchemaValidationFlags.ProcessSchemaLocation |
+									XmlSchemaValidationFlags.ReportValidationWarnings
+				};
+				settings.ValidationEventHandler += ValidationCallBack;
+				settings.Schemas.Add(GetXMLSchema(""));
+
+				inputData = XmlReader.Create(inputData, settings);
+			}
+			//Document = new XPathDocument(inputData);
+
+			var xmldoc = new XmlDocument();
+			xmldoc.Load(inputData);
+			var h = VectoHash.Load(xmldoc);
+			XMLHash = h.ComputeXmlHash();
+
+			Document = new XPathDocument(new XmlNodeReader(xmldoc));
+
+			//CheckInputDocument();
+
+			XMLJobData = new XMLDeclarationJobInputDataProvider(this);
+			_vehicleInputData = new XMLDeclarationVehicleDataProvider(this);
+			AirdragInputData = new XMLDeclarationAirdragDataProvider(this);
+			AxleGearInputData = new XMLDeclarationAxlegearDataProvider(this);
+			AngledriveInputData = new XMLDeclarationAngledriveDataProvider(this);
+			EngineInputData = new XMLDeclarationEngineDataProvider(this);
+			GearboxInputData = new XMLDeclarationGearboxDataProvider(this);
+			TorqueConverterInputData = new XMLDeclarationTorqueConverterDataProvider(this);
+			RetarderInputData = new XMLDeclarationRetarderDataProvider(this);
+			XMLDriverData = new XMLDeclarationDriverDataProvider(this);
+			XMLAuxiliaryData = new XMLDeclarationAuxiliaryDataProvider(this);
+			PTOTransmissionInputData = _vehicleInputData.GetPTOData();
+		}
+
+		private static void ValidationCallBack(object sender, ValidationEventArgs args)
+		{
+			if (args.Severity == XmlSeverityType.Error) {
+				throw new VectoException("Validation error: {0}" + Environment.NewLine +
+										"Line: {1}", args.Message, args.Exception.LineNumber);
+			}
+		}
+
+		private static XmlSchemaSet GetXMLSchema(string version)
+		{
+			var resource = RessourceHelper.LoadResourceAsStream(RessourceHelper.ResourceType.XMLSchema, "VectoInput.xsd");
+			var xset = new XmlSchemaSet() { XmlResolver = new XmlResourceResolver() };
+			var reader = XmlReader.Create(resource, new XmlReaderSettings(), XmlResourceResolver.BaseUri);
+			xset.Add(XmlSchema.Read(reader, null));
+			xset.Compile();
+			return xset;
+		}
+
+		public IDeclarationJobInputData JobInputData()
+		{
+			return XMLJobData;
+		}
+
+		public IVehicleDeclarationInputData VehicleInputData
+		{
+			get { return _vehicleInputData; }
+		}
+
+		public IAirdragDeclarationInputData AirdragInputData { get; private set; }
+
+		public IGearboxDeclarationInputData GearboxInputData { get; private set; }
+
+		public ITorqueConverterDeclarationInputData TorqueConverterInputData { get; private set; }
+
+		public IAxleGearInputData AxleGearInputData { get; private set; }
+
+		public IAngledriveInputData AngledriveInputData { get; private set; }
+
+		public IEngineDeclarationInputData EngineInputData { get; private set; }
+
+		public IAuxiliariesDeclarationInputData AuxiliaryInputData()
+		{
+			return XMLAuxiliaryData;
+		}
+
+		public IRetarderInputData RetarderInputData { get; private set; }
+
+		public IDriverDeclarationInputData DriverInputData
+		{
+			get { return XMLDriverData; }
+		}
+
+		public IPTOTransmissionInputData PTOTransmissionInputData { get; private set; }
+
+		public XElement XMLHash { get; private set; }
+	}
+}
-- 
GitLab