From 605fde57caf7399a99e764de02c730443f8ff9cd Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Thu, 7 Dec 2017 17:26:42 +0100
Subject: [PATCH] change hashing tool to verify hash of manufacturer report in
 customer file

---
 HashingTool/HashingTool.csproj                |   1 +
 .../UserControl/CustomerReportXMLFile.cs      | 161 ++++++++++++++++++
 .../ViewModel/UserControl/ReportXMLFile.cs    |   2 +-
 .../ViewModel/VerifyResultDataViewModel.cs    |   7 +-
 HashingTool/Views/VerifyResults.xaml          |  67 +++++++-
 5 files changed, 229 insertions(+), 9 deletions(-)
 create mode 100644 HashingTool/ViewModel/UserControl/CustomerReportXMLFile.cs

diff --git a/HashingTool/HashingTool.csproj b/HashingTool/HashingTool.csproj
index d3195f3739..937009645d 100644
--- a/HashingTool/HashingTool.csproj
+++ b/HashingTool/HashingTool.csproj
@@ -84,6 +84,7 @@
     <Compile Include="ViewModel\ObservableObject.cs" />
     <Compile Include="ViewModel\RelayCommand.cs" />
     <Compile Include="ViewModel\HashComponentDataViewModel.cs" />
+    <Compile Include="ViewModel\UserControl\CustomerReportXMLFile.cs" />
     <Compile Include="ViewModel\UserControl\HashedXMLFile.cs" />
     <Compile Include="ViewModel\UserControl\ManufacturerReportXMLFile.cs" />
     <Compile Include="ViewModel\UserControl\ReportXMLFile.cs" />
