From 4c068e68e4e8b787b5e1bf4f99054b00171e4263 Mon Sep 17 00:00:00 2001 From: John Wu Date: Fri, 7 Jul 2023 11:08:17 +0100 Subject: [PATCH] Ensure canonizalization is the last transform --- lib/xmldsig/transforms.rb | 28 +++++++++++++--- .../with_unsorted_canonizalization.xml | 32 +++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 spec/fixtures/unsigned/with_unsorted_canonizalization.xml diff --git a/lib/xmldsig/transforms.rb b/lib/xmldsig/transforms.rb index 9d93265..cedd969 100644 --- a/lib/xmldsig/transforms.rb +++ b/lib/xmldsig/transforms.rb @@ -1,8 +1,18 @@ module Xmldsig class Transforms < Array + CANONIZALIZATION_ALGORITHMS = { + without_comments: [ + "http://www.w3.org/2001/10/xml-exc-c14n#", + "http://www.w3.org/TR/2001/REC-xml-c14n-20010315", + "http://www.w3.org/2006/12/xml-c14n11" + ], + with_comments: "http://www.w3.org/2001/10/xml-exc-c14n#WithComments" + }.freeze def apply(node) @node = node + reorder_canonizalization! + each do |transform_node| @node = get_transform(@node, transform_node).transform end @@ -15,16 +25,26 @@ def get_transform(node, transform_node) case transform_node.get_attribute("Algorithm") when "http://www.w3.org/2000/09/xmldsig#enveloped-signature" Transforms::EnvelopedSignature.new(node, transform_node) - when "http://www.w3.org/2001/10/xml-exc-c14n#", - "http://www.w3.org/TR/2001/REC-xml-c14n-20010315", - "http://www.w3.org/2006/12/xml-c14n11" + when *CANONIZALIZATION_ALGORITHMS[:without_comments] Transforms::Canonicalize.new(node, transform_node) - when "http://www.w3.org/2001/10/xml-exc-c14n#WithComments" + when CANONIZALIZATION_ALGORITHMS[:with_comments] Transforms::Canonicalize.new(node, transform_node, true) when "http://www.w3.org/TR/1999/REC-xpath-19991116" Transforms::XPath.new(node, transform_node) end end + def reorder_canonizalization! + algorithms = CANONIZALIZATION_ALGORITHMS.values.flatten + canonizalization = find do |transform_node| + algorithms.include?(transform_node.get_attribute("Algorithm")) + end + + return if canonizalization.nil? || self[-1] == canonizalization + + position = index(canonizalization) + delete_at(position) + self << canonizalization + end end end diff --git a/spec/fixtures/unsigned/with_unsorted_canonizalization.xml b/spec/fixtures/unsigned/with_unsorted_canonizalization.xml new file mode 100644 index 0000000..3d904f2 --- /dev/null +++ b/spec/fixtures/unsigned/with_unsorted_canonizalization.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +