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