diff --git a/HashingTool/ViewModel/UserControl/CustomerReportXMLFile.cs b/HashingTool/ViewModel/UserControl/CustomerReportXMLFile.cs
new file mode 100644
index 0000000000..a9c988df6d
--- /dev/null
+++ b/HashingTool/ViewModel/UserControl/CustomerReportXMLFile.cs
@@ -0,0 +1,161 @@
+using System;
+using System.ComponentModel;
+using System.Linq;
+using System.Xml;
+using TUGraz.VectoHashing;
+
+namespace HashingTool.ViewModel.UserControl
+{
+	public class CustomerReportXMLFile : ReportXMLFile
+	{
+		private ManufacturerReportXMLFile _manufacturerReport;
+		private string[] _manufacturerReportCanonicalizationMethodRead;
+		private string _manufacturerReportDigestMethodRead;
+		private string _manufacturerReportDigestValueRead;
+		private bool _manufacturerReportMatchesReport;
+		private string _manufacturerReportDigestValueComputed;
+
+		public CustomerReportXMLFile(string name, Func<XmlDocument, IErrorLogger, bool?> contentCheck,
+			Action<XmlDocument, VectoXMLFile> hashValidation = null) : base(name, contentCheck, hashValidation)
+		{
+			
+		}
+
+
+		public ManufacturerReportXMLFile ManufacturerReport
+		{
+			get { return _manufacturerReport; }
+			set {
+				if (_manufacturerReport == value) {
+					return;
+				}
+				_manufacturerReport = value;
+				_manufacturerReport.PropertyChanged += ManufacturerReportChanged;
+			}
+		}
+
+		public string[] ManufacturerReportCanonicalizationMethodRead
+		{
+			get { return _manufacturerReportCanonicalizationMethodRead; }
+			set
+			{
+				if (_manufacturerReportCanonicalizationMethodRead == value) {
+					return;
+				}
+				_manufacturerReportCanonicalizationMethodRead = value;
+				RaisePropertyChanged("ManufacturerReportCanonicalizationMethodRead");
+			}
+		}
+
+		public string ManufacturerReportDigestMethodRead
+		{
+			get { return _manufacturerReportDigestMethodRead; }
+			set
+			{
+				if (_manufacturerReportDigestMethodRead == value) {
+					return;
+				}
+				_manufacturerReportDigestMethodRead = value;
+				RaisePropertyChanged("ManufacturerReportDigestMethodRead");
+			}
+		}
+
+		public string ManufacturerReportDigestValueRead
+		{
+			get { return _manufacturerReportDigestValueRead; }
+			set
+			{
+				if (_manufacturerReportDigestValueRead == value) {
+					return;
+				}
+				_manufacturerReportDigestValueRead = value;
+				RaisePropertyChanged("ManufacturerReportDigestValueRead");
+			}
+		}
+
+		public bool ManufacturerReportMatchesReport
+		{
+			get { return _manufacturerReportMatchesReport; }
+			set
+			{
+				if (_manufacturerReportMatchesReport == value) {
+					return;
+				}
+				_manufacturerReportMatchesReport = value;
+				RaisePropertyChanged("ManufacturerReportMatchesReport");
+			}
+		}
+
+		public string ManufacturerReportDigestValueComputed
+		{
+			get { return _manufacturerReportDigestValueComputed; }
+			set
+			{
+				if (_manufacturerReportDigestValueComputed == value) {
+					return;
+				}
+				_manufacturerReportDigestValueComputed = value;
+				RaisePropertyChanged("ManufacturerReportDigestValueComputed");
+			}
+		}
+
+		protected virtual void ManufacturerReportChanged(object sender, PropertyChangedEventArgs e)
+		{
+			if (sender == _manufacturerReport && e.PropertyName == GeneralUpdate) {
+				VerifyManufacturerReport();
+			}
+		}
+
+		protected override void ReportChanged(object sender, PropertyChangedEventArgs e)
+		{
+			if (sender == _xmlFile && e.PropertyName == GeneralUpdate) {
+				ReadReportData();
+				VerifyManufacturerReport();
+			}
+		}
+
+
+		protected virtual void VerifyManufacturerReport()
+		{
+			var manufacturerReportDigestValueRead = "";
+			var manufacturerReportDigestMethodRead = "";
+			var manufacturerReportCanonicalizationMethodRead = new string[] { };
+
+			var manufacturerReportDigestValueComputed = "";
+			var digestMatch = false;
+
+			if (_xmlFile.Document != null && _xmlFile.Document.DocumentElement != null) {
+				var digestValueNode =
+					_xmlFile.Document.SelectSingleNode("//*[local-name()='ResultDataSignature']//*[local-name()='DigestValue']");
+				if (digestValueNode != null) {
+					manufacturerReportDigestValueRead = digestValueNode.InnerText;
+				}
+				var digestMethodNode =
+					_xmlFile.Document.SelectSingleNode(
+						"//*[local-name()='ResultDataSignature']//*[local-name()='DigestMethod']/@Algorithm");
+				if (digestMethodNode != null) {
+					manufacturerReportDigestMethodRead = digestMethodNode.InnerText;
+				}
+
+				var c14NtMethodNodes =
+					_xmlFile.Document.SelectNodes("//*[local-name()='ResultDataSignature']//*[local-name()='Transform']/@Algorithm");
+				if (c14NtMethodNodes != null) {
+					manufacturerReportCanonicalizationMethodRead = (from XmlNode node in c14NtMethodNodes select node.InnerText).ToArray();
+				}
+
+				if (_manufacturerReport != null && _manufacturerReport.XMLFile != null && _manufacturerReport.XMLFile.IsValid == XmlFileStatus.ValidXML) {
+					var h = VectoHash.Load(_manufacturerReport.XMLFile.Document);
+					manufacturerReportDigestValueComputed = h.ComputeHash(manufacturerReportCanonicalizationMethodRead,
+						manufacturerReportDigestMethodRead);
+					digestMatch = manufacturerReportDigestValueRead == manufacturerReportDigestValueComputed;
+				}
+			}
+			ManufacturerReportDigestMethodRead = manufacturerReportDigestMethodRead;
+			ManufacturerReportCanonicalizationMethodRead = manufacturerReportCanonicalizationMethodRead;
+			ManufacturerReportDigestValueRead = manufacturerReportDigestValueRead;
+			ManufacturerReportDigestValueComputed = manufacturerReportDigestValueComputed;
+
+			ManufacturerReportMatchesReport = digestMatch;
+		}
+	}
+}
\ No newline at end of file
diff --git a/HashingTool/ViewModel/UserControl/ReportXMLFile.cs b/HashingTool/ViewModel/UserControl/ReportXMLFile.cs
index eec1eb6597..770390873b 100644
--- a/HashingTool/ViewModel/UserControl/ReportXMLFile.cs
+++ b/HashingTool/ViewModel/UserControl/ReportXMLFile.cs
@@ -74,7 +74,7 @@ namespace HashingTool.ViewModel.UserControl
 			}
 		}
 
