Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit 218dedab authored by Markus QUARITSCH's avatar Markus QUARITSCH
Browse files

refactoring of VectoHash class to allow passing c14n method and digest method,...

refactoring of VectoHash class to allow passing c14n method and digest method, return info about c14n method and digest method
parent 4c57bff2
No related branches found
No related tags found
No related merge requests found
......@@ -29,60 +29,111 @@
* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
*/
using System.Collections.Generic;
using System.Xml.Linq;
namespace TUGraz.VectoHashing
{
public interface IVectoHash
{
IList<VectoComponents> GetContainigComponents();
/**
* Computes the hash-value of the top-level Data element (or vehicle)
* Note: the top-level Data element is required to have an id attribute!
* @return base64 encoded hash value
*/
string ComputeHash();
/**
* Computes the hash-value for the given component. If a component can exist multiple times
* (i.e., Tyres) the index specifies for which component the hash is computed
* Note: the Data element is required to have an id attribute!
* @return base64 encoded hash value
*/
string ComputeHash(VectoComponents component, int index = 0);
/**
* Computes the hash-value of the outer Data element and adds the according Signature element
* after the Data element.
* Note: the id attribute is added to the Data element automatically. if an id attribute is already
* present its value is overwritten.
* @return returns the document including the Signature element with the hash of the Data block
*/
XDocument AddHash();
/**
* Reads the hash-value of the top-level Signature element
* @return base64 encoded hash value
*/
string ReadHash();
/**
* Reads the hash-value of the Signature element for the given component. If a component can exist
* multiple times (i.e., Tyres), the index specifies for which component the hash is computed
* @return base64 encoded hash value
*/
string ReadHash(VectoComponents component, int index = 0);
/**
* Validates the hash of the top-level component (or vehicle)
*/
bool ValidateHash();
/**
* Validates the hash for the given component.
*/
bool ValidateHash(VectoComponents component, int index = 0);
}
}
\ No newline at end of file
using System.Collections.Generic;
using System.Xml.Linq;
namespace TUGraz.VectoHashing
{
public interface IVectoHash
{
/**
* Get a list of all vecto components contained in the XML file. If a certain
* component appears multiple times (e.g. tires) it is provided multiple times
* in the returned list.
* to get a list with unique entries (and the number of occurences) use e.g.
* GetContainigComponents().GroupBy(s => s).Select(g => new { Entry = g.Key, Count = g.Count() })
*/
IList<VectoComponents> GetContainigComponents();
/**
* Get the digest method used to compute the digest value of the top-level Signature element
* if there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaultDigestMethod)
* @return identifier (urn) of the digest method
*/
string GetDigestMethod();
/**
* Get the digest method of the Signature element for the given component. If a component exists
* multiple times (e.g., tires), the index specifies for which component the digest method is returned
* @param component
* @param index
* @return identifier (urn) of the digest method
*/
string GetDigestMethod(VectoComponents component, int index = 0);
/**
* Get the list of canonicalization methods used to compute the digest value of the top-level Signature element
* If there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaulCanonicalizationMethod)
* @return returns a list of identifiers (urns) of the canonicalization methods
*/
IEnumerable<string> GetCanonicalizationMethods();
/**
* Get the list of canonicalization methods used to compute the digest value of the Signature element
* for the given component. If a component exists multiple times (e.g., tires) the indes specifies for which
* component the canonicalization method is returned
* If there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaulCanonicalizationMethod)
* @return returns a list of identifiers (urns) of the canonicalization methods
*/
IEnumerable<string> GetCanonicalizationMethods(VectoComponents component, int index = 0);
/**
* Reads the hash-value of the top-level Signature element
* @return base64 encoded hash value
*/
string ReadHash();
/**
* Reads the hash-value of the Signature element for the given component. If a component can exist
* multiple times (i.e., tires), the index specifies for which component the hash is computed
* @return base64 encoded hash value
*/
string ReadHash(VectoComponents component, int index = 0);
/**
* Computes the hash-value of the top-level Data element (or vehicle)
* If the canoonicalizationMethods is null the canonicalizationMethods from
* the signature element are read if available or the default canonicalization is applied
* If the digestMethod is null the digestMethod from the signature element is read if
* available or the default digestMethod is used
* Note: the top-level Data element is required to have an id attribute!
* @return base64 encoded hash value
*/
string ComputeHash(IEnumerable<string> canonicalizationMethods = null, string digestMethod = null);
/**
* Computes the hash-value for the given component. If a component can exist multiple times
* (i.e., Tyres) the index specifies for which component the hash is computed
* If the canoonicalizationMethods is null the canonicalizationMethods from
* the signature element are read if available or the default canonicalization is applied
* If the digestMethod is null the digestMethod from the signature element is read if
* available or the default digestMethod is used
* Note: the Data element is required to have an id attribute!
* @return base64 encoded hash value
*/
string ComputeHash(VectoComponents component, int index = 0, IEnumerable<string> canonicalizationMethods = null,
string digestMethod = null);
/**
* Validates the hash of the top-level component (or vehicle)
*/
bool ValidateHash();
/**
* Validates the hash for the given component.
*/
bool ValidateHash(VectoComponents component, int index = 0);
/**
* Computes the hash-value of the outer Data element and adds the according Signature element
* after the Data element.
* The default CaonocalizationMethods and DigestMethod are used.
* Note: the id attribute is added to the Data element automatically. if an id attribute is already
* present its value is overwritten.
* @return returns the document including the Signature element with the hash of the Data block
*/
XDocument AddHash();
}
}
......@@ -99,29 +99,30 @@ namespace TUGraz.VectoHashing
return retVal;
}
public XElement ComputeXmlHash()
public XElement ComputeXmlHash(IEnumerable<string> canonicalization = null, string digestMethod = null)
{
var nodes = Document.SelectNodes(GetComponentQueryString());
if (nodes == null || nodes.Count == 0) {
throw new Exception("No component found");
}
var componentId = nodes[0].Attributes[XMLNames.Component_ID_Attr].Value;
var hash = DoComputeHash(nodes[0]);
var hash = DoComputeHash(nodes[0], canonicalization, digestMethod);
return hash.ToXDocument().Root;
}
public string ComputeHash()
public string ComputeHash(IEnumerable<string> canonicalization = null, string digestMethod = null)
{
var nodes = Document.SelectNodes(GetComponentQueryString());
if (nodes == null || nodes.Count == 0) {
throw new Exception("No component found");
}
var componentId = nodes[0].Attributes[XMLNames.Component_ID_Attr].Value;
return GetHashValueFromSig(DoComputeHash(nodes[0]), componentId);
return GetHashValueFromSig(DoComputeHash(nodes[0], canonicalization, digestMethod), componentId);
}
public string ComputeHash(VectoComponents component, int index = 0)
public string ComputeHash(VectoComponents component, int index = 0, IEnumerable<string> canonicalization = null,
string digestMethod = null)
{
var nodes = Document.SelectNodes(GetComponentQueryString(component));
......@@ -133,16 +134,29 @@ namespace TUGraz.VectoHashing
nodes.Count));
}
var componentId = nodes[index].Attributes[XMLNames.Component_ID_Attr].Value;
return GetHashValueFromSig(DoComputeHash(nodes[index]), componentId);
return GetHashValueFromSig(DoComputeHash(nodes[index], canonicalization, digestMethod), componentId);
}
private static XmlDocument DoComputeHash(XmlNode dataNode)
private static XmlDocument DoComputeHash(XmlNode dataNode, IEnumerable<string> canonicalization, string digestMethod)
{
var parent = dataNode.ParentNode;
if (parent == null) {
throw new Exception("Invalid structure of input XML!");
}
if (canonicalization == null) {
canonicalization = ReadCanonicalizationMethods(parent);
}
if (digestMethod == null) {
digestMethod = ReadDigestMethod(parent);
}
canonicalization = canonicalization ?? XMLHashProvider.DefaultCanonicalizationMethod;
digestMethod = digestMethod ?? XMLHashProvider.DefaultDigestMethod;
// copy the provided data Node to a new document before computing the hash
// required if the same component (e.g. tire) is used multiple times
var newDoc = new XmlDocument();
var node = newDoc.CreateElement("Dummy");
newDoc.AppendChild(node);
......@@ -150,7 +164,28 @@ namespace TUGraz.VectoHashing
node.AppendChild(newNode);
var componentId = dataNode.Attributes[XMLNames.Component_ID_Attr].Value;
return XMLHashProvider.ComputeHash(newDoc, componentId);
return XMLHashProvider.ComputeHash(newDoc, componentId, canonicalization, digestMethod);
}
private static string ReadDigestMethod(XmlNode rootNode)
{
var nodes = rootNode.SelectNodes("./*[local-name()='Signature']//*[local-name() = 'DigestMethod']/@Algorithm");
if (nodes == null || nodes.Count == 0) {
return null;
}
if (nodes.Count > 1) {
throw new Exception("Multiple DigestValue elements found!");
}
return nodes[0].InnerText;
}
private static IEnumerable<string> ReadCanonicalizationMethods(XmlNode rootNode)
{
var nodes = rootNode.SelectNodes("./*[local-name()='Signature']//*[local-name() = 'Transform']/@Algorithm");
if (nodes == null || nodes.Count == 0) {
return null;
}
return (from XmlNode node in nodes select node.InnerText).ToArray();
}
public XDocument AddHash()
......@@ -197,7 +232,8 @@ namespace TUGraz.VectoHashing
dateNode.FirstChild.Value = XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc);
var hash = XMLHashProvider.ComputeHash(Document, id);
var hash = XMLHashProvider.ComputeHash(Document, id, XMLHashProvider.DefaultCanonicalizationMethod,
XMLHashProvider.DefaultDigestMethod);
var sig = Document.CreateElement(XMLNames.DI_Signature, node.NamespaceURI);
if (node.ParentNode == null || hash.DocumentElement == null) {
......@@ -235,26 +271,68 @@ namespace TUGraz.VectoHashing
throw new Exception("unknown document structure! neither input data nor output data format");
}
public string GetDigestMethod()
{
return DoGetDigestMethod(null, 0);
}
public string GetDigestMethod(VectoComponents component, int index = 0)
{
return DoGetDigestMethod(component, index);
}
private string DoGetDigestMethod(VectoComponents? component, int index)
{
var nodes = GetNodes(component, index);
return ReadDigestMethod(nodes[index].ParentNode);
}
public IEnumerable<string> GetCanonicalizationMethods()
{
return DoGetCanonicalizationMethods(null, 0);
}
public IEnumerable<string> GetCanonicalizationMethods(VectoComponents component, int index = 0)
{
return DoGetCanonicalizationMethods(component, index);
}
private IEnumerable<string> DoGetCanonicalizationMethods(VectoComponents? component, int index)
{
var nodes = GetNodes(component, index);
return ReadCanonicalizationMethods(nodes[index].ParentNode);
}
public string ReadHash()
{
var nodes = Document.SelectNodes(GetComponentQueryString());
if (nodes == null || nodes.Count == 0) {
throw new Exception("No component found");
}
return ReadHashValue(nodes[0]);
return DoReadHash(null, 0);
}
public string ReadHash(VectoComponents component, int index = 0)
{
return DoReadHash(component, index);
}
private string DoReadHash(VectoComponents? component, int index)
{
var nodes = GetNodes(component, index);
return ReadHashValue(nodes[index]);
}
private XmlNodeList GetNodes(VectoComponents? component, int index)
{
var nodes = Document.SelectNodes(GetComponentQueryString(component));
if (nodes == null || nodes.Count == 0) {
throw new Exception(string.Format("Component {0} not found", component.XMLElementName()));
throw new Exception(component == null
? "No component found"
: string.Format("Component {0} not found", component.Value.XMLElementName()));
}
if (index >= nodes.Count) {
throw new Exception(string.Format("index exceeds number of components found! index: {0}, #components: {1}", index,
nodes.Count));
}
return ReadHashValue(nodes[index]);
return nodes;
}
......@@ -309,4 +387,4 @@ namespace TUGraz.VectoHashing
return nodes[0].InnerText;
}
}
}
\ No newline at end of file
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment