Skip to content

Commit b1da19d

Browse files
committed
Move utilities to the place where they belong
1 parent 6f81ec6 commit b1da19d

File tree

2 files changed

+117
-134
lines changed

2 files changed

+117
-134
lines changed

src/Utils/XML.php

Lines changed: 0 additions & 133 deletions
This file was deleted.

src/XML/CanonicalizableElementTrait.php

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
namespace SimpleSAML\XMLSecurity\XML;
66

77
use DOMElement;
8-
use SimpleSAML\XMLSecurity\Utils\XML;
8+
use SimpleSAML\Assert\Assert;
9+
use SimpleSAML\XMLSecurity\Constants as C;
10+
use SimpleSAML\XMLSecurity\Exception\ReferenceValidationFailedException;
11+
use SimpleSAML\XMLSecurity\Utils\XPath;
12+
use SimpleSAML\XMLSecurity\XML\ds\Transforms;
913

1014
/**
1115
* A trait implementing the CanonicalizableElementInterface.
@@ -25,6 +29,64 @@ trait CanonicalizableElementTrait
2529
abstract protected function getOriginalXML(): DOMElement;
2630

2731

32+
/**
33+
* Canonicalize any given node.
34+
*
35+
* @param \DOMElement $element The DOM element that needs canonicalization.
36+
* @param string $c14nMethod The identifier of the canonicalization algorithm to use.
37+
* See \SimpleSAML\XMLSecurity\Constants.
38+
* @param string[]|null $xpaths An array of xpaths to filter the nodes by. Defaults to null (no filters).
39+
* @param string[]|null $prefixes An array of namespace prefixes to filter the nodes by.
40+
* Defaults to null (no filters).
41+
*
42+
* @return string The canonical representation of the given DOM node, according to the algorithm requested.
43+
*/
44+
public function canonicalizeData(
45+
DOMElement $element,
46+
string $c14nMethod,
47+
?array $xpaths = null,
48+
?array $prefixes = null,
49+
): string {
50+
$withComments = match ($c14nMethod) {
51+
C::C14N_EXCLUSIVE_WITH_COMMENTS, C::C14N_INCLUSIVE_WITH_COMMENTS => true,
52+
default => false,
53+
};
54+
$exclusive = match ($c14nMethod) {
55+
C::C14N_EXCLUSIVE_WITH_COMMENTS, C::C14N_EXCLUSIVE_WITHOUT_COMMENTS => true,
56+
default => false,
57+
};
58+
59+
if (
60+
is_null($xpaths)
61+
&& ($element->ownerDocument !== null)
62+
&& ($element->ownerDocument->documentElement !== null)
63+
&& $element->isSameNode($element->ownerDocument->documentElement)
64+
) {
65+
// check for any PI or comments as they would have been excluded
66+
$current = $element;
67+
for ($refNode = $current->previousSibling; $refNode !== null; $current = $refNode) {
68+
if (
69+
(($refNode->nodeType === XML_COMMENT_NODE) && $withComments)
70+
|| $refNode->nodeType === XML_PI_NODE
71+
) {
72+
break;
73+
}
74+
}
75+
76+
if ($refNode === null) {
77+
$element = $element->ownerDocument;
78+
}
79+
}
80+
81+
$ret = $element->C14N($exclusive, $withComments, $xpaths, $prefixes);
82+
if ($ret === false) {
83+
// GHSA-h25p-2wxc-6584
84+
throw new CanonicalizationFailedException();
85+
}
86+
return $ret;
87+
}
88+
89+
2890
/**
2991
* Get the canonical (string) representation of this object.
3092
*
@@ -43,6 +105,60 @@ public function canonicalize(string $method, ?array $xpaths = null, ?array $pref
43105
}
44106

45107

108+
/**
109+
* Process all transforms specified by a given Reference element.
110+
*
111+
* @param \SimpleSAML\XMLSecurity\XML\ds\Transforms $transforms The transforms to apply.
112+
* @param \DOMElement $data The data referenced.
113+
*
114+
* @return string The canonicalized data after applying all transforms specified by $ref.
115+
*
116+
* @see http://www.w3.org/TR/xmldsig-core/#sec-ReferenceProcessingModel
117+
*/
118+
public function processTransforms(
119+
Transforms $transforms,
120+
DOMElement $data,
121+
): string {
122+
$canonicalMethod = C::C14N_EXCLUSIVE_WITHOUT_COMMENTS;
123+
$arXPath = null;
124+
$prefixList = null;
125+
foreach ($transforms->getTransform() as $transform) {
126+
$canonicalMethod = $transform->getAlgorithm()->getValue();
127+
switch ($canonicalMethod) {
128+
case C::C14N_EXCLUSIVE_WITHOUT_COMMENTS:
129+
case C::C14N_EXCLUSIVE_WITH_COMMENTS:
130+
$inclusiveNamespaces = $transform->getInclusiveNamespaces();
131+
if ($inclusiveNamespaces !== null) {
132+
$prefixes = $inclusiveNamespaces->getPrefixes();
133+
if ($prefixes !== null) {
134+
$prefixList = array_map('strval', $prefixes->toArray());
135+
}
136+
}
137+
break;
138+
case XPATH_C::XPATH10_URI:
139+
$xpath = $transform->getXPath();
140+
if ($xpath !== null) {
141+
$arXPath = [];
142+
$xpathValue = $xpath->getContent()->getValue();
143+
$arXPath['query'] = '(.//. | .//@* | .//namespace::*)[' . $xpathValue . ']';
144+
145+
// $arXpath['namespaces'] = $xpath->getNamespaces();
146+
// TODO: review if $nsnode->localName is equivalent to the keys in getNamespaces()
147+
// $nslist = $xp->query('./namespace::*', $node);
148+
// foreach ($nslist as $nsnode) {
149+
// if ($nsnode->localName != "xml") {
150+
// $arXPath['namespaces'][$nsnode->localName] = $nsnode->nodeValue;
151+
// }
152+
// }
153+
}
154+
break;
155+
}
156+
}
157+
158+
return $this->canonicalizeData($data, $canonicalMethod, $arXPath, $prefixList);
159+
}
160+
161+
46162
/**
47163
* Serialize this canonicalisable element.
48164
*

0 commit comments

Comments
 (0)