diff --git a/resources/schemas/ws-securitypolicy-1.2.xsd b/resources/schemas/ws-securitypolicy-1.2.xsd
index 710acf4b..b52f120d 100644
--- a/resources/schemas/ws-securitypolicy-1.2.xsd
+++ b/resources/schemas/ws-securitypolicy-1.2.xsd
@@ -29,7 +29,7 @@ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
blockDefault="#all" >
+ schemaLocation="ws-addr.xsd" />
@@ -109,11 +131,11 @@ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-
-
-
+
+
+
+
+
@@ -1194,7 +1216,7 @@ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
+
10.1 Trust13 Assertion
@@ -1202,4 +1224,4 @@ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
\ No newline at end of file
+
diff --git a/src/Constants.php b/src/Constants.php
index 1a84f602..e8e6596a 100644
--- a/src/Constants.php
+++ b/src/Constants.php
@@ -42,6 +42,11 @@ class Constants extends \SimpleSAML\SAML2\Constants
*/
public const NS_SEC_EXT = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
+ /**
+ * The namespace for WS Security Policy.
+ */
+ public const NS_SEC_POLICY = 'http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702';
+
/**
* The namespace for WS-Security utilities protocol.
*/
diff --git a/src/Utils/XPath.php b/src/Utils/XPath.php
new file mode 100644
index 00000000..cba95d16
--- /dev/null
+++ b/src/Utils/XPath.php
@@ -0,0 +1,41 @@
+registerNamespace('addr', C::NS_ADDR);
+ $xp->registerNamespace('auth', C::NS_AUTH);
+ $xp->registerNamespace('fed', C::NS_FED);
+ $xp->registerNamespace('trust', C::NS_TRUST);
+ $xp->registerNamespace('policy', C::NS_POLICY);
+ $xp->registerNamespace('sp', C::NS_SEC_POLICY);
+ $xp->registerNamespace('wsse', C::NS_SEC_EXT);
+ $xp->registerNamespace('wsu', C::NS_SEC_UTIL);
+
+ return $xp;
+ }
+}
diff --git a/src/XML/sp/AbsXPath.php b/src/XML/sp/AbsXPath.php
new file mode 100644
index 00000000..b59ff705
--- /dev/null
+++ b/src/XML/sp/AbsXPath.php
@@ -0,0 +1,14 @@
+localName,
+ $qualifiedName,
+ sprintf('Unexpected name for EmptyType: %s. Expected: %s.', $xml->localName, $qualifiedName),
+ InvalidDOMElementException::class
+ );
+
+
+ return new static();
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ return $this->instantiateParentElement($parent);
+ }
+}
diff --git a/src/XML/sp/AbstractHeaderType.php b/src/XML/sp/AbstractHeaderType.php
new file mode 100644
index 00000000..08d65115
--- /dev/null
+++ b/src/XML/sp/AbstractHeaderType.php
@@ -0,0 +1,129 @@
+ $namespacedAttributes
+ */
+ final public function __construct(
+ protected string $namespace,
+ protected ?string $name = null,
+ array $namespacedAttributes = []
+ ) {
+ Assert::nullOrValidURI($namespace);
+ Assert::validQName($name);
+
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Collect the value of the Name property.
+ *
+ * @return string|null
+ */
+ public function getName(): ?string
+ {
+ return $this->name;
+ }
+
+
+ /**
+ * Collect the value of the Namespace property.
+ *
+ * @return string
+ */
+ public function getNamespace(): string
+ {
+ return $this->namespace;
+ }
+
+
+ /**
+ * Initialize an HeaderType.
+ *
+ * Note: this method cannot be used when extending this class, if the constructor has a different signature.
+ *
+ * @param \DOMElement $xml The XML element we should load.
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ $qualifiedName = static::getClassName(static::class);
+ Assert::eq(
+ $xml->localName,
+ $qualifiedName,
+ sprintf('Unexpected name for HeaderType: %s. Expected: %s.', $xml->localName, $qualifiedName),
+ InvalidDOMElementException::class
+ );
+
+ $namespacedAttributes = self::getAttributesNSFromXML($xml);
+ foreach ($namespacedAttributes as $i => $attr) {
+ if ($attr->getNamespaceURI() === null) {
+ if ($attr->getAttrName() === 'Name' || $attr->getAttrName() === 'Namespace') {
+ unset($namespacedAttributes[$i]);
+ }
+ }
+ }
+
+ return new static(
+ self::getAttribute($xml, 'Namespace'),
+ self::getOptionalAttribute($xml, 'Name', null),
+ $namespacedAttributes,
+ );
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ if ($this->getName() !== null) {
+ $e->setAttribute('Name', $this->getName());
+ }
+
+ $e->setAttribute('Namespace', $this->getNamespace());
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AbstractIssuedTokenType.php b/src/XML/sp/AbstractIssuedTokenType.php
new file mode 100644
index 00000000..e673aba0
--- /dev/null
+++ b/src/XML/sp/AbstractIssuedTokenType.php
@@ -0,0 +1,186 @@
+ $elts
+ * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
+ */
+ final public function __construct(
+ protected RequestSecurityTokenTemplate $requestSecurityTokenTemplate,
+ protected Issuer|IssuerName|null $issuer,
+ ?IncludeToken $includeToken = null,
+ array $elts = [],
+ array $namespacedAttributes = []
+ ) {
+ $this->setIncludeToken($includeToken);
+ $this->setElements($elts);
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Collect the value of the Issuer property.
+ *
+ * @return \SimpleSAML\WSSecurity\XML\sp\Issuer|\SimpleSAML\WSSecurity\XML\sp\IssuerName|null
+ */
+ public function getIssuer(): Issuer|IssuerName|null
+ {
+ return $this->issuer;
+ }
+
+
+ /**
+ * Collect the value of the RequestSecurityTokenTemplate property.
+ *
+ * @return \SimpleSAML\WSSecurity\XML\sp\RequestSecurityTokenTemplate
+ */
+ public function getRequestSecurityTokenTemplate(): RequestSecurityTokenTemplate
+ {
+ return $this->requestSecurityTokenTemplate;
+ }
+
+
+ /**
+ * Initialize an IssuedTokenType.
+ *
+ * Note: this method cannot be used when extending this class, if the constructor has a different signature.
+ *
+ * @param \DOMElement $xml The XML element we should load.
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ $qualifiedName = static::getClassName(static::class);
+ Assert::eq(
+ $xml->localName,
+ $qualifiedName,
+ sprintf('Unexpected name for IssuedTokenType: %s. Expected: %s.', $xml->localName, $qualifiedName),
+ InvalidDOMElementException::class
+ );
+
+ $issuer = Issuer::getChildrenOfClass($xml);
+ $issuerName = IssuerName::getChildrenOfClass($xml);
+ $issuer = array_merge($issuer, $issuerName);
+
+ $requestSecurityTokenTemplate = RequestSecurityTokenTemplate::getChildrenOfClass($xml);
+ Assert::minCount($requestSecurityTokenTemplate, 1, MissingElementException::class);
+ Assert::maxCount($requestSecurityTokenTemplate, 1, TooManyElementsException::class);
+
+ try {
+ $includeToken = IncludeToken::from(self::getOptionalAttribute($xml, 'IncludeToken', null));
+ } catch (ValueError) {
+ self::getOptionalAttribute($xml, 'IncludeToken', null);
+ }
+
+ $elements = [];
+ foreach ($xml->childNodes as $element) {
+ if ($element->namespaceURI === static::NS) {
+ continue;
+ } elseif (!($element instanceof DOMElement)) {
+ continue;
+ }
+
+ $elements[] = new Chunk($element);
+ }
+
+ $namespacedAttributes = self::getAttributesNSFromXML($xml);
+ foreach ($namespacedAttributes as $i => $attr) {
+ if ($attr->getNamespaceURI() === null) {
+ if ($attr->getAttrName() === 'IncludeToken') {
+ unset($namespacedAttributes[$i]);
+ break;
+ }
+ }
+ }
+
+
+ return new static(
+ $requestSecurityTokenTemplate[0],
+ array_pop($issuer),
+ $includeToken,
+ $elements,
+ $namespacedAttributes,
+ );
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ if ($this->getIncludeToken() !== null) {
+ $e->setAttribute(
+ 'IncludeToken',
+ is_string($this->getIncludeToken()) ? $this->getIncludeToken() : $this->getIncludeToken()->value,
+ );
+ }
+
+ if ($this->getIssuer() !== null) {
+ $this->getIssuer()->toXML($e);
+ }
+
+ $this->getRequestSecurityTokenTemplate()->toXML($e);
+
+ foreach ($this->getElements() as $elt) {
+ /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $elt */
+ $elt->toXML($e);
+ }
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AbstractKeyValueTokenType.php b/src/XML/sp/AbstractKeyValueTokenType.php
new file mode 100644
index 00000000..4faa2d8f
--- /dev/null
+++ b/src/XML/sp/AbstractKeyValueTokenType.php
@@ -0,0 +1,157 @@
+ $elts
+ * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
+ */
+ final public function __construct(
+ ?IncludeToken $includeToken = null,
+ array $elts = [],
+ array $namespacedAttributes = []
+ ) {
+ $this->setIncludeToken($includeToken);
+ $this->setElements($elts);
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Test if an object, at the state it's in, would produce an empty XML-element
+ *
+ * @return bool
+ */
+ public function isEmptyElement(): bool
+ {
+ return empty($this->getIncludeToken())
+ && empty($this->getAttributesNS())
+ && empty($this->getElements());
+ }
+
+
+ /**
+ * Initialize an KeyValueTokenType.
+ *
+ * Note: this method cannot be used when extending this class, if the constructor has a different signature.
+ *
+ * @param \DOMElement $xml The XML element we should load.
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ $qualifiedName = static::getClassName(static::class);
+ Assert::eq(
+ $xml->localName,
+ $qualifiedName,
+ sprintf('Unexpected name for KeyValueTokenType: %s. Expected: %s.', $xml->localName, $qualifiedName),
+ InvalidDOMElementException::class
+ );
+
+ try {
+ $includeToken = IncludeToken::from(self::getOptionalAttribute($xml, 'IncludeToken', null));
+ } catch (ValueError) {
+ self::getOptionalAttribute($xml, 'IncludeToken', null);
+ }
+
+ $elements = [];
+ foreach ($xml->childNodes as $element) {
+ if ($element->namespaceURI === static::NS) {
+ continue;
+ } elseif (!($element instanceof DOMElement)) {
+ continue;
+ }
+
+ $elements[] = new Chunk($element);
+ }
+
+ $namespacedAttributes = self::getAttributesNSFromXML($xml);
+ foreach ($namespacedAttributes as $i => $attr) {
+ if ($attr->getNamespaceURI() === null) {
+ if ($attr->getAttrName() === 'IncludeToken') {
+ unset($namespacedAttributes[$i]);
+ break;
+ }
+ }
+ }
+
+
+ return new static(
+ $includeToken,
+ $elements,
+ $namespacedAttributes,
+ );
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ if ($this->getIncludeToken() !== null) {
+ $e->setAttribute(
+ 'IncludeToken',
+ is_string($this->getIncludeToken()) ? $this->getIncludeToken() : $this->getIncludeToken()->value,
+ );
+ }
+
+ foreach ($this->getElements() as $elt) {
+ /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $elt */
+ $elt->toXML($e);
+ }
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AbstractNestedPolicyType.php b/src/XML/sp/AbstractNestedPolicyType.php
new file mode 100644
index 00000000..e19c3ee6
--- /dev/null
+++ b/src/XML/sp/AbstractNestedPolicyType.php
@@ -0,0 +1,109 @@
+setElements($elements);
+ $this->setAttributesNS($attributes);
+ }
+
+
+
+ /**
+ * Test if an object, at the state it's in, would produce an empty XML-element
+ *
+ * @return bool
+ */
+ public function isEmptyElement(): bool
+ {
+ return empty($this->getAttributesNS())
+ && empty($this->getElements());
+ }
+
+
+ /**
+ * Convert XML into a AbstractNestedPolicyType
+ *
+ * @param \DOMElement $xml The XML element we should load
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
+ Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
+
+ $elements = [];
+ foreach ($xml->childNodes as $element) {
+ if ($element->namespaceURI === static::NS) {
+ continue;
+ } elseif (!($element instanceof DOMElement)) {
+ continue;
+ }
+
+ $elements[] = new Chunk($element);
+ }
+
+ return new static($elements, self::getAttributesNSFromXML($xml));
+ }
+
+
+ /**
+ * Convert this AbstractNestedPolicyType to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this AbstractNestedPolicyType to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ foreach ($this->getElements() as $element) {
+ /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $element */
+ $element->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AbstractQNameAssertionType.php b/src/XML/sp/AbstractQNameAssertionType.php
new file mode 100644
index 00000000..c22c4d6e
--- /dev/null
+++ b/src/XML/sp/AbstractQNameAssertionType.php
@@ -0,0 +1,83 @@
+ $namespacedAttributes
+ */
+ final public function __construct(
+ array $namespacedAttributes = []
+ ) {
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Initialize an QNameAssertionType.
+ *
+ * Note: this method cannot be used when extending this class, if the constructor has a different signature.
+ *
+ * @param \DOMElement $xml The XML element we should load.
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ $qualifiedName = static::getClassName(static::class);
+ Assert::eq(
+ $xml->localName,
+ $qualifiedName,
+ sprintf('Unexpected name for QNameAssertion: %s. Expected: %s.', $xml->localName, $qualifiedName),
+ InvalidDOMElementException::class
+ );
+
+
+ return new static(self::getAttributesNSFromXML($xml));
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AbstractReqPartsType.php b/src/XML/sp/AbstractReqPartsType.php
new file mode 100644
index 00000000..65f1ee32
--- /dev/null
+++ b/src/XML/sp/AbstractReqPartsType.php
@@ -0,0 +1,145 @@
+setElements($details);
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Collect the Header
+ *
+ * @return \SimpleSAML\WSSecurity\XML\sp\Header[]
+ */
+ public function getHeader(): array
+ {
+ return $this->header;
+ }
+
+
+ /**
+ * Test if an object, at the state it's in, would produce an empty XML-element
+ *
+ * @return bool
+ */
+ public function isEmptyElement(): bool
+ {
+ return empty($this->getElements())
+ && empty($this->getHeader())
+ && empty($this->getAttributesNS());
+ }
+
+
+ /**
+ * Initialize an ReqPartsType.
+ *
+ * Note: this method cannot be used when extending this class, if the constructor has a different signature.
+ *
+ * @param \DOMElement $xml The XML element we should load.
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ $qualifiedName = static::getClassName(static::class);
+ Assert::eq(
+ $xml->localName,
+ $qualifiedName,
+ sprintf('Unexpected name for Empty: %s. Expected: %s.', $xml->localName, $qualifiedName),
+ InvalidDOMElementException::class
+ );
+
+ $header = Header::getChildrenOfClass($xml);
+ Assert::maxcount($header, 1, TooManyElementsException::class);
+
+ $details = [];
+ foreach ($xml->childNodes as $detail) {
+ if (!($detail instanceof DOMElement)) {
+ continue;
+ } elseif ($detail->namespaceURI === static::NS) {
+ continue;
+ }
+
+ $details[] = new Chunk($detail);
+ }
+
+ return new static(
+ $header,
+ $details,
+ self::getAttributesNSFromXML($xml),
+ );
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ foreach ($this->getHeader() as $header) {
+ $header->toXML($e);
+ }
+
+ foreach ($this->getElements() as $elt) {
+ /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $elt */
+ $elt->toXML($e);
+ }
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AbstractRequestSecurityTokenTemplateType.php b/src/XML/sp/AbstractRequestSecurityTokenTemplateType.php
new file mode 100644
index 00000000..09217385
--- /dev/null
+++ b/src/XML/sp/AbstractRequestSecurityTokenTemplateType.php
@@ -0,0 +1,155 @@
+ $elts
+ * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
+ */
+ final public function __construct(
+ protected ?string $trustVersion = null,
+ array $elts = [],
+ array $namespacedAttributes = []
+ ) {
+ Assert::nullOrValidURI($trustVersion);
+
+ $this->setElements($elts);
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Collect the value of the trustVersion property.
+ *
+ * @return string|null
+ */
+ public function getTrustVersion(): ?string
+ {
+ return $this->trustVersion;
+ }
+
+
+ /**
+ * Test if an object, at the state it's in, would produce an empty XML-element
+ *
+ * @return bool
+ */
+ public function isEmptyElement(): bool
+ {
+ return empty($this->trustVersion) && empty($this->elements) && empty($this->namespacedAttributes);
+ }
+
+
+ /**
+ * Initialize an RequestSecurityTokenTemplateType.
+ *
+ * Note: this method cannot be used when extending this class, if the constructor has a different signature.
+ *
+ * @param \DOMElement $xml The XML element we should load.
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ $qualifiedName = static::getClassName(static::class);
+ Assert::eq(
+ $xml->localName,
+ $qualifiedName,
+ sprintf(
+ 'Unexpected name for RequestSecurityTokenTemplateType: %s. Expected: %s.',
+ $xml->localName,
+ $qualifiedName,
+ ),
+ InvalidDOMElementException::class
+ );
+
+ $elements = [];
+ foreach ($xml->childNodes as $element) {
+ if ($element->namespaceURI === static::NS) {
+ continue;
+ } elseif (!($element instanceof DOMElement)) {
+ continue;
+ }
+
+ $elements[] = new Chunk($element);
+ }
+
+ $namespacedAttributes = self::getAttributesNSFromXML($xml);
+ foreach ($namespacedAttributes as $i => $attr) {
+ if ($attr->getNamespaceURI() === null) {
+ if ($attr->getAttrName() === 'TrustVersion') {
+ unset($namespacedAttributes[$i]);
+ break;
+ }
+ }
+ }
+
+ return new static(
+ self::getOptionalAttribute($xml, 'TrustVersion', null),
+ $elements,
+ $namespacedAttributes,
+ );
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ if ($this->getTrustVersion() !== null) {
+ $e->setAttribute('TrustVersion', $this->getTrustVersion());
+ }
+
+ foreach ($this->getElements() as $elt) {
+ /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $elt */
+ $elt->toXML($e);
+ }
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AbstractSePartsType.php b/src/XML/sp/AbstractSePartsType.php
new file mode 100644
index 00000000..179cb8c7
--- /dev/null
+++ b/src/XML/sp/AbstractSePartsType.php
@@ -0,0 +1,187 @@
+setElements($details);
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Collect the Body
+ *
+ * @return \SimpleSAML\WSSecurity\XML\sp\Body|null
+ */
+ public function getBody(): ?Body
+ {
+ return $this->body;
+ }
+
+
+ /**
+ * Collect the Header
+ *
+ * @return \SimpleSAML\WSSecurity\XML\sp\Header[]
+ */
+ public function getHeader(): array
+ {
+ return $this->header;
+ }
+
+
+ /**
+ * Collect the Attachments
+ *
+ * @return \SimpleSAML\WSSecurity\XML\sp\Attachments|null
+ */
+ public function getAttachments(): ?Attachments
+ {
+ return $this->attachments;
+ }
+
+
+ /**
+ * Test if an object, at the state it's in, would produce an empty XML-element
+ *
+ * @return bool
+ */
+ public function isEmptyElement(): bool
+ {
+ return empty($this->getElements())
+ && empty($this->getBody())
+ && empty($this->getHeader())
+ && empty($this->getAttachments())
+ && empty($this->getAttributesNS());
+ }
+
+
+ /**
+ * Initialize an SePartsType.
+ *
+ * Note: this method cannot be used when extending this class, if the constructor has a different signature.
+ *
+ * @param \DOMElement $xml The XML element we should load.
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ $qualifiedName = static::getClassName(static::class);
+ Assert::eq(
+ $xml->localName,
+ $qualifiedName,
+ sprintf('Unexpected name for Empty: %s. Expected: %s.', $xml->localName, $qualifiedName),
+ InvalidDOMElementException::class
+ );
+
+ $body = Body::getChildrenOfClass($xml);
+
+ $header = Header::getChildrenOfClass($xml);
+ Assert::maxcount($header, 1, TooManyElementsException::class);
+
+ $attachments = Attachments::getChildrenOfClass($xml);
+
+ $details = [];
+ foreach ($xml->childNodes as $detail) {
+ if (!($detail instanceof DOMElement)) {
+ continue;
+ } elseif ($detail->namespaceURI === static::NS) {
+ continue;
+ }
+
+ $details[] = new Chunk($detail);
+ }
+
+ return new static(
+ array_pop($body),
+ $header,
+ array_pop($attachments),
+ $details,
+ self::getAttributesNSFromXML($xml),
+ );
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ if ($this->getBody() !== null) {
+ $this->getBody()->toXML($e);
+ }
+
+ foreach ($this->getHeader() as $header) {
+ $header->toXML($e);
+ }
+
+ if ($this->getAttachments() !== null) {
+ $this->getAttachments()->toXML($e);
+ }
+
+ foreach ($this->getElements() as $elt) {
+ /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $elt */
+ $elt->toXML($e);
+ }
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AbstractSecureConversationTokenType.php b/src/XML/sp/AbstractSecureConversationTokenType.php
new file mode 100644
index 00000000..782c3b7f
--- /dev/null
+++ b/src/XML/sp/AbstractSecureConversationTokenType.php
@@ -0,0 +1,180 @@
+ $elts
+ * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
+ */
+ final public function __construct(
+ protected Issuer|IssuerName|null $issuer,
+ ?IncludeToken $includeToken = null,
+ array $elts = [],
+ array $namespacedAttributes = []
+ ) {
+ $this->setIncludeToken($includeToken);
+ $this->setElements($elts);
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Collect the value of the Issuer property.
+ *
+ * @return \SimpleSAML\WSSecurity\XML\sp\Issuer|\SimpleSAML\WSSecurity\XML\sp\IssuerName|null
+ */
+ public function getIssuer(): Issuer|IssuerName|null
+ {
+ return $this->issuer;
+ }
+
+
+ /**
+ * Test if an object, at the state it's in, would produce an empty XML-element
+ *
+ * @return bool
+ */
+ public function isEmptyElement(): bool
+ {
+ return empty($this->getIssuer())
+ && empty($this->getIncludeToken())
+ && empty($this->getAttributesNS())
+ && empty($this->getElements());
+ }
+
+
+ /**
+ * Initialize an SecureConversationTokenType.
+ *
+ * Note: this method cannot be used when extending this class, if the constructor has a different signature.
+ *
+ * @param \DOMElement $xml The XML element we should load.
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ $qualifiedName = static::getClassName(static::class);
+ Assert::eq(
+ $xml->localName,
+ $qualifiedName,
+ sprintf('Unexpected name for IssuedTokenType: %s. Expected: %s.', $xml->localName, $qualifiedName),
+ InvalidDOMElementException::class
+ );
+
+ $issuer = Issuer::getChildrenOfClass($xml);
+ $issuerName = IssuerName::getChildrenOfClass($xml);
+ $issuer = array_merge($issuer, $issuerName);
+
+ try {
+ $includeToken = IncludeToken::from(self::getOptionalAttribute($xml, 'IncludeToken', null));
+ } catch (ValueError) {
+ self::getOptionalAttribute($xml, 'IncludeToken', null);
+ }
+
+ $elements = [];
+ foreach ($xml->childNodes as $element) {
+ if ($element->namespaceURI === static::NS) {
+ continue;
+ } elseif (!($element instanceof DOMElement)) {
+ continue;
+ }
+
+ $elements[] = new Chunk($element);
+ }
+
+ $namespacedAttributes = self::getAttributesNSFromXML($xml);
+ foreach ($namespacedAttributes as $i => $attr) {
+ if ($attr->getNamespaceURI() === null) {
+ if ($attr->getAttrName() === 'IncludeToken') {
+ unset($namespacedAttributes[$i]);
+ break;
+ }
+ }
+ }
+
+
+ return new static(
+ array_pop($issuer),
+ $includeToken,
+ $elements,
+ $namespacedAttributes,
+ );
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ if ($this->getIncludeToken() !== null) {
+ $e->setAttribute(
+ 'IncludeToken',
+ is_string($this->getIncludeToken()) ? $this->getIncludeToken() : $this->getIncludeToken()->value,
+ );
+ }
+
+ if ($this->getIssuer() !== null) {
+ $this->getIssuer()->toXML($e);
+ }
+
+ foreach ($this->getElements() as $elt) {
+ /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $elt */
+ $elt->toXML($e);
+ }
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AbstractSerElementsType.php b/src/XML/sp/AbstractSerElementsType.php
new file mode 100644
index 00000000..fb61e72f
--- /dev/null
+++ b/src/XML/sp/AbstractSerElementsType.php
@@ -0,0 +1,159 @@
+ $xpath
+ * @param string|null $xpathVersion
+ * @param list<\SimpleSAML\XML\ElementInterface> $elts
+ * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
+ */
+ final public function __construct(
+ protected array $xpath,
+ protected ?string $xpathVersion = null,
+ array $elts = [],
+ array $namespacedAttributes = []
+ ) {
+ Assert::minCount($xpath, 1, SchemaViolationException::class);
+ Assert::nullOrValidURI($xpathVersion);
+
+ $this->setElements($elts);
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Collect the value of the XPath property.
+ *
+ * @return list<\SimpleSAML\WSSecurity\XML\sp\XPath>
+ */
+ public function getXPath(): array
+ {
+ return $this->xpath;
+ }
+
+
+ /**
+ * Collect the value of the XPathVersion property.
+ *
+ * @return string|null
+ */
+ public function getXPathVersion(): ?string
+ {
+ return $this->xpathVersion;
+ }
+
+
+ /**
+ * Initialize an SerElementsType.
+ *
+ * Note: this method cannot be used when extending this class, if the constructor has a different signature.
+ *
+ * @param \DOMElement $xml The XML element we should load.
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ $qualifiedName = static::getClassName(static::class);
+ Assert::eq(
+ $xml->localName,
+ $qualifiedName,
+ sprintf('Unexpected name for SerElementsType: %s. Expected: %s.', $xml->localName, $qualifiedName),
+ InvalidDOMElementException::class
+ );
+
+ $elements = [];
+ foreach ($xml->childNodes as $element) {
+ if ($element->namespaceURI === static::NS) {
+ continue;
+ } elseif (!($element instanceof DOMElement)) {
+ continue;
+ }
+
+ $elements[] = new Chunk($element);
+ }
+
+ $namespacedAttributes = self::getAttributesNSFromXML($xml);
+ foreach ($namespacedAttributes as $i => $attr) {
+ if ($attr->getNamespaceURI() === null) {
+ if ($attr->getAttrName() === 'XPathVersion') {
+ unset($namespacedAttributes[$i]);
+ break;
+ }
+ }
+ }
+
+ return new static(
+ XPath::getChildrenOfClass($xml),
+ self::getOptionalAttribute($xml, 'XPathVersion', null),
+ $elements,
+ $namespacedAttributes,
+ );
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ if ($this->getXPathVersion() !== null) {
+ $e->setAttribute('XPathVersion', $this->getXPathVersion());
+ }
+
+ foreach ($this->getXPath() as $xpath) {
+ $xpath->toXML($e);
+ }
+
+ foreach ($this->getElements() as $elt) {
+ /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $elt */
+ $elt->toXML($e);
+ }
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AbstractSpElement.php b/src/XML/sp/AbstractSpElement.php
new file mode 100644
index 00000000..019b8991
--- /dev/null
+++ b/src/XML/sp/AbstractSpElement.php
@@ -0,0 +1,22 @@
+ $elts
+ * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
+ */
+ final public function __construct(
+ protected Issuer|IssuerName|null $issuer,
+ ?IncludeToken $includeToken = null,
+ array $elts = [],
+ array $namespacedAttributes = []
+ ) {
+ $this->setIncludeToken($includeToken);
+ $this->setElements($elts);
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Collect the value of the Issuer property.
+ *
+ * @return \SimpleSAML\WSSecurity\XML\sp\Issuer|\SimpleSAML\WSSecurity\XML\sp\IssuerName|null
+ */
+ public function getIssuer(): Issuer|IssuerName|null
+ {
+ return $this->issuer;
+ }
+
+
+ /**
+ * Test if an object, at the state it's in, would produce an empty XML-element
+ *
+ * @return bool
+ */
+ public function isEmptyElement(): bool
+ {
+ return empty($this->getIssuer())
+ && empty($this->getIncludeToken())
+ && empty($this->getAttributesNS())
+ && empty($this->getElements());
+ }
+
+
+ /**
+ * Initialize an SpnegoContextTokenType.
+ *
+ * Note: this method cannot be used when extending this class, if the constructor has a different signature.
+ *
+ * @param \DOMElement $xml The XML element we should load.
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ $qualifiedName = static::getClassName(static::class);
+ Assert::eq(
+ $xml->localName,
+ $qualifiedName,
+ sprintf('Unexpected name for IssuedTokenType: %s. Expected: %s.', $xml->localName, $qualifiedName),
+ InvalidDOMElementException::class
+ );
+
+ $issuer = Issuer::getChildrenOfClass($xml);
+ $issuerName = IssuerName::getChildrenOfClass($xml);
+ $issuer = array_merge($issuer, $issuerName);
+
+ try {
+ $includeToken = IncludeToken::from(self::getOptionalAttribute($xml, 'IncludeToken', null));
+ } catch (ValueError) {
+ self::getOptionalAttribute($xml, 'IncludeToken', null);
+ }
+
+ $elements = [];
+ foreach ($xml->childNodes as $element) {
+ if ($element->namespaceURI === static::NS) {
+ continue;
+ } elseif (!($element instanceof DOMElement)) {
+ continue;
+ }
+
+ $elements[] = new Chunk($element);
+ }
+
+ $namespacedAttributes = self::getAttributesNSFromXML($xml);
+ foreach ($namespacedAttributes as $i => $attr) {
+ if ($attr->getNamespaceURI() === null) {
+ if ($attr->getAttrName() === 'IncludeToken') {
+ unset($namespacedAttributes[$i]);
+ break;
+ }
+ }
+ }
+
+
+ return new static(
+ array_pop($issuer),
+ $includeToken,
+ $elements,
+ $namespacedAttributes,
+ );
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ if ($this->getIncludeToken() !== null) {
+ $e->setAttribute(
+ 'IncludeToken',
+ is_string($this->getIncludeToken()) ? $this->getIncludeToken() : $this->getIncludeToken()->value,
+ );
+ }
+
+ if ($this->getIssuer() !== null) {
+ $this->getIssuer()->toXML($e);
+ }
+
+ foreach ($this->getElements() as $elt) {
+ /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $elt */
+ $elt->toXML($e);
+ }
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AbstractTokenAssertionType.php b/src/XML/sp/AbstractTokenAssertionType.php
new file mode 100644
index 00000000..eb9ed4b2
--- /dev/null
+++ b/src/XML/sp/AbstractTokenAssertionType.php
@@ -0,0 +1,157 @@
+ $elts
+ * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
+ */
+ final public function __construct(
+ ?IncludeToken $includeToken = null,
+ array $elts = [],
+ array $namespacedAttributes = []
+ ) {
+ $this->setIncludeToken($includeToken);
+ $this->setElements($elts);
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Test if an object, at the state it's in, would produce an empty XML-element
+ *
+ * @return bool
+ */
+ public function isEmptyElement(): bool
+ {
+ return empty($this->getIncludeToken())
+ && empty($this->getAttributesNS())
+ && empty($this->getElements());
+ }
+
+
+ /**
+ * Initialize an TokenAssertionType.
+ *
+ * Note: this method cannot be used when extending this class, if the constructor has a different signature.
+ *
+ * @param \DOMElement $xml The XML element we should load.
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ $qualifiedName = static::getClassName(static::class);
+ Assert::eq(
+ $xml->localName,
+ $qualifiedName,
+ sprintf('Unexpected name for TokenAssertionType: %s. Expected: %s.', $xml->localName, $qualifiedName),
+ InvalidDOMElementException::class
+ );
+
+ try {
+ $includeToken = IncludeToken::from(self::getOptionalAttribute($xml, 'IncludeToken', null));
+ } catch (ValueError) {
+ self::getOptionalAttribute($xml, 'IncludeToken', null);
+ }
+
+ $elements = [];
+ foreach ($xml->childNodes as $element) {
+ if ($element->namespaceURI === static::NS) {
+ continue;
+ } elseif (!($element instanceof DOMElement)) {
+ continue;
+ }
+
+ $elements[] = new Chunk($element);
+ }
+
+ $namespacedAttributes = self::getAttributesNSFromXML($xml);
+ foreach ($namespacedAttributes as $i => $attr) {
+ if ($attr->getNamespaceURI() === null) {
+ if ($attr->getAttrName() === 'IncludeToken') {
+ unset($namespacedAttributes[$i]);
+ break;
+ }
+ }
+ }
+
+
+ return new static(
+ $includeToken,
+ $elements,
+ $namespacedAttributes,
+ );
+ }
+
+
+ /**
+ * Convert this element to XML.
+ *
+ * @param \DOMElement|null $parent The element we should append this element to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = $this->instantiateParentElement($parent);
+
+ if ($this->getIncludeToken() !== null) {
+ $e->setAttribute(
+ 'IncludeToken',
+ is_string($this->getIncludeToken()) ? $this->getIncludeToken() : $this->getIncludeToken()->value,
+ );
+ }
+
+ foreach ($this->getElements() as $elt) {
+ /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $elt */
+ $elt->toXML($e);
+ }
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/sp/AlgorithmSuite.php b/src/XML/sp/AlgorithmSuite.php
new file mode 100644
index 00000000..07ee5ca8
--- /dev/null
+++ b/src/XML/sp/AlgorithmSuite.php
@@ -0,0 +1,14 @@
+includeToken;
+ }
+
+
+ /**
+ * Set the value of the includeToken-property
+ *
+ * @param \SimpleSAML\WSSecurity\XML\sp\IncludeToken|string|null $includeToken
+ */
+ protected function setIncludeToken(IncludeToken|string|null $includeToken): void
+ {
+ if (is_string($includeToken)) {
+ Assert::validURI($includeToken);
+ }
+
+ $this->includeToken = $includeToken;
+ }
+}
diff --git a/src/XML/sp/InclusiveC14N.php b/src/XML/sp/InclusiveC14N.php
new file mode 100644
index 00000000..1da447f2
--- /dev/null
+++ b/src/XML/sp/InclusiveC14N.php
@@ -0,0 +1,14 @@
+setContent($content);
+ }
+
+
+ /**
+ * Validate the content of the element.
+ *
+ * @param string $content The value to go in the XML textContent
+ * @throws \SimpleSAML\XML\Exception\SchemaViolationException on failure
+ * @return void
+ */
+ protected function validateContent(string $content): void
+ {
+ Assert::validURI($content);
+ }
+}
diff --git a/src/XML/sp/KerberosToken.php b/src/XML/sp/KerberosToken.php
new file mode 100644
index 00000000..96ee206d
--- /dev/null
+++ b/src/XML/sp/KerberosToken.php
@@ -0,0 +1,14 @@
+setContent($content);
+ }
+
+
+ /**
+ * Validate the content of the element.
+ *
+ * @param string $content The value to go in the XML textContent
+ * @throws \SimpleSAML\XML\Exception\SchemaViolationException on failure
+ * @return void
+ */
+ protected function validateContent(string $content): void
+ {
+ $dom = new DOMXPath(DOMDocumentFactory::create());
+ $result = $dom->evaluate($content);
+ Assert::isInstanceOf($result, DOMNodeList::class);
+ }
+}
diff --git a/src/XML/sp/XPath10.php b/src/XML/sp/XPath10.php
new file mode 100644
index 00000000..fdc26a83
--- /dev/null
+++ b/src/XML/sp/XPath10.php
@@ -0,0 +1,14 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/AsymmetricBindingTest.php b/tests/WSSecurity/XML/sp/AsymmetricBindingTest.php
new file mode 100644
index 00000000..f6c215ea
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/AsymmetricBindingTest.php
@@ -0,0 +1,58 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/AttachmentsTest.php b/tests/WSSecurity/XML/sp/AttachmentsTest.php
new file mode 100644
index 00000000..5dc4f58e
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/AttachmentsTest.php
@@ -0,0 +1,57 @@
+assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($attachments),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/Basic128Rsa15Test.php b/tests/WSSecurity/XML/sp/Basic128Rsa15Test.php
new file mode 100644
index 00000000..e166a40a
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/Basic128Rsa15Test.php
@@ -0,0 +1,44 @@
+assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($body),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/BootstrapPolicyTest.php b/tests/WSSecurity/XML/sp/BootstrapPolicyTest.php
new file mode 100644
index 00000000..ceaca73d
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/BootstrapPolicyTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/ContentEncryptedElementsTest.php b/tests/WSSecurity/XML/sp/ContentEncryptedElementsTest.php
new file mode 100644
index 00000000..6e7f2ef3
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/ContentEncryptedElementsTest.php
@@ -0,0 +1,114 @@
+35.00]/title');
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $contentEncryptedElements = new ContentEncryptedElements(
+ [$xpath],
+ 'urn:x-simplesamlphp:version',
+ [$chunk],
+ [$attr],
+ );
+ $contentEncryptedElementsElement = $contentEncryptedElements->toXML();
+
+ // Test for an XPath
+ $xpCache = XMLXPath::getXPath($contentEncryptedElementsElement);
+ $contentEncryptedElementsElements = XMLXPath::xpQuery(
+ $contentEncryptedElementsElement,
+ './sp:XPath',
+ $xpCache,
+ );
+ $this->assertCount(1, $contentEncryptedElementsElements);
+
+ // Test ordering of ContentEncryptedElements contents
+ /** @psalm-var \DOMElement[] $contentEncryptedElementsElements */
+ $contentEncryptedElementsElements = XMLXPath::xpQuery(
+ $contentEncryptedElementsElement,
+ './sp:XPath/following-sibling::*',
+ $xpCache,
+ );
+ $this->assertCount(1, $contentEncryptedElementsElements);
+ $this->assertEquals('ssp:Chunk', $contentEncryptedElementsElements[0]->tagName);
+ }
+
+
+ // test marshalling
+
+
+ /**
+ * Test that creating a ContentEncryptedElements from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $xpath = new XPath('/bookstore/book[price>35.00]/title');
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $contentEncryptedElements = new ContentEncryptedElements(
+ [$xpath],
+ 'urn:x-simplesamlphp:version',
+ [$chunk],
+ [$attr],
+ );
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($contentEncryptedElements),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/EncryptBeforeSigningTest.php b/tests/WSSecurity/XML/sp/EncryptBeforeSigningTest.php
new file mode 100644
index 00000000..47a21a1e
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/EncryptBeforeSigningTest.php
@@ -0,0 +1,44 @@
+35.00]/title');
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $EncryptedElements = new EncryptedElements([$xpath], 'urn:x-simplesamlphp:version', [$chunk], [$attr]);
+ $EncryptedElementsElement = $EncryptedElements->toXML();
+
+ // Test for an XPath
+ $xpCache = XMLXPath::getXPath($EncryptedElementsElement);
+ $EncryptedElementsElements = XMLXPath::xpQuery($EncryptedElementsElement, './sp:XPath', $xpCache);
+ $this->assertCount(1, $EncryptedElementsElements);
+
+ // Test ordering of EncryptedElements contents
+ /** @psalm-var \DOMElement[] $EncryptedElementsElements */
+ $EncryptedElementsElements = XMLXPath::xpQuery(
+ $EncryptedElementsElement,
+ './sp:XPath/following-sibling::*',
+ $xpCache,
+ );
+
+ $this->assertCount(1, $EncryptedElementsElements);
+ $this->assertEquals('ssp:Chunk', $EncryptedElementsElements[0]->tagName);
+ }
+
+
+ // test marshalling
+
+
+ /**
+ * Test that creating a EncryptedElements from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $xpath = new XPath('/bookstore/book[price>35.00]/title');
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $EncryptedElements = new EncryptedElements([$xpath], 'urn:x-simplesamlphp:version', [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($EncryptedElements),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/EncryptedPartsTest.php b/tests/WSSecurity/XML/sp/EncryptedPartsTest.php
new file mode 100644
index 00000000..fbf99eac
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/EncryptedPartsTest.php
@@ -0,0 +1,120 @@
+some'
+ )->documentElement);
+
+ $EncryptedParts = new EncryptedParts($body, [$header], $attachments, [$chunk], [$attr]);
+
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($EncryptedParts),
+ );
+ }
+
+
+ /**
+ * Adding an empty EncryptedParts element should yield an empty element.
+ */
+ public function testMarshallingEmptyElement(): void
+ {
+ $spns = C::NS_SEC_POLICY;
+ $encryptedParts = new EncryptedParts();
+ $this->assertEquals(
+ "",
+ strval($encryptedParts),
+ );
+ $this->assertTrue($encryptedParts->isEmptyElement());
+ }
+
+
+ /**
+ */
+ public function testMarshallingElementOrdering(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $body = new Body();
+ $header = new Header('urn:x-simplesamlphp:namespace', 'ssp:name', [$attr]);
+ $attachments = new Attachments();
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $EncryptedParts = new EncryptedParts($body, [$header], $attachments, [$chunk], [$attr]);
+ $EncryptedPartsElement = $EncryptedParts->toXML();
+
+ // Test for a Body
+ $xpCache = XPath::getXPath($EncryptedPartsElement);
+ $EncryptedPartsElements = XPath::xpQuery($EncryptedPartsElement, './sp:Body', $xpCache);
+ $this->assertCount(1, $EncryptedPartsElements);
+
+ // Test ordering of EncryptedParts contents
+ /** @psalm-var \DOMElement[] $EncryptedPartsElements */
+ $EncryptedPartsElements = XPath::xpQuery($EncryptedPartsElement, './sp:Body/following-sibling::*', $xpCache);
+ $this->assertCount(3, $EncryptedPartsElements);
+ $this->assertEquals('sp:Header', $EncryptedPartsElements[0]->tagName);
+ $this->assertEquals('sp:Attachments', $EncryptedPartsElements[1]->tagName);
+ $this->assertEquals('ssp:Chunk', $EncryptedPartsElements[2]->tagName);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/EncryptedSupportingTokensTest.php b/tests/WSSecurity/XML/sp/EncryptedSupportingTokensTest.php
new file mode 100644
index 00000000..4f25f821
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/EncryptedSupportingTokensTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/EncryptionTokenTest.php b/tests/WSSecurity/XML/sp/EncryptionTokenTest.php
new file mode 100644
index 00000000..697a32ad
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/EncryptionTokenTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/EndorsingEncryptedSupportingTokensTest.php b/tests/WSSecurity/XML/sp/EndorsingEncryptedSupportingTokensTest.php
new file mode 100644
index 00000000..10b0fd95
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/EndorsingEncryptedSupportingTokensTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/EndorsingSupportingTokensTest.php b/tests/WSSecurity/XML/sp/EndorsingSupportingTokensTest.php
new file mode 100644
index 00000000..26876692
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/EndorsingSupportingTokensTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/HashPasswordTest.php b/tests/WSSecurity/XML/sp/HashPasswordTest.php
new file mode 100644
index 00000000..8b9a0de1
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/HashPasswordTest.php
@@ -0,0 +1,44 @@
+assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($header),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/HttpBasicAuthenticationTest.php b/tests/WSSecurity/XML/sp/HttpBasicAuthenticationTest.php
new file mode 100644
index 00000000..96ff70e4
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/HttpBasicAuthenticationTest.php
@@ -0,0 +1,44 @@
+assertEquals(
+ "",
+ strval($httpsToken),
+ );
+ $this->assertTrue($httpsToken->isEmptyElement());
+ }
+
+
+ /**
+ * Test that creating a HttpsToken from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $httpsToken = new HttpsToken(IncludeToken::Always, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($httpsToken),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/IncludeTimestampTest.php b/tests/WSSecurity/XML/sp/IncludeTimestampTest.php
new file mode 100644
index 00000000..7dc0cd80
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/IncludeTimestampTest.php
@@ -0,0 +1,44 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/InitiatorSignatureTokenTest.php b/tests/WSSecurity/XML/sp/InitiatorSignatureTokenTest.php
new file mode 100644
index 00000000..63af2dd2
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/InitiatorSignatureTokenTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/InitiatorTokenTest.php b/tests/WSSecurity/XML/sp/InitiatorTokenTest.php
new file mode 100644
index 00000000..9be68fa1
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/InitiatorTokenTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/IssuedTokenTest.php b/tests/WSSecurity/XML/sp/IssuedTokenTest.php
new file mode 100644
index 00000000..1549115a
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/IssuedTokenTest.php
@@ -0,0 +1,111 @@
+some'
+ )->documentElement);
+ $requestSecurityTokenTemplate = new RequestSecurityTokenTemplate(
+ 'urn:x-simplesamlphp:version',
+ [$chunk],
+ [$attr],
+ );
+
+ $issuedToken = new IssuedToken($requestSecurityTokenTemplate, $issuer, IncludeToken::Always, [$chunk], [$attr]);
+ $issuedTokenElement = $issuedToken->toXML();
+
+ // Test for a Issuer
+ $xpCache = XPath::getXPath($issuedTokenElement);
+ $issuedTokenElements = XPath::xpQuery($issuedTokenElement, './sp:IssuerName', $xpCache);
+ $this->assertCount(1, $issuedTokenElements);
+
+ // Test ordering of IssuedToken contents
+ /** @psalm-var \DOMElement[] $issuedTokenElements */
+ $issuedTokenElements = XPath::xpQuery($issuedTokenElement, './sp:IssuerName/following-sibling::*', $xpCache);
+ $this->assertCount(2, $issuedTokenElements);
+ $this->assertEquals('sp:RequestSecurityTokenTemplate', $issuedTokenElements[0]->tagName);
+ $this->assertEquals('ssp:Chunk', $issuedTokenElements[1]->tagName);
+ }
+
+
+ // test marshalling
+
+
+ /**
+ * Test that creating a IssuedToken from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $issuer = new IssuerName('urn:x-simplesamlphp:issuer');
+ $requestSecurityTokenTemplate = new RequestSecurityTokenTemplate(
+ 'urn:x-simplesamlphp:version',
+ [$chunk],
+ [$attr],
+ );
+
+ $issuedToken = new IssuedToken($requestSecurityTokenTemplate, $issuer, IncludeToken::Always, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($issuedToken),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/IssuerNameTest.php b/tests/WSSecurity/XML/sp/IssuerNameTest.php
new file mode 100644
index 00000000..55265743
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/IssuerNameTest.php
@@ -0,0 +1,57 @@
+assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($issuerName),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/IssuerTest.php b/tests/WSSecurity/XML/sp/IssuerTest.php
new file mode 100644
index 00000000..a72cedac
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/IssuerTest.php
@@ -0,0 +1,100 @@
+Pears'
+ )->documentElement;
+
+ self::$metadataContent = DOMDocumentFactory::fromString(
+ 'Apples'
+ )->documentElement;
+
+ self::$customContent = DOMDocumentFactory::fromString(
+ 'SomeChunk'
+ )->documentElement;
+ }
+
+
+ // test marshalling
+
+
+ /**
+ * Test creating an Issuer object from scratch.
+ */
+ public function testMarshalling(): void
+ {
+ $attr1 = new Attribute('urn:x-simplesamlphp:namespace', 'ssp', 'test1', 'value1');
+ $attr2 = new Attribute('urn:x-simplesamlphp:namespace', 'ssp', 'test2', 'value2');
+ $attr3 = new Attribute('urn:x-simplesamlphp:namespace', 'ssp', 'test3', 'value3');
+ $attr4 = new Attribute('urn:x-simplesamlphp:namespace', 'ssp', 'test4', 'value4');
+
+ $referenceParameters = new ReferenceParameters([new Chunk(self::$referenceParametersContent)], [$attr4]);
+ $metadata = new Metadata([new Chunk(self::$metadataContent)], [$attr3]);
+ $chunk = new Chunk(self::$customContent);
+
+ $issuer = new Issuer(
+ new Address('https://login.microsoftonline.com/login.srf', [$attr2]),
+ [$referenceParameters],
+ [$metadata],
+ [$chunk],
+ [$attr1],
+ );
+
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($issuer)
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/KerberosTokenTest.php b/tests/WSSecurity/XML/sp/KerberosTokenTest.php
new file mode 100644
index 00000000..e3cceeca
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/KerberosTokenTest.php
@@ -0,0 +1,85 @@
+assertEquals(
+ "",
+ strval($kerberosToken),
+ );
+ $this->assertTrue($kerberosToken->isEmptyElement());
+ }
+
+
+ /**
+ * Test that creating a KerberosToken from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $kerberosToken = new KerberosToken(IncludeToken::Always, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($kerberosToken),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/KeyValueTokenTest.php b/tests/WSSecurity/XML/sp/KeyValueTokenTest.php
new file mode 100644
index 00000000..25ae2a67
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/KeyValueTokenTest.php
@@ -0,0 +1,85 @@
+assertEquals(
+ "",
+ strval($keyValueToken),
+ );
+ $this->assertTrue($keyValueToken->isEmptyElement());
+ }
+
+
+ /**
+ * Test that creating a KeyValueToken from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $keyValueToken = new KeyValueToken(IncludeToken::Always, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($keyValueToken),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/LaxTest.php b/tests/WSSecurity/XML/sp/LaxTest.php
new file mode 100644
index 00000000..4dab9948
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/LaxTest.php
@@ -0,0 +1,44 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/MustNotSendAmendTest.php b/tests/WSSecurity/XML/sp/MustNotSendAmendTest.php
new file mode 100644
index 00000000..31555be0
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/MustNotSendAmendTest.php
@@ -0,0 +1,44 @@
+assertEquals(
+ static::$xmlRepresentation->saveXML(static::$xmlRepresentation->documentElement),
+ strval($np),
+ );
+ }
+
+
+ /**
+ * Test that creating a NestedPolicyType from scratch without attributes works.
+ */
+ public function testMarshallingWithoutNSAttr(): void
+ {
+ $xml = <<
+ Some
+
+XML;
+ $localName = static::$testedClass::getLocalName();
+ $xml = sprintf($xml, $localName, C::NS_SEC_POLICY, $localName);
+ $xmlRepresentation = DOMDocumentFactory::fromString($xml);
+
+ $np = new static::$testedClass([static::$chunk]);
+
+ $this->assertEquals(
+ $xmlRepresentation->saveXML($xmlRepresentation->documentElement),
+ strval($np),
+ );
+ }
+
+
+ /**
+ * Test that creating a NestedPolicyType from scratch without children works.
+ */
+ public function testMarshallingWithoutChildren(): void
+ {
+ $xml = '';
+ $localName = static::$testedClass::getLocalName();
+ $xml = sprintf($xml, $localName, C::NS_SEC_POLICY, C::NAMESPACE);
+ $xmlRepresentation = DOMDocumentFactory::fromString($xml);
+
+ $qns = new static::$testedClass([], [static::$attr]);
+
+ $this->assertEquals(
+ $xmlRepresentation->saveXML($xmlRepresentation->documentElement),
+ strval($qns),
+ );
+ }
+
+
+ /**
+ * Adding an empty NestedPolicyType element should yield an empty element.
+ */
+ public function testMarshallingEmptyElement(): void
+ {
+ $np = new static::$testedClass();
+ $this->assertEquals(
+ sprintf("", static::$testedClass::getLocalName(), C::NS_SEC_POLICY),
+ strval($np),
+ );
+ $this->assertTrue($np->isEmptyElement());
+ }
+
+
+ // test unmarshalling
+
+
+ /**
+ * Test that creating a NestedPolicyType from XML without attributes succeeds.
+ */
+ public function testUnmarshallingWithoutNSAttr(): void
+ {
+ $xml = <<
+ Some
+
+XML;
+ $localName = static::$testedClass::getLocalName();
+ $xml = sprintf($xml, $localName, C::NS_SEC_POLICY, $localName);
+ $xmlRepresentation = DOMDocumentFactory::fromString($xml);
+
+ $np = static::$testedClass::fromXML($xmlRepresentation->documentElement);
+
+ $this->assertEquals(
+ $xmlRepresentation->saveXML($xmlRepresentation->documentElement),
+ strval($np),
+ );
+ }
+
+
+ /**
+ * Test that creating a NestedPolicyType from XML without children succeeds.
+ */
+ public function testUnmarshallingWithoutChildren(): void
+ {
+ $xml = '';
+ $localName = static::$testedClass::getLocalName();
+ $xml = sprintf($xml, $localName, C::NS_SEC_POLICY);
+ $xmlRepresentation = DOMDocumentFactory::fromString($xml);
+
+ $np = static::$testedClass::fromXML($xmlRepresentation->documentElement);
+
+ $this->assertEquals(
+ $xmlRepresentation->saveXML($xmlRepresentation->documentElement),
+ strval($np),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/NoPasswordTest.php b/tests/WSSecurity/XML/sp/NoPasswordTest.php
new file mode 100644
index 00000000..2d4b1003
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/NoPasswordTest.php
@@ -0,0 +1,44 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/QNameAssertionTypeTestTrait.php b/tests/WSSecurity/XML/sp/QNameAssertionTypeTestTrait.php
new file mode 100644
index 00000000..08255408
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/QNameAssertionTypeTestTrait.php
@@ -0,0 +1,75 @@
+assertEquals(
+ static::$xmlRepresentation->saveXML(static::$xmlRepresentation->documentElement),
+ strval($qns),
+ );
+ }
+
+
+ /**
+ * Test that creating a QNameAssertionType from scratch without attributes works.
+ */
+ public function testMarshallingWithoutNSAttr(): void
+ {
+ $xmlRepresentation = clone static::$xmlRepresentation;
+ $xmlRepresentation->documentElement->removeAttributeNS(C::NAMESPACE, 'attr1');
+ $xmlRepresentation->documentElement->removeAttributeNS(C::NAMESPACE, 'ssp');
+
+ $qns = new static::$testedClass();
+
+ $this->assertEquals(
+ $xmlRepresentation->saveXML($xmlRepresentation->documentElement),
+ strval($qns),
+ );
+ }
+
+
+ // test unmarshalling
+
+
+ /**
+ * Test that creating a QNameAssertionType from XML without attributes succeeds.
+ */
+ public function testUnmarshallingWithoutNSAttr(): void
+ {
+ $xmlRepresentation = clone static::$xmlRepresentation;
+ $xmlRepresentation->documentElement->removeAttributeNS(C::NAMESPACE, 'attr1');
+ $xmlRepresentation->documentElement->removeAttributeNS(C::NAMESPACE, 'ssp');
+
+ $qna = static::$testedClass::fromXML($xmlRepresentation->documentElement);
+
+ $this->assertEquals(
+ $xmlRepresentation->saveXML($xmlRepresentation->documentElement),
+ strval($qna),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/RecipientEncryptionTokenTest.php b/tests/WSSecurity/XML/sp/RecipientEncryptionTokenTest.php
new file mode 100644
index 00000000..b8093256
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/RecipientEncryptionTokenTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/RecipientSignatureTokenTest.php b/tests/WSSecurity/XML/sp/RecipientSignatureTokenTest.php
new file mode 100644
index 00000000..37c6c322
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/RecipientSignatureTokenTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/RecipientTokenTest.php b/tests/WSSecurity/XML/sp/RecipientTokenTest.php
new file mode 100644
index 00000000..3a4aedbc
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/RecipientTokenTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/RelTokenTest.php b/tests/WSSecurity/XML/sp/RelTokenTest.php
new file mode 100644
index 00000000..9cd1ec8b
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/RelTokenTest.php
@@ -0,0 +1,85 @@
+assertEquals(
+ "",
+ strval($relToken),
+ );
+ $this->assertTrue($relToken->isEmptyElement());
+ }
+
+
+ /**
+ * Test that creating a RelToken from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $relToken = new RelToken(IncludeToken::Always, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($relToken),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/RequestSecurityTokenTemplateTest.php b/tests/WSSecurity/XML/sp/RequestSecurityTokenTemplateTest.php
new file mode 100644
index 00000000..93dae9e3
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/RequestSecurityTokenTemplateTest.php
@@ -0,0 +1,83 @@
+some'
+ )->documentElement);
+
+ $RequestSecurityTokenTemplateElements = new RequestSecurityTokenTemplate(
+ 'urn:x-simplesamlphp:version',
+ [$chunk],
+ [$attr],
+ );
+
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($RequestSecurityTokenTemplateElements),
+ );
+ }
+
+
+ /**
+ * Adding an empty RequestSecurityTokenTemplate element should yield an empty element.
+ */
+ public function testMarshallingEmptyElement(): void
+ {
+ $spns = C::NS_SEC_POLICY;
+ $RequestSecurityTokenTemplate = new RequestSecurityTokenTemplate();
+ $this->assertEquals(
+ "",
+ strval($RequestSecurityTokenTemplate),
+ );
+ $this->assertTrue($RequestSecurityTokenTemplate->isEmptyElement());
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/RequireAppliesToTest.php b/tests/WSSecurity/XML/sp/RequireAppliesToTest.php
new file mode 100644
index 00000000..5668a9be
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/RequireAppliesToTest.php
@@ -0,0 +1,44 @@
+35.00]/title');
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $requiredElements = new RequiredElements([$xpath], 'urn:x-simplesamlphp:version', [$chunk], [$attr]);
+ $requiredElementsElement = $requiredElements->toXML();
+
+ // Test for an XPath
+ $xpCache = XMLXPath::getXPath($requiredElementsElement);
+ $requiredElementsElements = XMLXPath::xpQuery($requiredElementsElement, './sp:XPath', $xpCache);
+ $this->assertCount(1, $requiredElementsElements);
+
+ // Test ordering of RequiredElements contents
+ /** @psalm-var \DOMElement[] $requiredElementsElements */
+ $requiredElementsElements = XMLXPath::xpQuery(
+ $requiredElementsElement,
+ './sp:XPath/following-sibling::*',
+ $xpCache,
+ );
+
+ $this->assertCount(1, $requiredElementsElements);
+ $this->assertEquals('ssp:Chunk', $requiredElementsElements[0]->tagName);
+ }
+
+
+ // test marshalling
+
+
+ /**
+ * Test that creating a RequiredElements from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $xpath = new XPath('/bookstore/book[price>35.00]/title');
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $requiredElements = new RequiredElements([$xpath], 'urn:x-simplesamlphp:version', [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($requiredElements),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/RequiredPartsTest.php b/tests/WSSecurity/XML/sp/RequiredPartsTest.php
new file mode 100644
index 00000000..301bfc09
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/RequiredPartsTest.php
@@ -0,0 +1,111 @@
+assertEquals(
+ "",
+ strval($requiredParts),
+ );
+ $this->assertTrue($requiredParts->isEmptyElement());
+ }
+
+
+ /**
+ */
+ public function testMarshallingElementOrdering(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $header = new Header('urn:x-simplesamlphp:namespace', 'ssp:name', [$attr]);
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $RequiredParts = new RequiredParts([$header], [$chunk], [$attr]);
+ $RequiredPartsElement = $RequiredParts->toXML();
+
+ // Test for a Header
+ $xpCache = XPath::getXPath($RequiredPartsElement);
+ $RequiredPartsElements = XPath::xpQuery($RequiredPartsElement, './sp:Header', $xpCache);
+ $this->assertCount(1, $RequiredPartsElements);
+
+ // Test ordering of RequiredParts contents
+ /** @psalm-var \DOMElement[] $RequiredPartsElements */
+ $RequiredPartsElements = XPath::xpQuery($RequiredPartsElement, './sp:Header/following-sibling::*', $xpCache);
+ $this->assertCount(1, $RequiredPartsElements);
+ $this->assertEquals('ssp:Chunk', $RequiredPartsElements[0]->tagName);
+ }
+
+
+ // test marshalling
+
+
+ /**
+ * Test that creating a RequiredParts from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $header = new Header('urn:x-simplesamlphp:namespace', 'ssp:name', [$attr]);
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $RequiredParts = new RequiredParts([$header], [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($RequiredParts),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/RsaKeyValueTest.php b/tests/WSSecurity/XML/sp/RsaKeyValueTest.php
new file mode 100644
index 00000000..30726346
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/RsaKeyValueTest.php
@@ -0,0 +1,44 @@
+assertEquals(
+ "",
+ strval($samlToken),
+ );
+ $this->assertTrue($samlToken->isEmptyElement());
+ }
+
+
+ /**
+ * Test that creating a SamlToken from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $samlToken = new SamlToken(IncludeToken::Always, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($samlToken),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/SecureConversationTokenTest.php b/tests/WSSecurity/XML/sp/SecureConversationTokenTest.php
new file mode 100644
index 00000000..9aea22f8
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/SecureConversationTokenTest.php
@@ -0,0 +1,103 @@
+some'
+ )->documentElement);
+
+ $secureConversationToken = new SecureConversationToken($issuer, IncludeToken::Always, [$chunk], [$attr]);
+ $secureConversationTokenElement = $secureConversationToken->toXML();
+
+ // Test for a IssuerName
+ $xpCache = XPath::getXPath($secureConversationTokenElement);
+ $secureConversationTokenElements = XPath::xpQuery($secureConversationTokenElement, './sp:IssuerName', $xpCache);
+ $this->assertCount(1, $secureConversationTokenElements);
+
+ // Test ordering of SecureConversationToken contents
+ /** @psalm-var \DOMElement[] $secureConversationTokenElements */
+ $secureConversationTokenElements = XPath::xpQuery(
+ $secureConversationTokenElement,
+ './sp:IssuerName/following-sibling::*',
+ $xpCache,
+ );
+ $this->assertCount(1, $secureConversationTokenElements);
+ $this->assertEquals('ssp:Chunk', $secureConversationTokenElements[0]->tagName);
+ }
+
+
+ // test marshalling
+
+
+ /**
+ * Test that creating a SecureConversationToken from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $issuer = new IssuerName('urn:x-simplesamlphp:issuer');
+
+ $secureConversationToken = new SecureConversationToken($issuer, IncludeToken::Always, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($secureConversationToken),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/SecurityContextTokenTest.php b/tests/WSSecurity/XML/sp/SecurityContextTokenTest.php
new file mode 100644
index 00000000..e15fbcd3
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/SecurityContextTokenTest.php
@@ -0,0 +1,85 @@
+assertEquals(
+ "",
+ strval($securityContextToken),
+ );
+ $this->assertTrue($securityContextToken->isEmptyElement());
+ }
+
+
+ /**
+ * Test that creating a SecurityContextToken from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $securityContextToken = new SecurityContextToken(IncludeToken::Always, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($securityContextToken),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/SignatureTokenTest.php b/tests/WSSecurity/XML/sp/SignatureTokenTest.php
new file mode 100644
index 00000000..b4a05393
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/SignatureTokenTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/SignedElementsTest.php b/tests/WSSecurity/XML/sp/SignedElementsTest.php
new file mode 100644
index 00000000..e25af2c6
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/SignedElementsTest.php
@@ -0,0 +1,101 @@
+35.00]/title');
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $SignedElements = new SignedElements([$xpath], 'urn:x-simplesamlphp:version', [$chunk], [$attr]);
+ $SignedElementsElement = $SignedElements->toXML();
+
+ // Test for an XPath
+ $xpCache = XMLXPath::getXPath($SignedElementsElement);
+ $SignedElementsElements = XMLXPath::xpQuery($SignedElementsElement, './sp:XPath', $xpCache);
+ $this->assertCount(1, $SignedElementsElements);
+
+ // Test ordering of SignedElements contents
+ /** @psalm-var \DOMElement[] $SignedElementsElements */
+ $SignedElementsElements = XMLXPath::xpQuery(
+ $SignedElementsElement,
+ './sp:XPath/following-sibling::*',
+ $xpCache,
+ );
+
+ $this->assertCount(1, $SignedElementsElements);
+ $this->assertEquals('ssp:Chunk', $SignedElementsElements[0]->tagName);
+ }
+
+
+ // test marshalling
+
+
+ /**
+ * Test that creating a SignedElements from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $xpath = new XPath('/bookstore/book[price>35.00]/title');
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $SignedElements = new SignedElements([$xpath], 'urn:x-simplesamlphp:version', [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($SignedElements),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/SignedEncryptedSupportingTokensTest.php b/tests/WSSecurity/XML/sp/SignedEncryptedSupportingTokensTest.php
new file mode 100644
index 00000000..22bdaae7
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/SignedEncryptedSupportingTokensTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/SignedEndorsingEncryptedSupportingTokensTest.php b/tests/WSSecurity/XML/sp/SignedEndorsingEncryptedSupportingTokensTest.php
new file mode 100644
index 00000000..a6786664
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/SignedEndorsingEncryptedSupportingTokensTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/SignedEndorsingSupportingTokensTest.php b/tests/WSSecurity/XML/sp/SignedEndorsingSupportingTokensTest.php
new file mode 100644
index 00000000..d1f7ecb7
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/SignedEndorsingSupportingTokensTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/SignedPartsTest.php b/tests/WSSecurity/XML/sp/SignedPartsTest.php
new file mode 100644
index 00000000..3bc9158d
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/SignedPartsTest.php
@@ -0,0 +1,119 @@
+assertEquals(
+ "",
+ strval($signedParts),
+ );
+ $this->assertTrue($signedParts->isEmptyElement());
+ }
+
+
+ /**
+ * Test that creating a SignedParts from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $body = new Body();
+ $header = new Header('urn:x-simplesamlphp:namespace', 'ssp:name', [$attr]);
+ $attachments = new Attachments();
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $signedParts = new SignedParts($body, [$header], $attachments, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($signedParts),
+ );
+ }
+
+
+ /**
+ */
+ public function testMarshallingElementOrdering(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $body = new Body();
+ $header = new Header('urn:x-simplesamlphp:namespace', 'ssp:name', [$attr]);
+ $attachments = new Attachments();
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $SignedParts = new SignedParts($body, [$header], $attachments, [$chunk], [$attr]);
+ $SignedPartsElement = $SignedParts->toXML();
+
+ // Test for a Body
+ $xpCache = XPath::getXPath($SignedPartsElement);
+ $SignedPartsElements = XPath::xpQuery($SignedPartsElement, './sp:Body', $xpCache);
+ $this->assertCount(1, $SignedPartsElements);
+
+ // Test ordering of SignedParts contents
+ /** @psalm-var \DOMElement[] $SignedPartsElements */
+ $SignedPartsElements = XPath::xpQuery($SignedPartsElement, './sp:Body/following-sibling::*', $xpCache);
+ $this->assertCount(3, $SignedPartsElements);
+ $this->assertEquals('sp:Header', $SignedPartsElements[0]->tagName);
+ $this->assertEquals('sp:Attachments', $SignedPartsElements[1]->tagName);
+ $this->assertEquals('ssp:Chunk', $SignedPartsElements[2]->tagName);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/SignedSupportingTokensTest.php b/tests/WSSecurity/XML/sp/SignedSupportingTokensTest.php
new file mode 100644
index 00000000..51190dfc
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/SignedSupportingTokensTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/SpnegoContextTokenTest.php b/tests/WSSecurity/XML/sp/SpnegoContextTokenTest.php
new file mode 100644
index 00000000..c7b5864c
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/SpnegoContextTokenTest.php
@@ -0,0 +1,103 @@
+some'
+ )->documentElement);
+
+ $spnegoContextToken = new SpnegoContextToken($issuer, IncludeToken::Always, [$chunk], [$attr]);
+ $spnegoContextTokenElement = $spnegoContextToken->toXML();
+
+ // Test for a IssuerName
+ $xpCache = XPath::getXPath($spnegoContextTokenElement);
+ $spnegoContextTokenElements = XPath::xpQuery($spnegoContextTokenElement, './sp:IssuerName', $xpCache);
+ $this->assertCount(1, $spnegoContextTokenElements);
+
+ // Test ordering of SpnegoContextToken contents
+ /** @psalm-var \DOMElement[] $spnegoContextTokenElements */
+ $spnegoContextTokenElements = XPath::xpQuery(
+ $spnegoContextTokenElement,
+ './sp:IssuerName/following-sibling::*',
+ $xpCache,
+ );
+ $this->assertCount(1, $spnegoContextTokenElements);
+ $this->assertEquals('ssp:Chunk', $spnegoContextTokenElements[0]->tagName);
+ }
+
+
+ // test marshalling
+
+
+ /**
+ * Test that creating a SpnegoContextToken from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $issuer = new IssuerName('urn:x-simplesamlphp:issuer');
+
+ $spnegoContextToken = new SpnegoContextToken($issuer, IncludeToken::Always, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($spnegoContextToken),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/StrictTest.php b/tests/WSSecurity/XML/sp/StrictTest.php
new file mode 100644
index 00000000..60a6ac72
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/StrictTest.php
@@ -0,0 +1,44 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/SymmetricBindingTest.php b/tests/WSSecurity/XML/sp/SymmetricBindingTest.php
new file mode 100644
index 00000000..9a6f931f
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/SymmetricBindingTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/TransportBindingTest.php b/tests/WSSecurity/XML/sp/TransportBindingTest.php
new file mode 100644
index 00000000..06d19406
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/TransportBindingTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/TransportTokenTest.php b/tests/WSSecurity/XML/sp/TransportTokenTest.php
new file mode 100644
index 00000000..704783c9
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/TransportTokenTest.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/TripleDesRsa15Test.php b/tests/WSSecurity/XML/sp/TripleDesRsa15Test.php
new file mode 100644
index 00000000..7853427b
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/TripleDesRsa15Test.php
@@ -0,0 +1,44 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/UsernameTokenTest.php b/tests/WSSecurity/XML/sp/UsernameTokenTest.php
new file mode 100644
index 00000000..9606b074
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/UsernameTokenTest.php
@@ -0,0 +1,85 @@
+assertEquals(
+ "",
+ strval($usernameToken),
+ );
+ $this->assertTrue($usernameToken->isEmptyElement());
+ }
+
+
+ /**
+ * Test that creating a UsernameToken from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $usernameToken = new UsernameToken(IncludeToken::Always, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($usernameToken),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/Wss10Test.php b/tests/WSSecurity/XML/sp/Wss10Test.php
new file mode 100644
index 00000000..d1aab257
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/Wss10Test.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/Wss11Test.php b/tests/WSSecurity/XML/sp/Wss11Test.php
new file mode 100644
index 00000000..80e39c79
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/Wss11Test.php
@@ -0,0 +1,59 @@
+Some'
+ )->documentElement);
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/WssGssKerberosV5ApReqToken11Test.php b/tests/WSSecurity/XML/sp/WssGssKerberosV5ApReqToken11Test.php
new file mode 100644
index 00000000..8f25c199
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/WssGssKerberosV5ApReqToken11Test.php
@@ -0,0 +1,44 @@
+assertEquals(
+ "",
+ strval($x509Token),
+ );
+ $this->assertTrue($x509Token->isEmptyElement());
+ }
+
+
+ /**
+ * Test that creating a X509Token from scratch works.
+ */
+ public function testMarshalling(): void
+ {
+ $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1');
+ $chunk = new Chunk(DOMDocumentFactory::fromString(
+ 'some'
+ )->documentElement);
+
+ $x509Token = new X509Token(IncludeToken::Always, [$chunk], [$attr]);
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($x509Token),
+ );
+ }
+}
diff --git a/tests/WSSecurity/XML/sp/XPath10Test.php b/tests/WSSecurity/XML/sp/XPath10Test.php
new file mode 100644
index 00000000..e708a9a0
--- /dev/null
+++ b/tests/WSSecurity/XML/sp/XPath10Test.php
@@ -0,0 +1,44 @@
+35.00]/title');
+
+ $this->assertEquals(
+ self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
+ strval($xpath),
+ );
+ }
+}
diff --git a/tests/resources/xml/sp_AbsXPath.xml b/tests/resources/xml/sp_AbsXPath.xml
new file mode 100644
index 00000000..0634dafd
--- /dev/null
+++ b/tests/resources/xml/sp_AbsXPath.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_AlgorithmSuite.xml b/tests/resources/xml/sp_AlgorithmSuite.xml
new file mode 100644
index 00000000..a62b4d81
--- /dev/null
+++ b/tests/resources/xml/sp_AlgorithmSuite.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_AsymmetricBinding.xml b/tests/resources/xml/sp_AsymmetricBinding.xml
new file mode 100644
index 00000000..2a78c193
--- /dev/null
+++ b/tests/resources/xml/sp_AsymmetricBinding.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_Attachments.xml b/tests/resources/xml/sp_Attachments.xml
new file mode 100644
index 00000000..e0295d5a
--- /dev/null
+++ b/tests/resources/xml/sp_Attachments.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic128.xml b/tests/resources/xml/sp_Basic128.xml
new file mode 100644
index 00000000..a516099e
--- /dev/null
+++ b/tests/resources/xml/sp_Basic128.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic128Rsa15.xml b/tests/resources/xml/sp_Basic128Rsa15.xml
new file mode 100644
index 00000000..b6e72abf
--- /dev/null
+++ b/tests/resources/xml/sp_Basic128Rsa15.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic128Sha256.xml b/tests/resources/xml/sp_Basic128Sha256.xml
new file mode 100644
index 00000000..f64641c1
--- /dev/null
+++ b/tests/resources/xml/sp_Basic128Sha256.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic128Sha256Rsa15.xml b/tests/resources/xml/sp_Basic128Sha256Rsa15.xml
new file mode 100644
index 00000000..2e695ccd
--- /dev/null
+++ b/tests/resources/xml/sp_Basic128Sha256Rsa15.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic192.xml b/tests/resources/xml/sp_Basic192.xml
new file mode 100644
index 00000000..0ec3907d
--- /dev/null
+++ b/tests/resources/xml/sp_Basic192.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic192Rsa15.xml b/tests/resources/xml/sp_Basic192Rsa15.xml
new file mode 100644
index 00000000..cbd00ca8
--- /dev/null
+++ b/tests/resources/xml/sp_Basic192Rsa15.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic192Sha256.xml b/tests/resources/xml/sp_Basic192Sha256.xml
new file mode 100644
index 00000000..b4fd83fc
--- /dev/null
+++ b/tests/resources/xml/sp_Basic192Sha256.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic192Sha256Rsa15.xml b/tests/resources/xml/sp_Basic192Sha256Rsa15.xml
new file mode 100644
index 00000000..2bb8128d
--- /dev/null
+++ b/tests/resources/xml/sp_Basic192Sha256Rsa15.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic256.xml b/tests/resources/xml/sp_Basic256.xml
new file mode 100644
index 00000000..6935966b
--- /dev/null
+++ b/tests/resources/xml/sp_Basic256.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic256Rsa15.xml b/tests/resources/xml/sp_Basic256Rsa15.xml
new file mode 100644
index 00000000..224dc72b
--- /dev/null
+++ b/tests/resources/xml/sp_Basic256Rsa15.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic256Sha256.xml b/tests/resources/xml/sp_Basic256Sha256.xml
new file mode 100644
index 00000000..98b17685
--- /dev/null
+++ b/tests/resources/xml/sp_Basic256Sha256.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Basic256Sha256Rsa15.xml b/tests/resources/xml/sp_Basic256Sha256Rsa15.xml
new file mode 100644
index 00000000..bc0eb105
--- /dev/null
+++ b/tests/resources/xml/sp_Basic256Sha256Rsa15.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Body.xml b/tests/resources/xml/sp_Body.xml
new file mode 100644
index 00000000..f4468dab
--- /dev/null
+++ b/tests/resources/xml/sp_Body.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_BootstrapPolicy.xml b/tests/resources/xml/sp_BootstrapPolicy.xml
new file mode 100644
index 00000000..aaff6142
--- /dev/null
+++ b/tests/resources/xml/sp_BootstrapPolicy.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_ContentEncryptedElements.xml b/tests/resources/xml/sp_ContentEncryptedElements.xml
new file mode 100644
index 00000000..80556510
--- /dev/null
+++ b/tests/resources/xml/sp_ContentEncryptedElements.xml
@@ -0,0 +1,4 @@
+
+ /bookstore/book[price>35.00]/title
+ some
+
diff --git a/tests/resources/xml/sp_EncryptBeforeSigning.xml b/tests/resources/xml/sp_EncryptBeforeSigning.xml
new file mode 100644
index 00000000..d60d91b2
--- /dev/null
+++ b/tests/resources/xml/sp_EncryptBeforeSigning.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_EncryptSignature.xml b/tests/resources/xml/sp_EncryptSignature.xml
new file mode 100644
index 00000000..47adcfba
--- /dev/null
+++ b/tests/resources/xml/sp_EncryptSignature.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_EncryptedElements.xml b/tests/resources/xml/sp_EncryptedElements.xml
new file mode 100644
index 00000000..e05990c6
--- /dev/null
+++ b/tests/resources/xml/sp_EncryptedElements.xml
@@ -0,0 +1,4 @@
+
+ /bookstore/book[price>35.00]/title
+ some
+
diff --git a/tests/resources/xml/sp_EncryptedParts.xml b/tests/resources/xml/sp_EncryptedParts.xml
new file mode 100644
index 00000000..c9ce63b1
--- /dev/null
+++ b/tests/resources/xml/sp_EncryptedParts.xml
@@ -0,0 +1,6 @@
+
+
+
+
+ some
+
diff --git a/tests/resources/xml/sp_EncryptedSupportingTokens.xml b/tests/resources/xml/sp_EncryptedSupportingTokens.xml
new file mode 100644
index 00000000..f9331742
--- /dev/null
+++ b/tests/resources/xml/sp_EncryptedSupportingTokens.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_EncryptionToken.xml b/tests/resources/xml/sp_EncryptionToken.xml
new file mode 100644
index 00000000..abcfea21
--- /dev/null
+++ b/tests/resources/xml/sp_EncryptionToken.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_EndorsingEncryptedSupportingTokens.xml b/tests/resources/xml/sp_EndorsingEncryptedSupportingTokens.xml
new file mode 100644
index 00000000..dcd120fe
--- /dev/null
+++ b/tests/resources/xml/sp_EndorsingEncryptedSupportingTokens.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_EndorsingSupportingTokens.xml b/tests/resources/xml/sp_EndorsingSupportingTokens.xml
new file mode 100644
index 00000000..bd60f025
--- /dev/null
+++ b/tests/resources/xml/sp_EndorsingSupportingTokens.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_HashPassword.xml b/tests/resources/xml/sp_HashPassword.xml
new file mode 100644
index 00000000..21955d33
--- /dev/null
+++ b/tests/resources/xml/sp_HashPassword.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Header.xml b/tests/resources/xml/sp_Header.xml
new file mode 100644
index 00000000..56ef7fc3
--- /dev/null
+++ b/tests/resources/xml/sp_Header.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_HttpBasicAuthentication.xml b/tests/resources/xml/sp_HttpBasicAuthentication.xml
new file mode 100644
index 00000000..a2f23e02
--- /dev/null
+++ b/tests/resources/xml/sp_HttpBasicAuthentication.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_HttpDigestAuthentication.xml b/tests/resources/xml/sp_HttpDigestAuthentication.xml
new file mode 100644
index 00000000..fe1c23d8
--- /dev/null
+++ b/tests/resources/xml/sp_HttpDigestAuthentication.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_HttpsToken.xml b/tests/resources/xml/sp_HttpsToken.xml
new file mode 100644
index 00000000..e8a2406e
--- /dev/null
+++ b/tests/resources/xml/sp_HttpsToken.xml
@@ -0,0 +1,3 @@
+
+ some
+
diff --git a/tests/resources/xml/sp_IncludeTimestamp.xml b/tests/resources/xml/sp_IncludeTimestamp.xml
new file mode 100644
index 00000000..c41a226e
--- /dev/null
+++ b/tests/resources/xml/sp_IncludeTimestamp.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_InclusiveC14N.xml b/tests/resources/xml/sp_InclusiveC14N.xml
new file mode 100644
index 00000000..6f68710d
--- /dev/null
+++ b/tests/resources/xml/sp_InclusiveC14N.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_InitiatorEncryptionToken.xml b/tests/resources/xml/sp_InitiatorEncryptionToken.xml
new file mode 100644
index 00000000..89f097a9
--- /dev/null
+++ b/tests/resources/xml/sp_InitiatorEncryptionToken.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_InitiatorSignatureToken.xml b/tests/resources/xml/sp_InitiatorSignatureToken.xml
new file mode 100644
index 00000000..3c8c46d2
--- /dev/null
+++ b/tests/resources/xml/sp_InitiatorSignatureToken.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_InitiatorToken.xml b/tests/resources/xml/sp_InitiatorToken.xml
new file mode 100644
index 00000000..49f557a8
--- /dev/null
+++ b/tests/resources/xml/sp_InitiatorToken.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_IssuedToken.xml b/tests/resources/xml/sp_IssuedToken.xml
new file mode 100644
index 00000000..5d16f4f1
--- /dev/null
+++ b/tests/resources/xml/sp_IssuedToken.xml
@@ -0,0 +1,7 @@
+
+ urn:x-simplesamlphp:issuer
+
+ some
+
+ some
+
diff --git a/tests/resources/xml/sp_Issuer.xml b/tests/resources/xml/sp_Issuer.xml
new file mode 100644
index 00000000..4fd8d0b9
--- /dev/null
+++ b/tests/resources/xml/sp_Issuer.xml
@@ -0,0 +1,14 @@
+
+ https://login.microsoftonline.com/login.srf
+
+
+ Pears
+
+
+
+
+ Apples
+
+
+ SomeChunk
+
diff --git a/tests/resources/xml/sp_IssuerName.xml b/tests/resources/xml/sp_IssuerName.xml
new file mode 100644
index 00000000..309293cf
--- /dev/null
+++ b/tests/resources/xml/sp_IssuerName.xml
@@ -0,0 +1 @@
+urn:x-simplesamlphp:namespace
diff --git a/tests/resources/xml/sp_KerberosToken.xml b/tests/resources/xml/sp_KerberosToken.xml
new file mode 100644
index 00000000..2cc83de2
--- /dev/null
+++ b/tests/resources/xml/sp_KerberosToken.xml
@@ -0,0 +1,3 @@
+
+ some
+
diff --git a/tests/resources/xml/sp_KeyValueToken.xml b/tests/resources/xml/sp_KeyValueToken.xml
new file mode 100644
index 00000000..9dfa1952
--- /dev/null
+++ b/tests/resources/xml/sp_KeyValueToken.xml
@@ -0,0 +1,3 @@
+
+ some
+
diff --git a/tests/resources/xml/sp_Lax.xml b/tests/resources/xml/sp_Lax.xml
new file mode 100644
index 00000000..1451d6e3
--- /dev/null
+++ b/tests/resources/xml/sp_Lax.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_LaxTsFirst.xml b/tests/resources/xml/sp_LaxTsFirst.xml
new file mode 100644
index 00000000..5ac1257f
--- /dev/null
+++ b/tests/resources/xml/sp_LaxTsFirst.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_LaxTsLast.xml b/tests/resources/xml/sp_LaxTsLast.xml
new file mode 100644
index 00000000..ba086a7a
--- /dev/null
+++ b/tests/resources/xml/sp_LaxTsLast.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Layout.xml b/tests/resources/xml/sp_Layout.xml
new file mode 100644
index 00000000..709b0ee1
--- /dev/null
+++ b/tests/resources/xml/sp_Layout.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_MustNotSendAmend.xml b/tests/resources/xml/sp_MustNotSendAmend.xml
new file mode 100644
index 00000000..8f6ed888
--- /dev/null
+++ b/tests/resources/xml/sp_MustNotSendAmend.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_MustNotSendCancel.xml b/tests/resources/xml/sp_MustNotSendCancel.xml
new file mode 100644
index 00000000..56ef447b
--- /dev/null
+++ b/tests/resources/xml/sp_MustNotSendCancel.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_MustNotSendRenew.xml b/tests/resources/xml/sp_MustNotSendRenew.xml
new file mode 100644
index 00000000..0372e02d
--- /dev/null
+++ b/tests/resources/xml/sp_MustNotSendRenew.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_MustSupportClientChallenge.xml b/tests/resources/xml/sp_MustSupportClientChallenge.xml
new file mode 100644
index 00000000..d001e37b
--- /dev/null
+++ b/tests/resources/xml/sp_MustSupportClientChallenge.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_MustSupportIssuedTokens.xml b/tests/resources/xml/sp_MustSupportIssuedTokens.xml
new file mode 100644
index 00000000..620a74dd
--- /dev/null
+++ b/tests/resources/xml/sp_MustSupportIssuedTokens.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_MustSupportRefEmbeddedToken.xml b/tests/resources/xml/sp_MustSupportRefEmbeddedToken.xml
new file mode 100644
index 00000000..3bf5cd24
--- /dev/null
+++ b/tests/resources/xml/sp_MustSupportRefEmbeddedToken.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_MustSupportRefEncryptedKey.xml b/tests/resources/xml/sp_MustSupportRefEncryptedKey.xml
new file mode 100644
index 00000000..f3c3b3c3
--- /dev/null
+++ b/tests/resources/xml/sp_MustSupportRefEncryptedKey.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_MustSupportRefExternalURI.xml b/tests/resources/xml/sp_MustSupportRefExternalURI.xml
new file mode 100644
index 00000000..ef967f97
--- /dev/null
+++ b/tests/resources/xml/sp_MustSupportRefExternalURI.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_MustSupportRefIssuerSerial.xml b/tests/resources/xml/sp_MustSupportRefIssuerSerial.xml
new file mode 100644
index 00000000..c0ca665c
--- /dev/null
+++ b/tests/resources/xml/sp_MustSupportRefIssuerSerial.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_MustSupportRefKeyIdentifier.xml b/tests/resources/xml/sp_MustSupportRefKeyIdentifier.xml
new file mode 100644
index 00000000..a9ef430a
--- /dev/null
+++ b/tests/resources/xml/sp_MustSupportRefKeyIdentifier.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_MustSupportRefThumbprint.xml b/tests/resources/xml/sp_MustSupportRefThumbprint.xml
new file mode 100644
index 00000000..1a3cbe42
--- /dev/null
+++ b/tests/resources/xml/sp_MustSupportRefThumbprint.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_MustSupportServerChallenge.xml b/tests/resources/xml/sp_MustSupportServerChallenge.xml
new file mode 100644
index 00000000..be2824fc
--- /dev/null
+++ b/tests/resources/xml/sp_MustSupportServerChallenge.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_NoPassword.xml b/tests/resources/xml/sp_NoPassword.xml
new file mode 100644
index 00000000..5b82ad29
--- /dev/null
+++ b/tests/resources/xml/sp_NoPassword.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_OnlySignEntireHeadersAndBody.xml b/tests/resources/xml/sp_OnlySignEntireHeadersAndBody.xml
new file mode 100644
index 00000000..492b78ba
--- /dev/null
+++ b/tests/resources/xml/sp_OnlySignEntireHeadersAndBody.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_ProtectTokens.xml b/tests/resources/xml/sp_ProtectTokens.xml
new file mode 100644
index 00000000..a9aa5f05
--- /dev/null
+++ b/tests/resources/xml/sp_ProtectTokens.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_ProtectionToken.xml b/tests/resources/xml/sp_ProtectionToken.xml
new file mode 100644
index 00000000..b379f8e3
--- /dev/null
+++ b/tests/resources/xml/sp_ProtectionToken.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_RecipientEncryptionToken.xml b/tests/resources/xml/sp_RecipientEncryptionToken.xml
new file mode 100644
index 00000000..352530c9
--- /dev/null
+++ b/tests/resources/xml/sp_RecipientEncryptionToken.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_RecipientSignatureToken.xml b/tests/resources/xml/sp_RecipientSignatureToken.xml
new file mode 100644
index 00000000..631850d0
--- /dev/null
+++ b/tests/resources/xml/sp_RecipientSignatureToken.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_RecipientToken.xml b/tests/resources/xml/sp_RecipientToken.xml
new file mode 100644
index 00000000..a2ca10e8
--- /dev/null
+++ b/tests/resources/xml/sp_RecipientToken.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_RelToken.xml b/tests/resources/xml/sp_RelToken.xml
new file mode 100644
index 00000000..f52e9302
--- /dev/null
+++ b/tests/resources/xml/sp_RelToken.xml
@@ -0,0 +1,3 @@
+
+ some
+
diff --git a/tests/resources/xml/sp_RequestSecurityTokenTemplate.xml b/tests/resources/xml/sp_RequestSecurityTokenTemplate.xml
new file mode 100644
index 00000000..cf3dba3d
--- /dev/null
+++ b/tests/resources/xml/sp_RequestSecurityTokenTemplate.xml
@@ -0,0 +1,3 @@
+
+ some
+
diff --git a/tests/resources/xml/sp_RequireAppliesTo.xml b/tests/resources/xml/sp_RequireAppliesTo.xml
new file mode 100644
index 00000000..dd3383b2
--- /dev/null
+++ b/tests/resources/xml/sp_RequireAppliesTo.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireClientCertificate.xml b/tests/resources/xml/sp_RequireClientCertificate.xml
new file mode 100644
index 00000000..dc613fb9
--- /dev/null
+++ b/tests/resources/xml/sp_RequireClientCertificate.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireClientEntropy.xml b/tests/resources/xml/sp_RequireClientEntropy.xml
new file mode 100644
index 00000000..30a36c1a
--- /dev/null
+++ b/tests/resources/xml/sp_RequireClientEntropy.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireDerivedKeys.xml b/tests/resources/xml/sp_RequireDerivedKeys.xml
new file mode 100644
index 00000000..32be2ec1
--- /dev/null
+++ b/tests/resources/xml/sp_RequireDerivedKeys.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireEmbeddedTokenReference.xml b/tests/resources/xml/sp_RequireEmbeddedTokenReference.xml
new file mode 100644
index 00000000..feb5a8e4
--- /dev/null
+++ b/tests/resources/xml/sp_RequireEmbeddedTokenReference.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireExplicitDerivedKeys.xml b/tests/resources/xml/sp_RequireExplicitDerivedKeys.xml
new file mode 100644
index 00000000..27dc75f9
--- /dev/null
+++ b/tests/resources/xml/sp_RequireExplicitDerivedKeys.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireExternalReference.xml b/tests/resources/xml/sp_RequireExternalReference.xml
new file mode 100644
index 00000000..8c4c0428
--- /dev/null
+++ b/tests/resources/xml/sp_RequireExternalReference.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireExternalUriReference.xml b/tests/resources/xml/sp_RequireExternalUriReference.xml
new file mode 100644
index 00000000..60bc469c
--- /dev/null
+++ b/tests/resources/xml/sp_RequireExternalUriReference.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireImpliedDerivedKeys.xml b/tests/resources/xml/sp_RequireImpliedDerivedKeys.xml
new file mode 100644
index 00000000..bab75242
--- /dev/null
+++ b/tests/resources/xml/sp_RequireImpliedDerivedKeys.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireInternalReference.xml b/tests/resources/xml/sp_RequireInternalReference.xml
new file mode 100644
index 00000000..6bf3fbdc
--- /dev/null
+++ b/tests/resources/xml/sp_RequireInternalReference.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireIssuerSerialReference.xml b/tests/resources/xml/sp_RequireIssuerSerialReference.xml
new file mode 100644
index 00000000..59290954
--- /dev/null
+++ b/tests/resources/xml/sp_RequireIssuerSerialReference.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireKeyIdentifierReference.xml b/tests/resources/xml/sp_RequireKeyIdentifierReference.xml
new file mode 100644
index 00000000..a8da36ca
--- /dev/null
+++ b/tests/resources/xml/sp_RequireKeyIdentifierReference.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireRequestSecurityTokenCollection.xml b/tests/resources/xml/sp_RequireRequestSecurityTokenCollection.xml
new file mode 100644
index 00000000..a6f20f5f
--- /dev/null
+++ b/tests/resources/xml/sp_RequireRequestSecurityTokenCollection.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireServerEntropy.xml b/tests/resources/xml/sp_RequireServerEntropy.xml
new file mode 100644
index 00000000..4c7126e0
--- /dev/null
+++ b/tests/resources/xml/sp_RequireServerEntropy.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireSignatureConfirmation.xml b/tests/resources/xml/sp_RequireSignatureConfirmation.xml
new file mode 100644
index 00000000..0f5d7599
--- /dev/null
+++ b/tests/resources/xml/sp_RequireSignatureConfirmation.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequireThumbprintReference.xml b/tests/resources/xml/sp_RequireThumbprintReference.xml
new file mode 100644
index 00000000..29213350
--- /dev/null
+++ b/tests/resources/xml/sp_RequireThumbprintReference.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_RequiredElements.xml b/tests/resources/xml/sp_RequiredElements.xml
new file mode 100644
index 00000000..131defba
--- /dev/null
+++ b/tests/resources/xml/sp_RequiredElements.xml
@@ -0,0 +1,4 @@
+
+ /bookstore/book[price>35.00]/title
+ some
+
diff --git a/tests/resources/xml/sp_RequiredParts.xml b/tests/resources/xml/sp_RequiredParts.xml
new file mode 100644
index 00000000..45ddb1e9
--- /dev/null
+++ b/tests/resources/xml/sp_RequiredParts.xml
@@ -0,0 +1,4 @@
+
+
+ some
+
diff --git a/tests/resources/xml/sp_RsaKeyValue.xml b/tests/resources/xml/sp_RsaKeyValue.xml
new file mode 100644
index 00000000..006d390b
--- /dev/null
+++ b/tests/resources/xml/sp_RsaKeyValue.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_SC13SecurityContextToken.xml b/tests/resources/xml/sp_SC13SecurityContextToken.xml
new file mode 100644
index 00000000..66f4cb86
--- /dev/null
+++ b/tests/resources/xml/sp_SC13SecurityContextToken.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_SOAPNormalization10.xml b/tests/resources/xml/sp_SOAPNormalization10.xml
new file mode 100644
index 00000000..71afddb3
--- /dev/null
+++ b/tests/resources/xml/sp_SOAPNormalization10.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_STRTransform10.xml b/tests/resources/xml/sp_STRTransform10.xml
new file mode 100644
index 00000000..bbd6464d
--- /dev/null
+++ b/tests/resources/xml/sp_STRTransform10.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_SamlToken.xml b/tests/resources/xml/sp_SamlToken.xml
new file mode 100644
index 00000000..5b858c6c
--- /dev/null
+++ b/tests/resources/xml/sp_SamlToken.xml
@@ -0,0 +1,3 @@
+
+ some
+
diff --git a/tests/resources/xml/sp_SecureConversationToken.xml b/tests/resources/xml/sp_SecureConversationToken.xml
new file mode 100644
index 00000000..7e23eef1
--- /dev/null
+++ b/tests/resources/xml/sp_SecureConversationToken.xml
@@ -0,0 +1,4 @@
+
+ urn:x-simplesamlphp:issuer
+ some
+
diff --git a/tests/resources/xml/sp_SecurityContextToken.xml b/tests/resources/xml/sp_SecurityContextToken.xml
new file mode 100644
index 00000000..cefa9b0a
--- /dev/null
+++ b/tests/resources/xml/sp_SecurityContextToken.xml
@@ -0,0 +1,3 @@
+
+ some
+
diff --git a/tests/resources/xml/sp_SignatureToken.xml b/tests/resources/xml/sp_SignatureToken.xml
new file mode 100644
index 00000000..495c80c4
--- /dev/null
+++ b/tests/resources/xml/sp_SignatureToken.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_SignedElements.xml b/tests/resources/xml/sp_SignedElements.xml
new file mode 100644
index 00000000..dc66e01b
--- /dev/null
+++ b/tests/resources/xml/sp_SignedElements.xml
@@ -0,0 +1,4 @@
+
+ /bookstore/book[price>35.00]/title
+ some
+
diff --git a/tests/resources/xml/sp_SignedEncryptedSupportingTokens.xml b/tests/resources/xml/sp_SignedEncryptedSupportingTokens.xml
new file mode 100644
index 00000000..5d74a16e
--- /dev/null
+++ b/tests/resources/xml/sp_SignedEncryptedSupportingTokens.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_SignedEndorsingEncryptedSupportingTokens.xml b/tests/resources/xml/sp_SignedEndorsingEncryptedSupportingTokens.xml
new file mode 100644
index 00000000..dfe94539
--- /dev/null
+++ b/tests/resources/xml/sp_SignedEndorsingEncryptedSupportingTokens.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_SignedEndorsingSupportingTokens.xml b/tests/resources/xml/sp_SignedEndorsingSupportingTokens.xml
new file mode 100644
index 00000000..a3ab305c
--- /dev/null
+++ b/tests/resources/xml/sp_SignedEndorsingSupportingTokens.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_SignedParts.xml b/tests/resources/xml/sp_SignedParts.xml
new file mode 100644
index 00000000..87c91e57
--- /dev/null
+++ b/tests/resources/xml/sp_SignedParts.xml
@@ -0,0 +1,6 @@
+
+
+
+
+ some
+
diff --git a/tests/resources/xml/sp_SignedSupportingTokens.xml b/tests/resources/xml/sp_SignedSupportingTokens.xml
new file mode 100644
index 00000000..d1b4f3bc
--- /dev/null
+++ b/tests/resources/xml/sp_SignedSupportingTokens.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_SpnegoContextToken.xml b/tests/resources/xml/sp_SpnegoContextToken.xml
new file mode 100644
index 00000000..0db1d87a
--- /dev/null
+++ b/tests/resources/xml/sp_SpnegoContextToken.xml
@@ -0,0 +1,4 @@
+
+ urn:x-simplesamlphp:issuer
+ some
+
diff --git a/tests/resources/xml/sp_Strict.xml b/tests/resources/xml/sp_Strict.xml
new file mode 100644
index 00000000..1bf8b550
--- /dev/null
+++ b/tests/resources/xml/sp_Strict.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_SupportingTokens.xml b/tests/resources/xml/sp_SupportingTokens.xml
new file mode 100644
index 00000000..ec006248
--- /dev/null
+++ b/tests/resources/xml/sp_SupportingTokens.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_SymmetricBinding.xml b/tests/resources/xml/sp_SymmetricBinding.xml
new file mode 100644
index 00000000..ad7d4595
--- /dev/null
+++ b/tests/resources/xml/sp_SymmetricBinding.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_TransportBinding.xml b/tests/resources/xml/sp_TransportBinding.xml
new file mode 100644
index 00000000..ba846811
--- /dev/null
+++ b/tests/resources/xml/sp_TransportBinding.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_TransportToken.xml b/tests/resources/xml/sp_TransportToken.xml
new file mode 100644
index 00000000..ff2ec608
--- /dev/null
+++ b/tests/resources/xml/sp_TransportToken.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_TripleDes.xml b/tests/resources/xml/sp_TripleDes.xml
new file mode 100644
index 00000000..c778ddf0
--- /dev/null
+++ b/tests/resources/xml/sp_TripleDes.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_TripleDesRsa15.xml b/tests/resources/xml/sp_TripleDesRsa15.xml
new file mode 100644
index 00000000..e65bb6f9
--- /dev/null
+++ b/tests/resources/xml/sp_TripleDesRsa15.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_TripleDesSha256.xml b/tests/resources/xml/sp_TripleDesSha256.xml
new file mode 100644
index 00000000..5a533112
--- /dev/null
+++ b/tests/resources/xml/sp_TripleDesSha256.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_TripleDesSha256Rsa15.xml b/tests/resources/xml/sp_TripleDesSha256Rsa15.xml
new file mode 100644
index 00000000..a8352942
--- /dev/null
+++ b/tests/resources/xml/sp_TripleDesSha256Rsa15.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_Trust13.xml b/tests/resources/xml/sp_Trust13.xml
new file mode 100644
index 00000000..3ea8732f
--- /dev/null
+++ b/tests/resources/xml/sp_Trust13.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_UsernameToken.xml b/tests/resources/xml/sp_UsernameToken.xml
new file mode 100644
index 00000000..11f5291a
--- /dev/null
+++ b/tests/resources/xml/sp_UsernameToken.xml
@@ -0,0 +1,3 @@
+
+ some
+
diff --git a/tests/resources/xml/sp_Wss10.xml b/tests/resources/xml/sp_Wss10.xml
new file mode 100644
index 00000000..496169a5
--- /dev/null
+++ b/tests/resources/xml/sp_Wss10.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_Wss11.xml b/tests/resources/xml/sp_Wss11.xml
new file mode 100644
index 00000000..faf6d0eb
--- /dev/null
+++ b/tests/resources/xml/sp_Wss11.xml
@@ -0,0 +1,3 @@
+
+ Some
+
diff --git a/tests/resources/xml/sp_WssGssKerberosV5ApReqToken11.xml b/tests/resources/xml/sp_WssGssKerberosV5ApReqToken11.xml
new file mode 100644
index 00000000..d8b38a2f
--- /dev/null
+++ b/tests/resources/xml/sp_WssGssKerberosV5ApReqToken11.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssKerberosV5ApReqToken11.xml b/tests/resources/xml/sp_WssKerberosV5ApReqToken11.xml
new file mode 100644
index 00000000..00f87c2e
--- /dev/null
+++ b/tests/resources/xml/sp_WssKerberosV5ApReqToken11.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssRelV10Token10.xml b/tests/resources/xml/sp_WssRelV10Token10.xml
new file mode 100644
index 00000000..0b041bda
--- /dev/null
+++ b/tests/resources/xml/sp_WssRelV10Token10.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssRelV10Token11.xml b/tests/resources/xml/sp_WssRelV10Token11.xml
new file mode 100644
index 00000000..b2818f51
--- /dev/null
+++ b/tests/resources/xml/sp_WssRelV10Token11.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssRelV20Token10.xml b/tests/resources/xml/sp_WssRelV20Token10.xml
new file mode 100644
index 00000000..50d53093
--- /dev/null
+++ b/tests/resources/xml/sp_WssRelV20Token10.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssRelV20Token11.xml b/tests/resources/xml/sp_WssRelV20Token11.xml
new file mode 100644
index 00000000..cc10a513
--- /dev/null
+++ b/tests/resources/xml/sp_WssRelV20Token11.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssSamlV11Token10.xml b/tests/resources/xml/sp_WssSamlV11Token10.xml
new file mode 100644
index 00000000..a43dc8b0
--- /dev/null
+++ b/tests/resources/xml/sp_WssSamlV11Token10.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssSamlV11Token11.xml b/tests/resources/xml/sp_WssSamlV11Token11.xml
new file mode 100644
index 00000000..6c11f647
--- /dev/null
+++ b/tests/resources/xml/sp_WssSamlV11Token11.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssSamlV20Token11.xml b/tests/resources/xml/sp_WssSamlV20Token11.xml
new file mode 100644
index 00000000..a5be0604
--- /dev/null
+++ b/tests/resources/xml/sp_WssSamlV20Token11.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssUsernameToken10.xml b/tests/resources/xml/sp_WssUsernameToken10.xml
new file mode 100644
index 00000000..cb1ecf84
--- /dev/null
+++ b/tests/resources/xml/sp_WssUsernameToken10.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssUsernameToken11.xml b/tests/resources/xml/sp_WssUsernameToken11.xml
new file mode 100644
index 00000000..16aeeff0
--- /dev/null
+++ b/tests/resources/xml/sp_WssUsernameToken11.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssX509Pkcs7Token10.xml b/tests/resources/xml/sp_WssX509Pkcs7Token10.xml
new file mode 100644
index 00000000..e5cb90ca
--- /dev/null
+++ b/tests/resources/xml/sp_WssX509Pkcs7Token10.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssX509Pkcs7Token11.xml b/tests/resources/xml/sp_WssX509Pkcs7Token11.xml
new file mode 100644
index 00000000..8e9aa504
--- /dev/null
+++ b/tests/resources/xml/sp_WssX509Pkcs7Token11.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssX509PkiPathV1Token10.xml b/tests/resources/xml/sp_WssX509PkiPathV1Token10.xml
new file mode 100644
index 00000000..af250e42
--- /dev/null
+++ b/tests/resources/xml/sp_WssX509PkiPathV1Token10.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssX509PkiPathV1Token11.xml b/tests/resources/xml/sp_WssX509PkiPathV1Token11.xml
new file mode 100644
index 00000000..896712c1
--- /dev/null
+++ b/tests/resources/xml/sp_WssX509PkiPathV1Token11.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssX509V1Token11.xml b/tests/resources/xml/sp_WssX509V1Token11.xml
new file mode 100644
index 00000000..62becc8f
--- /dev/null
+++ b/tests/resources/xml/sp_WssX509V1Token11.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssX509V3Token10.xml b/tests/resources/xml/sp_WssX509V3Token10.xml
new file mode 100644
index 00000000..6931e0a0
--- /dev/null
+++ b/tests/resources/xml/sp_WssX509V3Token10.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_WssX509V3Token11.xml b/tests/resources/xml/sp_WssX509V3Token11.xml
new file mode 100644
index 00000000..f6d56e98
--- /dev/null
+++ b/tests/resources/xml/sp_WssX509V3Token11.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_X509Token.xml b/tests/resources/xml/sp_X509Token.xml
new file mode 100644
index 00000000..7cd7f958
--- /dev/null
+++ b/tests/resources/xml/sp_X509Token.xml
@@ -0,0 +1,3 @@
+
+ some
+
diff --git a/tests/resources/xml/sp_XPath.xml b/tests/resources/xml/sp_XPath.xml
new file mode 100644
index 00000000..4a2bfcaa
--- /dev/null
+++ b/tests/resources/xml/sp_XPath.xml
@@ -0,0 +1 @@
+/bookstore/book[price>35.00]/title
diff --git a/tests/resources/xml/sp_XPath10.xml b/tests/resources/xml/sp_XPath10.xml
new file mode 100644
index 00000000..233ab1fd
--- /dev/null
+++ b/tests/resources/xml/sp_XPath10.xml
@@ -0,0 +1 @@
+
diff --git a/tests/resources/xml/sp_XPathFilter20.xml b/tests/resources/xml/sp_XPathFilter20.xml
new file mode 100644
index 00000000..c871aa27
--- /dev/null
+++ b/tests/resources/xml/sp_XPathFilter20.xml
@@ -0,0 +1 @@
+