diff --git a/src/XML/ds/SignatureMethod.php b/src/XML/ds/SignatureMethod.php index 095e1ecb..c067c346 100644 --- a/src/XML/ds/SignatureMethod.php +++ b/src/XML/ds/SignatureMethod.php @@ -8,9 +8,16 @@ 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. * @@ -18,13 +25,23 @@ */ 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( @@ -36,6 +53,8 @@ public function __construct( 'Invalid signature method: %s', InvalidArgumentException::class, ); + + $this->setElements($children); } @@ -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 * @@ -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)); } @@ -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; } } diff --git a/tests/XML/ds/SignatureMethodTest.php b/tests/XML/ds/SignatureMethodTest.php index 62097e7b..b89e490a 100644 --- a/tests/XML/ds/SignatureMethodTest.php +++ b/tests/XML/ds/SignatureMethodTest.php @@ -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; @@ -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', @@ -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( + 'Some', + )->documentElement); + + $signatureMethod = new SignatureMethod(C::SIG_RSA_SHA256, $hmacOutputLength, [$chunk]); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), diff --git a/tests/resources/schemas/simplesamlphp.xsd b/tests/resources/schemas/simplesamlphp.xsd new file mode 100644 index 00000000..7ce40447 --- /dev/null +++ b/tests/resources/schemas/simplesamlphp.xsd @@ -0,0 +1,31 @@ + + + + + + ]> + + + + + + + + + + + + + + + + diff --git a/tests/resources/xml/ds_SignatureMethod.xml b/tests/resources/xml/ds_SignatureMethod.xml index 2dccda50..0ddb104f 100644 --- a/tests/resources/xml/ds_SignatureMethod.xml +++ b/tests/resources/xml/ds_SignatureMethod.xml @@ -1 +1,4 @@ - + + 1234 + Some +