-		private void ReportChanged(object sender, PropertyChangedEventArgs e)
+		protected virtual void ReportChanged(object sender, PropertyChangedEventArgs e)
 		{
 			if (sender == _xmlFile && e.PropertyName == GeneralUpdate) {
 				ReadReportData();
diff --git a/HashingTool/ViewModel/VerifyResultDataViewModel.cs b/HashingTool/ViewModel/VerifyResultDataViewModel.cs
index 8ec7876911..1b8b5104d5 100644
--- a/HashingTool/ViewModel/VerifyResultDataViewModel.cs
+++ b/HashingTool/ViewModel/VerifyResultDataViewModel.cs
@@ -46,7 +46,7 @@ namespace HashingTool.ViewModel
 	public class VerifyResultDataViewModel : ObservableObject, IMainView
 	{
 		private readonly VectoJobFile _jobFile;
-		private readonly ReportXMLFile _customerReport;
+		private readonly CustomerReportXMLFile _customerReport;
 		private readonly ManufacturerReportXMLFile _manufacturerReport;
 
 
@@ -56,9 +56,10 @@ namespace HashingTool.ViewModel
 			_manufacturerReport = new ManufacturerReportXMLFile("Manufacturer Report", HashingHelper.IsManufacturerReport,
 				HashingHelper.ValidateDocumentHash);
 			_manufacturerReport.JobData = _jobFile;
-			_customerReport = new ReportXMLFile("Customer Report", HashingHelper.IsCustomerReport,
+			_customerReport = new CustomerReportXMLFile("Customer Report", HashingHelper.IsCustomerReport,
 				HashingHelper.ValidateDocumentHash);
 			_customerReport.JobData = _jobFile;
+			_customerReport.ManufacturerReport = _manufacturerReport;
 			Files = new ObservableCollection<VectoXMLFile> { _jobFile, _manufacturerReport, _customerReport };
 
 			ErrorsAndWarnings = new CompositeCollection();
@@ -105,7 +106,7 @@ namespace HashingTool.ViewModel
 		}
 
 
-		public ReportXMLFile CustomerReport
+		public CustomerReportXMLFile CustomerReport
 		{
 			get { return _customerReport; }
 		}
diff --git a/HashingTool/Views/VerifyResults.xaml b/HashingTool/Views/VerifyResults.xaml
index 3f50f7d515..e5ec6b59de 100644
--- a/HashingTool/Views/VerifyResults.xaml
+++ b/HashingTool/Views/VerifyResults.xaml
@@ -212,13 +212,14 @@
 			</Grid>
 		</DataTemplate>
 
-		<DataTemplate x:Key="ExpanderContentReport" DataType="userControl:ReportXMLFile">
+		<DataTemplate x:Key="ExpanderContentCustomerReport" DataType="userControl:CustomerReportXMLFile">
 			<Grid Grid.IsSharedSizeScope="True">
 				<Grid.RowDefinitions>
 					<RowDefinition />
 					<RowDefinition />
 					<RowDefinition />
 					<RowDefinition />
+                    <RowDefinition/>
 				</Grid.RowDefinitions>
 				<Grid.ColumnDefinitions>
 					<ColumnDefinition Width="Auto"  SharedSizeGroup="LabelsShareGroup"/>
@@ -290,7 +291,63 @@
 					</Grid>
 				</GroupBox>
 
-				<GroupBox Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Header="Job Integrity" Style="{DynamicResource CustomGroupboxStyle}">
+                <GroupBox Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Header="Manufacturer Report Integrity" Style="{DynamicResource CustomGroupboxStyle}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="Auto" SharedSizeGroup="LabelsShareGroup" />
+                            <ColumnDefinition Width="*" />
+                        </Grid.ColumnDefinitions>
+                        <Grid.RowDefinitions>
+                            <RowDefinition />
+                            <RowDefinition />
+                            <RowDefinition />
+                            <RowDefinition />
+                    
+                        </Grid.RowDefinitions>
+                        <Label Grid.Row="0" Grid.Column="0" Content="CanonicalizationMethod:" />
+                        <TextBox Grid.Row="0" Grid.Column="1"
+								Text="{Binding ManufacturerReportCanonicalizationMethodRead, Mode=OneWay, Converter={StaticResource CollectionConverter}}"
+								Margin="10,2" IsReadOnly="True" />
+
+                        <Label Grid.Row="1" Grid.Column="0" Content="Digest Method:" />
+                        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding ManufacturerReportDigestMethodRead, Mode=OneWay}"
+								Margin="10,2" IsReadOnly="True" />
+
+                        <Label Grid.Row="2" Grid.Column="0" Content="Digest Value Read:"
+								Style="{StaticResource DigestValueLabelStyle}" />
+                        <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding ManufacturerReportDigestValueRead, Mode=OneWay}"
+								Margin="10,2" IsReadOnly="True">
+                            <TextBox.Style>
+                                <Style TargetType="TextBox" BasedOn="{StaticResource DigestValueTextboxStyle}">
+                                    <Setter Property="Foreground" Value="{StaticResource Color.ErrorRed}" />
+                                    <Style.Triggers>
+                                        <DataTrigger Binding="{Binding ManufacturerReportMatchesReport}" Value="True">
+                                            <Setter Property="Foreground" Value="{StaticResource Color.SuccessGreen}" />
+                                        </DataTrigger>
+                                    </Style.Triggers>
+                                </Style>
+                            </TextBox.Style>
+                        </TextBox>
+
+                        <Label Grid.Row="3" Grid.Column="0" Content="Digest Value Computed:"
+								Style="{StaticResource DigestValueLabelStyle}" />
+                        <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding ManufacturerReportDigestValueComputed, Mode=OneWay}"
+								Margin="10,2" IsReadOnly="True">
+                            <TextBox.Style>
+                                <Style TargetType="TextBox" BasedOn="{StaticResource DigestValueTextboxStyle}">
+                                    <Setter Property="Foreground" Value="{StaticResource Color.ErrorRed}" />
+                                    <Style.Triggers>
+                                        <DataTrigger Binding="{Binding ManufacturerReportMatchesReport}" Value="True">
+                                            <Setter Property="Foreground" Value="{StaticResource Color.SuccessGreen}" />
+                                        </DataTrigger>
+                                    </Style.Triggers>
+                                </Style>
+                            </TextBox.Style>
+                        </TextBox>
+                    </Grid>
+                </GroupBox>
+
+                <GroupBox Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" Header="Job Integrity" Style="{DynamicResource CustomGroupboxStyle}">
 					<Grid>
 						<Grid.ColumnDefinitions>
 							<ColumnDefinition Width="Auto" SharedSizeGroup="LabelsShareGroup" />
