Skip to content

Commit

Permalink
Refactor ds:SignatureMethod
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Nov 29, 2024
1 parent 310db4e commit 15949c9
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 4 deletions.
41 changes: 40 additions & 1 deletion src/XML/ds/SignatureMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,40 @@
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\Exception\TooManyElementsException;
use SimpleSAML\XML\ExtendableElementTrait;
use SimpleSAML\XML\XsNamespace as NS;
use SimpleSAML\XMLSecurity\Constants as C;
use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException;

use function array_keys;
use function array_merge;
use function array_pop;

/**
* Class representing a ds:SignatureMethod element.
*
* @package simplesamlphp/xml-security
*/
final class SignatureMethod extends AbstractDsElement
{
use ExtendableElementTrait;

/** The namespace-attribute for the xs:any element */
public const XS_ANY_ELT_NAMESPACE = NS::OTHER;


/**
* Initialize a SignatureMethod element.
*
* @param string $Algorithm
* @param \SimpleSAML\XMLSecurity\ds\HMACOutputLength|null $hmacOutputLength
* @param array<\SimpleSAML\XML\SerializableElementInterface> $children
*/
public function __construct(
protected string $Algorithm,
protected ?HMACOutputLength $hmacOutputLength = null,
array $children = [],
) {
Assert::validURI($Algorithm, SchemaViolationException::class);
Assert::oneOf(
Expand All @@ -36,6 +53,8 @@ public function __construct(
'Invalid signature method: %s',
InvalidArgumentException::class,
);

$this->setElements($children);
}


Expand All @@ -50,6 +69,17 @@ public function getAlgorithm(): string
}


/**
* Collect the value of the hmacOutputLength-property
*
* @return \SimpleSAML\XMLSecurity\ds\HMACOutputLength|null
*/
public function getHMACOutputLength(): ?HMACOutputLength
{
return $this->hmacOutputLength;
}


/**
* Convert XML into a SignatureMethod
*
Expand All @@ -66,7 +96,10 @@ public static function fromXML(DOMElement $xml): static

$Algorithm = SignatureMethod::getAttribute($xml, 'Algorithm');

return new static($Algorithm);
$hmacOutputLength = HMACOutputLength::getChildrenOfClass($xml);
Assert::maxCount($hmacOutputLength, 1, TooManyElementsException::class);

return new static($Algorithm, array_pop($hmacOutputLength), self::getChildElementsFromXML($xml));
}


Expand All @@ -81,6 +114,12 @@ public function toXML(DOMElement $parent = null): DOMElement
$e = $this->instantiateParentElement($parent);
$e->setAttribute('Algorithm', $this->getAlgorithm());

$this->getHMACOutputLength()?->toXML($e);

foreach ($this->getElements() as $elt) {
$elt->toXML($e);
}

return $e;
}
}
12 changes: 10 additions & 2 deletions tests/XML/ds/SignatureMethodTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait;
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;
use SimpleSAML\XMLSecurity\Constants as C;
use SimpleSAML\XMLSecurity\XML\ds\AbstractDsElement;
use SimpleSAML\XMLSecurity\XML\ds\HMACOutputLength;
use SimpleSAML\XMLSecurity\XML\ds\SignatureMethod;

use function dirname;
Expand All @@ -34,7 +36,7 @@ public static function setUpBeforeClass(): void
{
self::$testedClass = SignatureMethod::class;

self::$schemaFile = dirname(__FILE__, 4) . '/resources/schemas/xmldsig1-schema.xsd';
self::$schemaFile = dirname(__FILE__, 3) . '/resources/schemas/simplesamlphp.xsd';

self::$xmlRepresentation = DOMDocumentFactory::fromFile(
dirname(__FILE__, 3) . '/resources/xml/ds_SignatureMethod.xml',
Expand All @@ -46,7 +48,13 @@ public static function setUpBeforeClass(): void
*/
public function testMarshalling(): void
{
$signatureMethod = new SignatureMethod(C::SIG_RSA_SHA256);
$hmacOutputLength = new HMACOutputLength('1234');

$chunk = new Chunk(DOMDocumentFactory::fromString(
'<ssp:Chunk xmlns:ssp="urn:x-simplesamlphp:namespace">Some</ssp:Chunk>',
)->documentElement);

$signatureMethod = new SignatureMethod(C::SIG_RSA_SHA256, $hmacOutputLength, [$chunk]);

$this->assertEquals(
self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
Expand Down
31 changes: 31 additions & 0 deletions tests/resources/schemas/simplesamlphp.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE schema
PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd"
[
<!ATTLIST schema
xmlns:ds CDATA #FIXED "urn:x-simplesamlphp:namespace">
<!ENTITY ssp 'urn:x-simplesamlphp:namespace'>
<!ENTITY % p ''>
<!ENTITY % s ''>
]>

<!-- Schema for SimpleSAMLphp dummy classes -->


<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:ssp="urn:x-simplesamlphp:namespace"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
targetNamespace="urn:x-simplesamlphp:namespace"
version="0.1" elementFormDefault="qualified">

<import namespace='http://www.w3.org/2000/09/xmldsig#'
schemaLocation='../../../resources/schemas/xmldsig1-schema.xsd'/>

<!-- Start Chunk -->

<element name="Chunk" type="string"/>

<!-- End Chunk -->

</schema>

5 changes: 4 additions & 1 deletion tests/resources/xml/ds_SignatureMethod.xml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
<ds:SignatureMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:SignatureMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256">
<ds:HMACOutputLength>1234</ds:HMACOutputLength>
<ssp:Chunk xmlns:ssp="urn:x-simplesamlphp:namespace">Some</ssp:Chunk>
</ds:SignatureMethod>

0 comments on commit 15949c9

Please sign in to comment.