@@ -682,7 +739,7 @@
 							<Border BorderBrush="White" BorderThickness="1" CornerRadius="2" Margin="0,0,3,0">
 								<Expander Margin="2" Header="{Binding}" HorizontalAlignment="Stretch"
 										Style="{DynamicResource HeaderStretchExpanderStyle}"
-										HeaderTemplate="{DynamicResource ExpanderHeader}" ContentTemplate="{DynamicResource ExpanderContentReport}"
+										HeaderTemplate="{DynamicResource ExpanderHeader}" ContentTemplate="{DynamicResource ExpanderContentCustomerReport}"
 										Content="{Binding}" />
 							</Border>
 
@@ -761,7 +818,7 @@
 				<TextBlock Grid.Row="0" Grid.Column="4" HorizontalAlignment="Center" VerticalAlignment="Center"
 							TextAlignment="Center" Margin="5"
 							FontSize="14" FontWeight="Bold">
-					Job-Data matches<LineBreak /> Customer Report
+					Manufacturer Report<LineBreak/> matches<LineBreak /> Customer Report
 				</TextBlock>
 				<ContentControl Grid.Row="1" Grid.Column="4" Width="50" Height="50" Margin="10,10,10,0">
 					<ContentControl.LayoutTransform>
@@ -771,7 +828,7 @@
 						<Style TargetType="ContentControl">
 							<Setter Property="ContentTemplate" Value="{StaticResource Icon_NOK}" />
 							<Style.Triggers>
-								<DataTrigger Binding="{Binding CustomerReport.JobDigestMatchesReport}" Value="True">
+                                <DataTrigger Binding="{Binding CustomerReport.ManufacturerReportMatchesReport}" Value="True">
 									<Setter Property="ContentTemplate" Value="{StaticResource Icon_OK}" />
 								</DataTrigger>
 							</Style.Triggers>
-- 
GitLab