From 73c7c6ea3d72b12d897c79f1b11c14006076d33b Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Fri, 29 Nov 2024 23:08:17 +0100 Subject: [PATCH 01/15] Refactor X509SerialNumber --- composer.json | 2 +- src/XML/ds/X509SerialNumber.php | 54 ++------------------------- tests/XML/ds/X509DataTest.php | 2 +- tests/XML/ds/X509IssuerSerialTest.php | 2 +- tests/XML/ds/X509SerialNumberTest.php | 2 +- 5 files changed, 8 insertions(+), 54 deletions(-) diff --git a/composer.json b/composer.json index b8a0c81b..1cd94084 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "ext-spl": "*", "simplesamlphp/assert": "^1.3", - "simplesamlphp/xml-common": "^1.18.5" + "simplesamlphp/xml-common": "^1.19.0" }, "require-dev": { "simplesamlphp/simplesamlphp-test-framework": "^1.7" diff --git a/src/XML/ds/X509SerialNumber.php b/src/XML/ds/X509SerialNumber.php index d7b65913..eb33d827 100644 --- a/src/XML/ds/X509SerialNumber.php +++ b/src/XML/ds/X509SerialNumber.php @@ -8,7 +8,7 @@ use SimpleSAML\Assert\Assert; use SimpleSAML\XML\Exception\InvalidDOMElementException; use SimpleSAML\XML\Exception\SchemaViolationException; -use SimpleSAML\XML\StringElementTrait; +use SimpleSAML\XML\IntegerElementTrait; /** * Class representing a ds:X509SerialNumber element. @@ -17,60 +17,14 @@ */ final class X509SerialNumber extends AbstractDsElement { - use StringElementTrait; + use IntegerElementTrait; /** - * @param string $content + * @param int $content */ - public function __construct(string $content) + public function __construct(int $content) { $this->setContent($content); } - - - /** - * Validate the content of the element. - * - * @param string $content The value to go in the XML textContent - * @throws \Exception on failure - * @return void - */ - protected function validateContent(/** @scrutinizer ignore-unused */ string $content): void - { - Assert::numeric($content, SchemaViolationException::class); - } - - - /** - * Convert XML into a X509SerialNumber - * - * @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, 'X509SerialNumber', InvalidDOMElementException::class); - Assert::same($xml->namespaceURI, X509SerialNumber::NS, InvalidDOMElementException::class); - - return new static($xml->textContent); - } - - - /** - * Convert this X509SerialNumber element to XML. - * - * @param \DOMElement|null $parent The element we should append this X509SerialNumber element to. - * @return \DOMElement - */ - public function toXML(DOMElement $parent = null): DOMElement - { - $e = $this->instantiateParentElement($parent); - $e->textContent = $this->getContent(); - - return $e; - } } diff --git a/tests/XML/ds/X509DataTest.php b/tests/XML/ds/X509DataTest.php index 85fa3cfd..35e5deac 100644 --- a/tests/XML/ds/X509DataTest.php +++ b/tests/XML/ds/X509DataTest.php @@ -111,7 +111,7 @@ public function testMarshalling(): void 'C=US,ST=Hawaii,L=Honolulu,O=SimpleSAMLphp HQ,CN=SimpleSAMLphp Testing CA,emailAddress=%s', 'noreply@simplesamlphp.org', )), - new X509SerialNumber('2'), + new X509SerialNumber(2), ), new X509SubjectName(self::$certData['name']), new X509Digest(self::$digest, C::DIGEST_SHA256), diff --git a/tests/XML/ds/X509IssuerSerialTest.php b/tests/XML/ds/X509IssuerSerialTest.php index b8658966..19490ef5 100644 --- a/tests/XML/ds/X509IssuerSerialTest.php +++ b/tests/XML/ds/X509IssuerSerialTest.php @@ -57,7 +57,7 @@ public function setUp(): void /** @var string[] $details */ $details = self::$key->getCertificateDetails(); self::$issuer = new X509IssuerName(CertificateUtils::parseIssuer($details['issuer'])); - self::$serial = new X509SerialNumber($details['serialNumber']); + self::$serial = new X509SerialNumber(intval($details['serialNumber'])); } diff --git a/tests/XML/ds/X509SerialNumberTest.php b/tests/XML/ds/X509SerialNumberTest.php index ee0f8077..eed31066 100644 --- a/tests/XML/ds/X509SerialNumberTest.php +++ b/tests/XML/ds/X509SerialNumberTest.php @@ -43,7 +43,7 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $serialNumber = new X509SerialNumber('123456'); + $serialNumber = new X509SerialNumber(123456); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), From 5855e0e6ce6cffa4ebd60a87b2209601899165ff Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Fri, 29 Nov 2024 23:22:18 +0100 Subject: [PATCH 02/15] Implement IntegerElementTrait --- src/XML/ds/X509SerialNumber.php | 8 ++------ tests/XML/ds/X509DataTest.php | 2 +- tests/XML/ds/X509IssuerSerialTest.php | 2 +- tests/XML/ds/X509SerialNumberTest.php | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/XML/ds/X509SerialNumber.php b/src/XML/ds/X509SerialNumber.php index eb33d827..19ad7d08 100644 --- a/src/XML/ds/X509SerialNumber.php +++ b/src/XML/ds/X509SerialNumber.php @@ -4,10 +4,6 @@ namespace SimpleSAML\XMLSecurity\XML\ds; -use DOMElement; -use SimpleSAML\Assert\Assert; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; use SimpleSAML\XML\IntegerElementTrait; /** @@ -21,9 +17,9 @@ final class X509SerialNumber extends AbstractDsElement /** - * @param int $content + * @param string $content */ - public function __construct(int $content) + public function __construct(string $content) { $this->setContent($content); } diff --git a/tests/XML/ds/X509DataTest.php b/tests/XML/ds/X509DataTest.php index 35e5deac..85fa3cfd 100644 --- a/tests/XML/ds/X509DataTest.php +++ b/tests/XML/ds/X509DataTest.php @@ -111,7 +111,7 @@ public function testMarshalling(): void 'C=US,ST=Hawaii,L=Honolulu,O=SimpleSAMLphp HQ,CN=SimpleSAMLphp Testing CA,emailAddress=%s', 'noreply@simplesamlphp.org', )), - new X509SerialNumber(2), + new X509SerialNumber('2'), ), new X509SubjectName(self::$certData['name']), new X509Digest(self::$digest, C::DIGEST_SHA256), diff --git a/tests/XML/ds/X509IssuerSerialTest.php b/tests/XML/ds/X509IssuerSerialTest.php index 19490ef5..b8658966 100644 --- a/tests/XML/ds/X509IssuerSerialTest.php +++ b/tests/XML/ds/X509IssuerSerialTest.php @@ -57,7 +57,7 @@ public function setUp(): void /** @var string[] $details */ $details = self::$key->getCertificateDetails(); self::$issuer = new X509IssuerName(CertificateUtils::parseIssuer($details['issuer'])); - self::$serial = new X509SerialNumber(intval($details['serialNumber'])); + self::$serial = new X509SerialNumber($details['serialNumber']); } diff --git a/tests/XML/ds/X509SerialNumberTest.php b/tests/XML/ds/X509SerialNumberTest.php index eed31066..ee0f8077 100644 --- a/tests/XML/ds/X509SerialNumberTest.php +++ b/tests/XML/ds/X509SerialNumberTest.php @@ -43,7 +43,7 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $serialNumber = new X509SerialNumber(123456); + $serialNumber = new X509SerialNumber('123456'); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), From 310db4eb24f9c9211883217bf9ac054f1cb866ae Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Fri, 29 Nov 2024 23:40:29 +0100 Subject: [PATCH 03/15] Add HMACOutputLength element --- src/XML/ds/HMACOutputLength.php | 26 +++++++++++ tests/XML/ds/HMACOutputLengthTest.php | 51 +++++++++++++++++++++ tests/resources/xml/ds_HMACOutputLength.xml | 1 + 3 files changed, 78 insertions(+) create mode 100644 src/XML/ds/HMACOutputLength.php create mode 100644 tests/XML/ds/HMACOutputLengthTest.php create mode 100644 tests/resources/xml/ds_HMACOutputLength.xml diff --git a/src/XML/ds/HMACOutputLength.php b/src/XML/ds/HMACOutputLength.php new file mode 100644 index 00000000..e8a6228c --- /dev/null +++ b/src/XML/ds/HMACOutputLength.php @@ -0,0 +1,26 @@ +setContent($length); + } +} diff --git a/tests/XML/ds/HMACOutputLengthTest.php b/tests/XML/ds/HMACOutputLengthTest.php new file mode 100644 index 00000000..6d3d2eba --- /dev/null +++ b/tests/XML/ds/HMACOutputLengthTest.php @@ -0,0 +1,51 @@ +assertEquals( + self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), + strval($hmacOutputLength), + ); + } +} diff --git a/tests/resources/xml/ds_HMACOutputLength.xml b/tests/resources/xml/ds_HMACOutputLength.xml new file mode 100644 index 00000000..cf8b9f3a --- /dev/null +++ b/tests/resources/xml/ds_HMACOutputLength.xml @@ -0,0 +1 @@ +1234 From 1d752e73763d653825c6552db36e95a8ee226fbc Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Sat, 30 Nov 2024 00:28:35 +0100 Subject: [PATCH 04/15] Refactor ds:SignatureMethod --- src/XML/ds/SignatureMethod.php | 41 +++++++++++++++++++++- tests/XML/ds/SignatureMethodTest.php | 12 +++++-- tests/resources/schemas/simplesamlphp.xsd | 31 ++++++++++++++++ tests/resources/xml/ds_SignatureMethod.xml | 5 ++- 4 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 tests/resources/schemas/simplesamlphp.xsd diff --git a/src/XML/ds/SignatureMethod.php b/src/XML/ds/SignatureMethod.php index 095e1ecb..2b5d5174 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\XML\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\XML\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 + From 889f012199c0003260c3b430ae6a2dac05c47d80 Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Sat, 30 Nov 2024 00:41:47 +0100 Subject: [PATCH 05/15] Add ds:MgmtData element --- src/XML/ds/KeyInfo.php | 8 ++-- src/XML/ds/MgmtData.php | 26 +++++++++++++ src/XML/element.registry.php | 2 +- src/XML/xenc/OriginatorKeyInfo.php | 9 +++-- src/XML/xenc/RecipientKeyInfo.php | 9 +++-- tests/XML/ds/MgmtDataTest.php | 55 ++++++++++++++++++++++++++++ tests/XML/ds/SignatureMethodTest.php | 33 +++++++++++++++++ tests/resources/xml/ds_MgmtData.xml | 1 + 8 files changed, 130 insertions(+), 13 deletions(-) create mode 100644 src/XML/ds/MgmtData.php create mode 100644 tests/XML/ds/MgmtDataTest.php create mode 100644 tests/resources/xml/ds_MgmtData.xml diff --git a/src/XML/ds/KeyInfo.php b/src/XML/ds/KeyInfo.php index 5f499345..079fde5e 100644 --- a/src/XML/ds/KeyInfo.php +++ b/src/XML/ds/KeyInfo.php @@ -39,7 +39,7 @@ public static function fromXML(DOMElement $xml): static $x509Data = X509Data::getChildrenOfClass($xml); //$pgpData = PGPData::getChildrenOfClass($xml); //$spkiData = SPKIData::getChildrenOfClass($xml); - //$mgmtData = MgmtData::getChildrenOfClass($xml); + $mgmtData = MgmtData::getChildrenOfClass($xml); $other = self::getChildElementsFromXML($xml); $info = array_merge( @@ -47,9 +47,9 @@ public static function fromXML(DOMElement $xml): static $keyValue, $retrievalMethod, $x509Data, - //$pgpdata, - //$spkidata, - //$mgmtdata, + //$pgpData, + //$spkiData, + $mgmtData, $other, ); diff --git a/src/XML/ds/MgmtData.php b/src/XML/ds/MgmtData.php new file mode 100644 index 00000000..23a1d7de --- /dev/null +++ b/src/XML/ds/MgmtData.php @@ -0,0 +1,26 @@ +setContent($content); + } +} diff --git a/src/XML/element.registry.php b/src/XML/element.registry.php index 9a55180d..441e0cee 100644 --- a/src/XML/element.registry.php +++ b/src/XML/element.registry.php @@ -12,7 +12,7 @@ 'KeyName' => '\SimpleSAML\XMLSecurity\XML\ds\KeyName', 'KeyValue' => '\SimpleSAML\XMLSecurity\XML\ds\KeyValue', 'Manifest' => '\SimpleSAML\XMLSecurity\XML\ds\Manifest', -// 'MgmtData' => '\SimpleSAML\XMLSecurity\XML\ds\MgmtData', + 'MgmtData' => '\SimpleSAML\XMLSecurity\XML\ds\MgmtData', 'Object' => '\SimpleSAML\XMLSecurity\XML\ds\DsObject', // 'PGPData' => '\SimpleSAML\XMLSecurity\XML\ds\PGPData', 'Reference' => '\SimpleSAML\XMLSecurity\XML\ds\Reference', diff --git a/src/XML/xenc/OriginatorKeyInfo.php b/src/XML/xenc/OriginatorKeyInfo.php index 2f7db9a1..2aba0d3e 100644 --- a/src/XML/xenc/OriginatorKeyInfo.php +++ b/src/XML/xenc/OriginatorKeyInfo.php @@ -11,6 +11,7 @@ use SimpleSAML\XMLSecurity\XML\ds\AbstractKeyInfoType; use SimpleSAML\XMLSecurity\XML\ds\KeyName; use SimpleSAML\XMLSecurity\XML\ds\KeyValue; +use SimpleSAML\XMLSecurity\XML\ds\MgmtData; use SimpleSAML\XMLSecurity\XML\ds\RetrievalMethod; use SimpleSAML\XMLSecurity\XML\ds\X509Data; @@ -52,7 +53,7 @@ public static function fromXML(DOMElement $xml): static $x509Data = X509Data::getChildrenOfClass($xml); //$pgpData = PGPData::getChildrenOfClass($xml); //$spkiData = SPKIData::getChildrenOfClass($xml); - //$mgmtData = MgmtData::getChildrenOfClass($xml); + $mgmtData = MgmtData::getChildrenOfClass($xml); $other = self::getChildElementsFromXML($xml); $info = array_merge( @@ -60,9 +61,9 @@ public static function fromXML(DOMElement $xml): static $keyValue, $retrievalMethod, $x509Data, - //$pgpdata, - //$spkidata, - //$mgmtdata, + //$pgpData, + //$spkiData, + $mgmtData, $other, ); diff --git a/src/XML/xenc/RecipientKeyInfo.php b/src/XML/xenc/RecipientKeyInfo.php index c5eb61b9..4d8d6136 100644 --- a/src/XML/xenc/RecipientKeyInfo.php +++ b/src/XML/xenc/RecipientKeyInfo.php @@ -11,6 +11,7 @@ use SimpleSAML\XMLSecurity\XML\ds\AbstractKeyInfoType; use SimpleSAML\XMLSecurity\XML\ds\KeyName; use SimpleSAML\XMLSecurity\XML\ds\KeyValue; +use SimpleSAML\XMLSecurity\XML\ds\MgmtData; use SimpleSAML\XMLSecurity\XML\ds\RetrievalMethod; use SimpleSAML\XMLSecurity\XML\ds\X509Data; @@ -52,7 +53,7 @@ public static function fromXML(DOMElement $xml): static $x509Data = X509Data::getChildrenOfClass($xml); //$pgpData = PGPData::getChildrenOfClass($xml); //$spkiData = SPKIData::getChildrenOfClass($xml); - //$mgmtData = MgmtData::getChildrenOfClass($xml); + $mgmtData = MgmtData::getChildrenOfClass($xml); $other = self::getChildElementsFromXML($xml); $info = array_merge( @@ -60,9 +61,9 @@ public static function fromXML(DOMElement $xml): static $keyValue, $retrievalMethod, $x509Data, - //$pgpdata, - //$spkidata, - //$mgmtdata, + //$pgpData, + //$spkiData, + $mgmtData, $other, ); diff --git a/tests/XML/ds/MgmtDataTest.php b/tests/XML/ds/MgmtDataTest.php new file mode 100644 index 00000000..935b87ce --- /dev/null +++ b/tests/XML/ds/MgmtDataTest.php @@ -0,0 +1,55 @@ +assertEquals( + self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), + strval($mgmtData), + ); + } +} diff --git a/tests/XML/ds/SignatureMethodTest.php b/tests/XML/ds/SignatureMethodTest.php index b89e490a..d1046a81 100644 --- a/tests/XML/ds/SignatureMethodTest.php +++ b/tests/XML/ds/SignatureMethodTest.php @@ -11,6 +11,7 @@ use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; use SimpleSAML\XMLSecurity\Constants as C; +use SimpleSAML\XMLSecurity\Utils\XPath; use SimpleSAML\XMLSecurity\XML\ds\AbstractDsElement; use SimpleSAML\XMLSecurity\XML\ds\HMACOutputLength; use SimpleSAML\XMLSecurity\XML\ds\SignatureMethod; @@ -61,4 +62,36 @@ public function testMarshalling(): void strval($signatureMethod), ); } + + + /** + */ + public function testMarshallingElementOrder(): void + { + $hmacOutputLength = new HMACOutputLength('1234'); + + $chunk = new Chunk(DOMDocumentFactory::fromString( + 'Some', + )->documentElement); + + $signatureMethod = new SignatureMethod(C::SIG_RSA_SHA256, $hmacOutputLength, [$chunk]); + + $signatureMethodElement = $signatureMethod->toXML(); + + $xpCache = XPath::getXPath($signatureMethodElement); + + $hmacOutputLength = XPath::xpQuery($signatureMethodElement, './ds:HMACOutputLength', $xpCache); + $this->assertCount(1, $hmacOutputLength); + + /** @var \DOMElement[] $signatureMethodElements */ + $signatureMethodElements = XPath::xpQuery( + $signatureMethodElement, + './ds:HMACOutputLength/following-sibling::*', + $xpCache, + ); + + // Test ordering of SignatureMethod contents + $this->assertCount(1, $signatureMethodElements); + $this->assertEquals('ssp:Chunk', $signatureMethodElements[0]->tagName); + } } diff --git a/tests/resources/xml/ds_MgmtData.xml b/tests/resources/xml/ds_MgmtData.xml new file mode 100644 index 00000000..a0e1e1d2 --- /dev/null +++ b/tests/resources/xml/ds_MgmtData.xml @@ -0,0 +1 @@ +ManagementData From de26a79ed06007d3b7d2104854af80780f5cc50a Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Sat, 30 Nov 2024 15:38:19 +0100 Subject: [PATCH 06/15] Add ds:PGPKeyID element --- src/XML/ds/PGPKeyID.php | 26 +++++++++++++++ tests/XML/ds/PGPKeyIDTest.php | 51 +++++++++++++++++++++++++++++ tests/resources/xml/ds_PGPKeyID.xml | 1 + 3 files changed, 78 insertions(+) create mode 100644 src/XML/ds/PGPKeyID.php create mode 100644 tests/XML/ds/PGPKeyIDTest.php create mode 100644 tests/resources/xml/ds_PGPKeyID.xml diff --git a/src/XML/ds/PGPKeyID.php b/src/XML/ds/PGPKeyID.php new file mode 100644 index 00000000..dea62bc9 --- /dev/null +++ b/src/XML/ds/PGPKeyID.php @@ -0,0 +1,26 @@ +setContent($content); + } +} diff --git a/tests/XML/ds/PGPKeyIDTest.php b/tests/XML/ds/PGPKeyIDTest.php new file mode 100644 index 00000000..915dc6ee --- /dev/null +++ b/tests/XML/ds/PGPKeyIDTest.php @@ -0,0 +1,51 @@ +assertEquals( + self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), + strval($pgpKeyId), + ); + } +} diff --git a/tests/resources/xml/ds_PGPKeyID.xml b/tests/resources/xml/ds_PGPKeyID.xml new file mode 100644 index 00000000..9bd4d1a8 --- /dev/null +++ b/tests/resources/xml/ds_PGPKeyID.xml @@ -0,0 +1 @@ +GpM7 From 6f5c6f9715c9e9440906756047c70a38f75004b0 Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Sat, 30 Nov 2024 15:40:33 +0100 Subject: [PATCH 07/15] Add ds:PGPKeyPacket element --- src/XML/ds/PGPKeyPacket.php | 26 +++++++++++++ tests/XML/ds/PGPKeyPacketTest.php | 51 +++++++++++++++++++++++++ tests/resources/xml/ds_PGPKeyPacket.xml | 1 + 3 files changed, 78 insertions(+) create mode 100644 src/XML/ds/PGPKeyPacket.php create mode 100644 tests/XML/ds/PGPKeyPacketTest.php create mode 100644 tests/resources/xml/ds_PGPKeyPacket.xml diff --git a/src/XML/ds/PGPKeyPacket.php b/src/XML/ds/PGPKeyPacket.php new file mode 100644 index 00000000..614bf86d --- /dev/null +++ b/src/XML/ds/PGPKeyPacket.php @@ -0,0 +1,26 @@ +setContent($content); + } +} diff --git a/tests/XML/ds/PGPKeyPacketTest.php b/tests/XML/ds/PGPKeyPacketTest.php new file mode 100644 index 00000000..b1d6c942 --- /dev/null +++ b/tests/XML/ds/PGPKeyPacketTest.php @@ -0,0 +1,51 @@ +assertEquals( + self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), + strval($pgpKeyPacket), + ); + } +} diff --git a/tests/resources/xml/ds_PGPKeyPacket.xml b/tests/resources/xml/ds_PGPKeyPacket.xml new file mode 100644 index 00000000..30ef37e4 --- /dev/null +++ b/tests/resources/xml/ds_PGPKeyPacket.xml @@ -0,0 +1 @@ +GpM7 From bf9e836710d042a6447b7af55f45d97a76e86152 Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Sat, 30 Nov 2024 16:32:27 +0100 Subject: [PATCH 08/15] Add ds:PGPData element --- src/XML/ds/AbstractKeyInfoType.php | 3 +- src/XML/ds/AbstractPGPDataType.php | 120 ++++++++++++++++++ src/XML/ds/KeyInfo.php | 4 +- src/XML/ds/PGPData.php | 14 ++ src/XML/element.registry.php | 2 +- src/XML/xenc/OriginatorKeyInfo.php | 5 +- src/XML/xenc/RecipientKeyInfo.php | 5 +- tests/XML/ds/KeyInfoTest.php | 9 ++ tests/XML/ds/PGPDataTest.php | 95 ++++++++++++++ tests/XML/xenc/OriginatorKeyInfoTest.php | 9 ++ tests/XML/xenc/RecipientKeyInfoTest.php | 9 ++ tests/resources/xml/ds_KeyInfo.xml | 5 + tests/resources/xml/ds_PGPData.xml | 5 + tests/resources/xml/ds_Signature.xml | 5 + .../resources/xml/xenc_OriginatorKeyInfo.xml | 5 + tests/resources/xml/xenc_RecipientKeyInfo.xml | 5 + 16 files changed, 292 insertions(+), 8 deletions(-) create mode 100644 src/XML/ds/AbstractPGPDataType.php create mode 100644 src/XML/ds/PGPData.php create mode 100644 tests/XML/ds/PGPDataTest.php create mode 100644 tests/resources/xml/ds_PGPData.xml diff --git a/src/XML/ds/AbstractKeyInfoType.php b/src/XML/ds/AbstractKeyInfoType.php index b266045f..3753e670 100644 --- a/src/XML/ds/AbstractKeyInfoType.php +++ b/src/XML/ds/AbstractKeyInfoType.php @@ -35,6 +35,7 @@ abstract class AbstractKeyInfoType extends AbstractDsElement * \SimpleSAML\XMLSecurity\XML\ds\KeyValue| * \SimpleSAML\XMLSecurity\XML\ds\RetrievalMethod| * \SimpleSAML\XMLSecurity\XML\ds\X509Data| + * \SimpleSAML\XMLSecurity\XML\ds\PGPData| * \SimpleSAML\XML\SerializableElementInterface * )[] $info * @param string|null $Id @@ -64,7 +65,7 @@ final public function __construct( if ($item instanceof AbstractDsElement) { Assert::isInstanceOfAny( $item, - [KeyName::class, KeyValue::class, RetrievalMethod::class, X509Data::class], + [KeyName::class, KeyValue::class, RetrievalMethod::class, X509Data::class, PGPData::class], SchemaViolationException::class, ); } diff --git a/src/XML/ds/AbstractPGPDataType.php b/src/XML/ds/AbstractPGPDataType.php new file mode 100644 index 00000000..b526fc47 --- /dev/null +++ b/src/XML/ds/AbstractPGPDataType.php @@ -0,0 +1,120 @@ + $children + */ + final public function __construct( + protected ?PGPKeyID $pgpKeyId = null, + protected ?PGPKeyPacket $pgpKeyPacket = null, + array $children = [], + ) { + if ($pgpKeyId === null && $pgpKeyPacket === null) { + throw new SchemaViolationException("ds:PGPKeyID and ds:PGPKeyPacket can't both be null."); + } + + $this->setElements($children); + } + + + /** + * Collect the value of the PGPKeyID-property + * + * @return \SimpleSAML\XMLSecurity\XML\ds\PGPKeyID|null + */ + public function getPGPKeyID(): ?PGPKeyID + { + return $this->pgpKeyId; + } + + + /** + * Collect the value of the PGPKeyPacket-property + * + * @return \SimpleSAML\XMLSecurity\XML\ds\PGPKeyPacket|null + */ + public function getPGPKeyPacket(): ?PGPKeyPacket + { + return $this->pgpKeyPacket; + } + + + /** + * Convert XML into a PGPData + * + * @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); + + $pgpKeyId = PGPKeyID::getChildrenOfClass($xml); + Assert::maxCount($pgpKeyId, 1, TooManyElementsException::class); + + $pgpKeyPacket = PGPKeyPacket::getChildrenOfClass($xml); + Assert::maxCount($pgpKeyPacket, 1, TooManyElementsException::class); + + return new static( + array_pop($pgpKeyId), + array_pop($pgpKeyPacket), + self::getChildElementsFromXML($xml), + ); + } + + + /** + * Convert this PGPData to XML. + * + * @param \DOMElement|null $parent The element we should append this PGPData to. + * @return \DOMElement + */ + public function toXML(DOMElement $parent = null): DOMElement + { + $e = $this->instantiateParentElement($parent); + + $this->getPGPKeyId()?->toXML($e); + $this->getPGPKeyPacket()?->toXML($e); + + foreach ($this->getElements() as $elt) { + $elt->toXML($e); + } + + return $e; + } +} diff --git a/src/XML/ds/KeyInfo.php b/src/XML/ds/KeyInfo.php index 079fde5e..59cd4fce 100644 --- a/src/XML/ds/KeyInfo.php +++ b/src/XML/ds/KeyInfo.php @@ -37,7 +37,7 @@ public static function fromXML(DOMElement $xml): static $keyValue = KeyValue::getChildrenOfClass($xml); $retrievalMethod = RetrievalMethod::getChildrenOfClass($xml); $x509Data = X509Data::getChildrenOfClass($xml); - //$pgpData = PGPData::getChildrenOfClass($xml); + $pgpData = PGPData::getChildrenOfClass($xml); //$spkiData = SPKIData::getChildrenOfClass($xml); $mgmtData = MgmtData::getChildrenOfClass($xml); $other = self::getChildElementsFromXML($xml); @@ -47,7 +47,7 @@ public static function fromXML(DOMElement $xml): static $keyValue, $retrievalMethod, $x509Data, - //$pgpData, + $pgpData, //$spkiData, $mgmtData, $other, diff --git a/src/XML/ds/PGPData.php b/src/XML/ds/PGPData.php new file mode 100644 index 00000000..f8a2c3b9 --- /dev/null +++ b/src/XML/ds/PGPData.php @@ -0,0 +1,14 @@ + '\SimpleSAML\XMLSecurity\XML\ds\Manifest', 'MgmtData' => '\SimpleSAML\XMLSecurity\XML\ds\MgmtData', 'Object' => '\SimpleSAML\XMLSecurity\XML\ds\DsObject', -// 'PGPData' => '\SimpleSAML\XMLSecurity\XML\ds\PGPData', + 'PGPData' => '\SimpleSAML\XMLSecurity\XML\ds\PGPData', 'Reference' => '\SimpleSAML\XMLSecurity\XML\ds\Reference', 'RetrievalMethod' => '\SimpleSAML\XMLSecurity\XML\ds\RetrievalMethod', 'RSAKeyValue' => '\SimpleSAML\XMLSecurity\XML\ds\RSAKeyValue', diff --git a/src/XML/xenc/OriginatorKeyInfo.php b/src/XML/xenc/OriginatorKeyInfo.php index 2aba0d3e..413d9e19 100644 --- a/src/XML/xenc/OriginatorKeyInfo.php +++ b/src/XML/xenc/OriginatorKeyInfo.php @@ -12,6 +12,7 @@ use SimpleSAML\XMLSecurity\XML\ds\KeyName; use SimpleSAML\XMLSecurity\XML\ds\KeyValue; use SimpleSAML\XMLSecurity\XML\ds\MgmtData; +use SimpleSAML\XMLSecurity\XML\ds\PGPData; use SimpleSAML\XMLSecurity\XML\ds\RetrievalMethod; use SimpleSAML\XMLSecurity\XML\ds\X509Data; @@ -51,7 +52,7 @@ public static function fromXML(DOMElement $xml): static $keyValue = KeyValue::getChildrenOfClass($xml); $retrievalMethod = RetrievalMethod::getChildrenOfClass($xml); $x509Data = X509Data::getChildrenOfClass($xml); - //$pgpData = PGPData::getChildrenOfClass($xml); + $pgpData = PGPData::getChildrenOfClass($xml); //$spkiData = SPKIData::getChildrenOfClass($xml); $mgmtData = MgmtData::getChildrenOfClass($xml); $other = self::getChildElementsFromXML($xml); @@ -61,7 +62,7 @@ public static function fromXML(DOMElement $xml): static $keyValue, $retrievalMethod, $x509Data, - //$pgpData, + $pgpData, //$spkiData, $mgmtData, $other, diff --git a/src/XML/xenc/RecipientKeyInfo.php b/src/XML/xenc/RecipientKeyInfo.php index 4d8d6136..e6af6857 100644 --- a/src/XML/xenc/RecipientKeyInfo.php +++ b/src/XML/xenc/RecipientKeyInfo.php @@ -12,6 +12,7 @@ use SimpleSAML\XMLSecurity\XML\ds\KeyName; use SimpleSAML\XMLSecurity\XML\ds\KeyValue; use SimpleSAML\XMLSecurity\XML\ds\MgmtData; +use SimpleSAML\XMLSecurity\XML\ds\PGPData; use SimpleSAML\XMLSecurity\XML\ds\RetrievalMethod; use SimpleSAML\XMLSecurity\XML\ds\X509Data; @@ -51,7 +52,7 @@ public static function fromXML(DOMElement $xml): static $keyValue = KeyValue::getChildrenOfClass($xml); $retrievalMethod = RetrievalMethod::getChildrenOfClass($xml); $x509Data = X509Data::getChildrenOfClass($xml); - //$pgpData = PGPData::getChildrenOfClass($xml); + $pgpData = PGPData::getChildrenOfClass($xml); //$spkiData = SPKIData::getChildrenOfClass($xml); $mgmtData = MgmtData::getChildrenOfClass($xml); $other = self::getChildElementsFromXML($xml); @@ -61,7 +62,7 @@ public static function fromXML(DOMElement $xml): static $keyValue, $retrievalMethod, $x509Data, - //$pgpData, + $pgpData, //$spkiData, $mgmtData, $other, diff --git a/tests/XML/ds/KeyInfoTest.php b/tests/XML/ds/KeyInfoTest.php index 44e25513..1ba1c1a2 100644 --- a/tests/XML/ds/KeyInfoTest.php +++ b/tests/XML/ds/KeyInfoTest.php @@ -16,9 +16,13 @@ use SimpleSAML\XMLSecurity\XML\ds\AbstractKeyInfoType; use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; use SimpleSAML\XMLSecurity\XML\ds\KeyName; +use SimpleSAML\XMLSecurity\XML\ds\PGPData; +use SimpleSAML\XMLSecurity\XML\ds\PGPKeyID; +use SimpleSAML\XMLSecurity\XML\ds\PGPKeyPacket; use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; use SimpleSAML\XMLSecurity\XML\ds\X509Data; use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\xenc\P; use function dirname; use function openssl_x509_parse; @@ -96,6 +100,11 @@ public function testMarshalling(): void new X509SubjectName(self::$certData['name']), ], ), + new PGPData( + new PGPKeyID('GpM7'), + new PGPKeyPacket('GpM8'), + [new P('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI=')], + ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), diff --git a/tests/XML/ds/PGPDataTest.php b/tests/XML/ds/PGPDataTest.php new file mode 100644 index 00000000..cc56a803 --- /dev/null +++ b/tests/XML/ds/PGPDataTest.php @@ -0,0 +1,95 @@ +assertEquals( + self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), + strval($pgpData), + ); + } + + + /** + */ + public function testMarshallingBothIdAndPacketNullThrowsException(): void + { + $this->expectException(SchemaViolationException::class); + + new PGPData(null, null, []); + } + + + /** + */ + public function testMarshallingReferenceElementOrdering(): void + { + $pgpKeyId = new PGPKeyID('GpM7'); + $pgpKeyPacket = new PGPKeyPacket('GpM8'); + $p = new P('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI='); + + $pgpData = new PGPData($pgpKeyId, $pgpKeyPacket, [$p]); + + $pgpDataElement = $pgpData->toXML(); + /** @var \DOMElement[] $children */ + $children = $pgpDataElement->childNodes; + + $this->assertEquals('ds:PGPKeyID', $children[0]->tagName); + $this->assertEquals('ds:PGPKeyPacket', $children[1]->tagName); + $this->assertEquals('xenc:P', $children[2]->tagName); + } +} diff --git a/tests/XML/xenc/OriginatorKeyInfoTest.php b/tests/XML/xenc/OriginatorKeyInfoTest.php index 69522d79..947f9d61 100644 --- a/tests/XML/xenc/OriginatorKeyInfoTest.php +++ b/tests/XML/xenc/OriginatorKeyInfoTest.php @@ -14,10 +14,14 @@ use SimpleSAML\XMLSecurity\XML\ds\AbstractDsElement; use SimpleSAML\XMLSecurity\XML\ds\AbstractKeyInfoType; use SimpleSAML\XMLSecurity\XML\ds\KeyName; +use SimpleSAML\XMLSecurity\XML\ds\PGPData; +use SimpleSAML\XMLSecurity\XML\ds\PGPKeyID; +use SimpleSAML\XMLSecurity\XML\ds\PGPKeyPacket; use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; use SimpleSAML\XMLSecurity\XML\ds\X509Data; use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; use SimpleSAML\XMLSecurity\XML\xenc\OriginatorKeyInfo; +use SimpleSAML\XMLSecurity\XML\xenc\P; use function dirname; use function openssl_x509_parse; @@ -92,6 +96,11 @@ public function testMarshalling(): void new X509SubjectName(self::$certData['name']), ], ), + new PGPData( + new PGPKeyID('GpM7'), + new PGPKeyPacket('GpM8'), + [new P('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI=')], + ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), diff --git a/tests/XML/xenc/RecipientKeyInfoTest.php b/tests/XML/xenc/RecipientKeyInfoTest.php index 3fdce621..7197a0e0 100644 --- a/tests/XML/xenc/RecipientKeyInfoTest.php +++ b/tests/XML/xenc/RecipientKeyInfoTest.php @@ -14,9 +14,13 @@ use SimpleSAML\XMLSecurity\XML\ds\AbstractDsElement; use SimpleSAML\XMLSecurity\XML\ds\AbstractKeyInfoType; use SimpleSAML\XMLSecurity\XML\ds\KeyName; +use SimpleSAML\XMLSecurity\XML\ds\PGPData; +use SimpleSAML\XMLSecurity\XML\ds\PGPKeyID; +use SimpleSAML\XMLSecurity\XML\ds\PGPKeyPacket; use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; use SimpleSAML\XMLSecurity\XML\ds\X509Data; use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\xenc\P; use SimpleSAML\XMLSecurity\XML\xenc\RecipientKeyInfo; use function dirname; @@ -92,6 +96,11 @@ public function testMarshalling(): void new X509SubjectName(self::$certData['name']), ], ), + new PGPData( + new PGPKeyID('GpM7'), + new PGPKeyPacket('GpM8'), + [new P('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI=')], + ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), diff --git a/tests/resources/xml/ds_KeyInfo.xml b/tests/resources/xml/ds_KeyInfo.xml index 7b06e7e5..4a051ea7 100644 --- a/tests/resources/xml/ds_KeyInfo.xml +++ b/tests/resources/xml/ds_KeyInfo.xml @@ -4,5 +4,10 @@ MIICxDCCAi2gAwIBAgIUZ9QDx+SBFHednUWDFGm9tyVKrgQwDQYJKoZIhvcNAQELBQAwczElMCMGA1UEAwwcc2VsZnNpZ25lZC5zaW1wbGVzYW1scGhwLm9yZzEZMBcGA1UECgwQU2ltcGxlU0FNTHBocCBIUTERMA8GA1UEBwwISG9ub2x1bHUxDzANBgNVBAgMBkhhd2FpaTELMAkGA1UEBhMCVVMwIBcNMjIxMjAzMTAzNTQwWhgPMjEyMjExMDkxMDM1NDBaMHMxJTAjBgNVBAMMHHNlbGZzaWduZWQuc2ltcGxlc2FtbHBocC5vcmcxGTAXBgNVBAoMEFNpbXBsZVNBTUxwaHAgSFExETAPBgNVBAcMCEhvbm9sdWx1MQ8wDQYDVQQIDAZIYXdhaWkxCzAJBgNVBAYTAlVTMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDessdFRVDTMQQW3Na81B1CjJV1tmY3nopoIhZrkbDxLa+pv7jGDRcYreyu1DoQxEs06V2nHLoyOPhqJXSFivqtUwVYhR6NYgbNI6RRSsIJCweH0YOdlHna7gULPcLX0Bfbi4odStaFwG9yzDySwSEPtsKxm5pENPjNVGh+jJ+H/QIDAQABo1MwUTAdBgNVHQ4EFgQUvV75t8EoQo2fVa0E9otdtIGK5X0wHwYDVR0jBBgwFoAUvV75t8EoQo2fVa0E9otdtIGK5X0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQANQUeiwPJXkWMXuaDHToEBKcezYGqGEYnGUi9LMjeb+Kln7X8nn5iknlz4k77rWCbSwLPC/WDr0ySYQA+HagaeUaFpoiYFJKS6uFlK1HYWnM3W4PUiGHg1/xeZlMO44wTwybXVo0y9KMhchfB5XNbDdoJcqWYvi6xtmZZNRbxUyw== /CN=selfsigned.simplesamlphp.org/O=SimpleSAMLphp HQ/L=Honolulu/ST=Hawaii/C=US + + GpM7 + GpM8 + /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + some diff --git a/tests/resources/xml/ds_PGPData.xml b/tests/resources/xml/ds_PGPData.xml new file mode 100644 index 00000000..bde1884e --- /dev/null +++ b/tests/resources/xml/ds_PGPData.xml @@ -0,0 +1,5 @@ + + GpM7 + GpM8 + /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + diff --git a/tests/resources/xml/ds_Signature.xml b/tests/resources/xml/ds_Signature.xml index 1081fb30..66b7595f 100644 --- a/tests/resources/xml/ds_Signature.xml +++ b/tests/resources/xml/ds_Signature.xml @@ -18,6 +18,11 @@ MIICxDCCAi2gAwIBAgIUZ9QDx+SBFHednUWDFGm9tyVKrgQwDQYJKoZIhvcNAQELBQAwczElMCMGA1UEAwwcc2VsZnNpZ25lZC5zaW1wbGVzYW1scGhwLm9yZzEZMBcGA1UECgwQU2ltcGxlU0FNTHBocCBIUTERMA8GA1UEBwwISG9ub2x1bHUxDzANBgNVBAgMBkhhd2FpaTELMAkGA1UEBhMCVVMwIBcNMjIxMjAzMTAzNTQwWhgPMjEyMjExMDkxMDM1NDBaMHMxJTAjBgNVBAMMHHNlbGZzaWduZWQuc2ltcGxlc2FtbHBocC5vcmcxGTAXBgNVBAoMEFNpbXBsZVNBTUxwaHAgSFExETAPBgNVBAcMCEhvbm9sdWx1MQ8wDQYDVQQIDAZIYXdhaWkxCzAJBgNVBAYTAlVTMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDessdFRVDTMQQW3Na81B1CjJV1tmY3nopoIhZrkbDxLa+pv7jGDRcYreyu1DoQxEs06V2nHLoyOPhqJXSFivqtUwVYhR6NYgbNI6RRSsIJCweH0YOdlHna7gULPcLX0Bfbi4odStaFwG9yzDySwSEPtsKxm5pENPjNVGh+jJ+H/QIDAQABo1MwUTAdBgNVHQ4EFgQUvV75t8EoQo2fVa0E9otdtIGK5X0wHwYDVR0jBBgwFoAUvV75t8EoQo2fVa0E9otdtIGK5X0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQANQUeiwPJXkWMXuaDHToEBKcezYGqGEYnGUi9LMjeb+Kln7X8nn5iknlz4k77rWCbSwLPC/WDr0ySYQA+HagaeUaFpoiYFJKS6uFlK1HYWnM3W4PUiGHg1/xeZlMO44wTwybXVo0y9KMhchfB5XNbDdoJcqWYvi6xtmZZNRbxUyw== /CN=selfsigned.simplesamlphp.org/O=SimpleSAMLphp HQ/L=Honolulu/ST=Hawaii/C=US + + GpM7 + GpM8 + /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + some diff --git a/tests/resources/xml/xenc_OriginatorKeyInfo.xml b/tests/resources/xml/xenc_OriginatorKeyInfo.xml index 080836d0..121f7edf 100644 --- a/tests/resources/xml/xenc_OriginatorKeyInfo.xml +++ b/tests/resources/xml/xenc_OriginatorKeyInfo.xml @@ -4,5 +4,10 @@ MIICxDCCAi2gAwIBAgIUZ9QDx+SBFHednUWDFGm9tyVKrgQwDQYJKoZIhvcNAQELBQAwczElMCMGA1UEAwwcc2VsZnNpZ25lZC5zaW1wbGVzYW1scGhwLm9yZzEZMBcGA1UECgwQU2ltcGxlU0FNTHBocCBIUTERMA8GA1UEBwwISG9ub2x1bHUxDzANBgNVBAgMBkhhd2FpaTELMAkGA1UEBhMCVVMwIBcNMjIxMjAzMTAzNTQwWhgPMjEyMjExMDkxMDM1NDBaMHMxJTAjBgNVBAMMHHNlbGZzaWduZWQuc2ltcGxlc2FtbHBocC5vcmcxGTAXBgNVBAoMEFNpbXBsZVNBTUxwaHAgSFExETAPBgNVBAcMCEhvbm9sdWx1MQ8wDQYDVQQIDAZIYXdhaWkxCzAJBgNVBAYTAlVTMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDessdFRVDTMQQW3Na81B1CjJV1tmY3nopoIhZrkbDxLa+pv7jGDRcYreyu1DoQxEs06V2nHLoyOPhqJXSFivqtUwVYhR6NYgbNI6RRSsIJCweH0YOdlHna7gULPcLX0Bfbi4odStaFwG9yzDySwSEPtsKxm5pENPjNVGh+jJ+H/QIDAQABo1MwUTAdBgNVHQ4EFgQUvV75t8EoQo2fVa0E9otdtIGK5X0wHwYDVR0jBBgwFoAUvV75t8EoQo2fVa0E9otdtIGK5X0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQANQUeiwPJXkWMXuaDHToEBKcezYGqGEYnGUi9LMjeb+Kln7X8nn5iknlz4k77rWCbSwLPC/WDr0ySYQA+HagaeUaFpoiYFJKS6uFlK1HYWnM3W4PUiGHg1/xeZlMO44wTwybXVo0y9KMhchfB5XNbDdoJcqWYvi6xtmZZNRbxUyw== /CN=selfsigned.simplesamlphp.org/O=SimpleSAMLphp HQ/L=Honolulu/ST=Hawaii/C=US + + GpM7 + GpM8 + /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + some diff --git a/tests/resources/xml/xenc_RecipientKeyInfo.xml b/tests/resources/xml/xenc_RecipientKeyInfo.xml index bee00ede..36a43030 100644 --- a/tests/resources/xml/xenc_RecipientKeyInfo.xml +++ b/tests/resources/xml/xenc_RecipientKeyInfo.xml @@ -4,5 +4,10 @@ MIICxDCCAi2gAwIBAgIUZ9QDx+SBFHednUWDFGm9tyVKrgQwDQYJKoZIhvcNAQELBQAwczElMCMGA1UEAwwcc2VsZnNpZ25lZC5zaW1wbGVzYW1scGhwLm9yZzEZMBcGA1UECgwQU2ltcGxlU0FNTHBocCBIUTERMA8GA1UEBwwISG9ub2x1bHUxDzANBgNVBAgMBkhhd2FpaTELMAkGA1UEBhMCVVMwIBcNMjIxMjAzMTAzNTQwWhgPMjEyMjExMDkxMDM1NDBaMHMxJTAjBgNVBAMMHHNlbGZzaWduZWQuc2ltcGxlc2FtbHBocC5vcmcxGTAXBgNVBAoMEFNpbXBsZVNBTUxwaHAgSFExETAPBgNVBAcMCEhvbm9sdWx1MQ8wDQYDVQQIDAZIYXdhaWkxCzAJBgNVBAYTAlVTMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDessdFRVDTMQQW3Na81B1CjJV1tmY3nopoIhZrkbDxLa+pv7jGDRcYreyu1DoQxEs06V2nHLoyOPhqJXSFivqtUwVYhR6NYgbNI6RRSsIJCweH0YOdlHna7gULPcLX0Bfbi4odStaFwG9yzDySwSEPtsKxm5pENPjNVGh+jJ+H/QIDAQABo1MwUTAdBgNVHQ4EFgQUvV75t8EoQo2fVa0E9otdtIGK5X0wHwYDVR0jBBgwFoAUvV75t8EoQo2fVa0E9otdtIGK5X0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQANQUeiwPJXkWMXuaDHToEBKcezYGqGEYnGUi9LMjeb+Kln7X8nn5iknlz4k77rWCbSwLPC/WDr0ySYQA+HagaeUaFpoiYFJKS6uFlK1HYWnM3W4PUiGHg1/xeZlMO44wTwybXVo0y9KMhchfB5XNbDdoJcqWYvi6xtmZZNRbxUyw== /CN=selfsigned.simplesamlphp.org/O=SimpleSAMLphp HQ/L=Honolulu/ST=Hawaii/C=US + + GpM7 + GpM8 + /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + some From 55defa230a158528ffaa8932bcc34193a36dfc63 Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Sat, 30 Nov 2024 16:39:25 +0100 Subject: [PATCH 09/15] Add ds:MgmtData element --- src/XML/ds/AbstractKeyInfoType.php | 11 ++++++++++- tests/XML/ds/KeyInfoTest.php | 2 ++ tests/XML/xenc/OriginatorKeyInfoTest.php | 2 ++ tests/XML/xenc/RecipientKeyInfoTest.php | 2 ++ tests/resources/xml/ds_KeyInfo.xml | 1 + tests/resources/xml/ds_Signature.xml | 1 + tests/resources/xml/xenc_OriginatorKeyInfo.xml | 1 + tests/resources/xml/xenc_RecipientKeyInfo.xml | 1 + 8 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/XML/ds/AbstractKeyInfoType.php b/src/XML/ds/AbstractKeyInfoType.php index 3753e670..1a227ea2 100644 --- a/src/XML/ds/AbstractKeyInfoType.php +++ b/src/XML/ds/AbstractKeyInfoType.php @@ -36,6 +36,7 @@ abstract class AbstractKeyInfoType extends AbstractDsElement * \SimpleSAML\XMLSecurity\XML\ds\RetrievalMethod| * \SimpleSAML\XMLSecurity\XML\ds\X509Data| * \SimpleSAML\XMLSecurity\XML\ds\PGPData| + * \SimpleSAML\XMLSecurity\XML\ds\MgmtData| * \SimpleSAML\XML\SerializableElementInterface * )[] $info * @param string|null $Id @@ -65,7 +66,15 @@ final public function __construct( if ($item instanceof AbstractDsElement) { Assert::isInstanceOfAny( $item, - [KeyName::class, KeyValue::class, RetrievalMethod::class, X509Data::class, PGPData::class], + [ + KeyName::class, + KeyValue::class, + RetrievalMethod::class, + X509Data::class, + PGPData::class, + // SPKIData::class, + MgmtData::class, + ], SchemaViolationException::class, ); } diff --git a/tests/XML/ds/KeyInfoTest.php b/tests/XML/ds/KeyInfoTest.php index 1ba1c1a2..d0cc384b 100644 --- a/tests/XML/ds/KeyInfoTest.php +++ b/tests/XML/ds/KeyInfoTest.php @@ -16,6 +16,7 @@ use SimpleSAML\XMLSecurity\XML\ds\AbstractKeyInfoType; use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; use SimpleSAML\XMLSecurity\XML\ds\KeyName; +use SimpleSAML\XMLSecurity\XML\ds\MgmtData; use SimpleSAML\XMLSecurity\XML\ds\PGPData; use SimpleSAML\XMLSecurity\XML\ds\PGPKeyID; use SimpleSAML\XMLSecurity\XML\ds\PGPKeyPacket; @@ -105,6 +106,7 @@ public function testMarshalling(): void new PGPKeyPacket('GpM8'), [new P('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI=')], ), + new MgmtData('ManagementData'), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), diff --git a/tests/XML/xenc/OriginatorKeyInfoTest.php b/tests/XML/xenc/OriginatorKeyInfoTest.php index 947f9d61..8b78e00c 100644 --- a/tests/XML/xenc/OriginatorKeyInfoTest.php +++ b/tests/XML/xenc/OriginatorKeyInfoTest.php @@ -14,6 +14,7 @@ use SimpleSAML\XMLSecurity\XML\ds\AbstractDsElement; use SimpleSAML\XMLSecurity\XML\ds\AbstractKeyInfoType; use SimpleSAML\XMLSecurity\XML\ds\KeyName; +use SimpleSAML\XMLSecurity\XML\ds\MgmtData; use SimpleSAML\XMLSecurity\XML\ds\PGPData; use SimpleSAML\XMLSecurity\XML\ds\PGPKeyID; use SimpleSAML\XMLSecurity\XML\ds\PGPKeyPacket; @@ -101,6 +102,7 @@ public function testMarshalling(): void new PGPKeyPacket('GpM8'), [new P('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI=')], ), + new MgmtData('ManagementData'), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), diff --git a/tests/XML/xenc/RecipientKeyInfoTest.php b/tests/XML/xenc/RecipientKeyInfoTest.php index 7197a0e0..e59658ea 100644 --- a/tests/XML/xenc/RecipientKeyInfoTest.php +++ b/tests/XML/xenc/RecipientKeyInfoTest.php @@ -14,6 +14,7 @@ use SimpleSAML\XMLSecurity\XML\ds\AbstractDsElement; use SimpleSAML\XMLSecurity\XML\ds\AbstractKeyInfoType; use SimpleSAML\XMLSecurity\XML\ds\KeyName; +use SimpleSAML\XMLSecurity\XML\ds\MgmtData; use SimpleSAML\XMLSecurity\XML\ds\PGPData; use SimpleSAML\XMLSecurity\XML\ds\PGPKeyID; use SimpleSAML\XMLSecurity\XML\ds\PGPKeyPacket; @@ -101,6 +102,7 @@ public function testMarshalling(): void new PGPKeyPacket('GpM8'), [new P('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI=')], ), + new MgmtData('ManagementData'), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), diff --git a/tests/resources/xml/ds_KeyInfo.xml b/tests/resources/xml/ds_KeyInfo.xml index 4a051ea7..ed6730e4 100644 --- a/tests/resources/xml/ds_KeyInfo.xml +++ b/tests/resources/xml/ds_KeyInfo.xml @@ -9,5 +9,6 @@ GpM8 /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + ManagementData some diff --git a/tests/resources/xml/ds_Signature.xml b/tests/resources/xml/ds_Signature.xml index 66b7595f..9e23abb8 100644 --- a/tests/resources/xml/ds_Signature.xml +++ b/tests/resources/xml/ds_Signature.xml @@ -23,6 +23,7 @@ GpM8 /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + ManagementData some diff --git a/tests/resources/xml/xenc_OriginatorKeyInfo.xml b/tests/resources/xml/xenc_OriginatorKeyInfo.xml index 121f7edf..4472feab 100644 --- a/tests/resources/xml/xenc_OriginatorKeyInfo.xml +++ b/tests/resources/xml/xenc_OriginatorKeyInfo.xml @@ -9,5 +9,6 @@ GpM8 /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + ManagementData some diff --git a/tests/resources/xml/xenc_RecipientKeyInfo.xml b/tests/resources/xml/xenc_RecipientKeyInfo.xml index 36a43030..4dcff148 100644 --- a/tests/resources/xml/xenc_RecipientKeyInfo.xml +++ b/tests/resources/xml/xenc_RecipientKeyInfo.xml @@ -9,5 +9,6 @@ GpM8 /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + ManagementData some From e2b2b0cf464b7f98f7121b71b0071595241b7063 Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Sat, 30 Nov 2024 19:12:32 +0100 Subject: [PATCH 10/15] Raise coverage --- src/XML/ds/X509Data.php | 24 ++++++++++++++---------- tests/XML/ds/ReferenceTest.php | 1 + 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/XML/ds/X509Data.php b/src/XML/ds/X509Data.php index b9c68947..6d7a8e74 100644 --- a/src/XML/ds/X509Data.php +++ b/src/XML/ds/X509Data.php @@ -7,8 +7,8 @@ use DOMElement; use SimpleSAML\Assert\Assert; use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\Constants as C; use SimpleSAML\XML\Exception\InvalidDOMElementException; +use SimpleSAML\XMLSecurity\Constants as C; use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException; use SimpleSAML\XMLSecurity\XML\dsig11\X509Digest; @@ -74,18 +74,22 @@ public static function fromXML(DOMElement $xml): static for ($n = $xml->firstChild; $n !== null; $n = $n->nextSibling) { if (!($n instanceof DOMElement)) { continue; - } elseif ($n->namespaceURI !== self::NS) { + } elseif ($n->namespaceURI === self::NS) { + $data[] = match ($n->localName) { + 'X509Certificate' => X509Certificate::fromXML($n), + 'X509IssuerSerial' => X509IssuerSerial::fromXML($n), + 'X509SubjectName' => X509SubjectName::fromXML($n), + default => new Chunk($n), + }; + } elseif ($n->namespaceURI === C::NS_XDSIG11) { + $data[] = match ($n->localName) { + 'X509Digest' => X509Digest::fromXML($n), + default => new Chunk($n), + }; + } else { $data[] = new Chunk($n); continue; } - - $data[] = match ($n->localName) { - 'X509Certificate' => X509Certificate::fromXML($n), - 'X509IssuerSerial' => X509IssuerSerial::fromXML($n), - 'X509SubjectName' => X509SubjectName::fromXML($n), - 'X509Digest' => X509Digest::fromXML($n), - default => new Chunk($n), - }; } return new static($data); diff --git a/tests/XML/ds/ReferenceTest.php b/tests/XML/ds/ReferenceTest.php index 610890ab..fe4b51ff 100644 --- a/tests/XML/ds/ReferenceTest.php +++ b/tests/XML/ds/ReferenceTest.php @@ -64,6 +64,7 @@ public function testMarshalling(): void '#_1e280ee704fb1d8d9dec4bd6c1889ec96942921153', ); + $this->assertFalse($reference->isXPointer()); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), strval($reference), From 47ff576fad7c213e895d40aace56e423e645dc6f Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Sat, 30 Nov 2024 21:31:10 +0100 Subject: [PATCH 11/15] Add ds:SPKISexp element --- src/XML/ds/SPKISexp.php | 26 +++++++++++++++ tests/XML/ds/SPKISexpTest.php | 51 +++++++++++++++++++++++++++++ tests/resources/xml/ds_SPKISexp.xml | 1 + 3 files changed, 78 insertions(+) create mode 100644 src/XML/ds/SPKISexp.php create mode 100644 tests/XML/ds/SPKISexpTest.php create mode 100644 tests/resources/xml/ds_SPKISexp.xml diff --git a/src/XML/ds/SPKISexp.php b/src/XML/ds/SPKISexp.php new file mode 100644 index 00000000..1ca50c4a --- /dev/null +++ b/src/XML/ds/SPKISexp.php @@ -0,0 +1,26 @@ +setContent($content); + } +} diff --git a/tests/XML/ds/SPKISexpTest.php b/tests/XML/ds/SPKISexpTest.php new file mode 100644 index 00000000..a3b32b6c --- /dev/null +++ b/tests/XML/ds/SPKISexpTest.php @@ -0,0 +1,51 @@ +assertEquals( + self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), + strval($SPKISexp), + ); + } +} diff --git a/tests/resources/xml/ds_SPKISexp.xml b/tests/resources/xml/ds_SPKISexp.xml new file mode 100644 index 00000000..280259b5 --- /dev/null +++ b/tests/resources/xml/ds_SPKISexp.xml @@ -0,0 +1 @@ +GpM6 From b5fed62f0d82acbb12c8ebfb9dea5d2a16345dd1 Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Mon, 2 Dec 2024 00:27:26 +0100 Subject: [PATCH 12/15] Add ds:SPKIData element --- src/XML/ds/AbstractKeyInfoType.php | 3 +- src/XML/ds/AbstractSPKIDataType.php | 115 ++++++++++++++++++ src/XML/ds/KeyInfo.php | 4 +- src/XML/ds/SPKIData.php | 14 +++ src/XML/xenc/OriginatorKeyInfo.php | 5 +- src/XML/xenc/RecipientKeyInfo.php | 5 +- tests/XML/ds/KeyInfoTest.php | 15 +++ tests/XML/ds/SPKIDataTest.php | 70 +++++++++++ tests/XML/xenc/OriginatorKeyInfoTest.php | 15 +++ tests/XML/xenc/RecipientKeyInfoTest.php | 15 +++ tests/resources/xml/ds_KeyInfo.xml | 7 ++ tests/resources/xml/ds_SPKIData.xml | 7 ++ tests/resources/xml/ds_Signature.xml | 7 ++ .../resources/xml/xenc_OriginatorKeyInfo.xml | 7 ++ tests/resources/xml/xenc_RecipientKeyInfo.xml | 7 ++ 15 files changed, 289 insertions(+), 7 deletions(-) create mode 100644 src/XML/ds/AbstractSPKIDataType.php create mode 100644 src/XML/ds/SPKIData.php create mode 100644 tests/XML/ds/SPKIDataTest.php create mode 100644 tests/resources/xml/ds_SPKIData.xml diff --git a/src/XML/ds/AbstractKeyInfoType.php b/src/XML/ds/AbstractKeyInfoType.php index 1a227ea2..09836f44 100644 --- a/src/XML/ds/AbstractKeyInfoType.php +++ b/src/XML/ds/AbstractKeyInfoType.php @@ -36,6 +36,7 @@ abstract class AbstractKeyInfoType extends AbstractDsElement * \SimpleSAML\XMLSecurity\XML\ds\RetrievalMethod| * \SimpleSAML\XMLSecurity\XML\ds\X509Data| * \SimpleSAML\XMLSecurity\XML\ds\PGPData| + * \SimpleSAML\XMLSecurity\XML\ds\SPKIData| * \SimpleSAML\XMLSecurity\XML\ds\MgmtData| * \SimpleSAML\XML\SerializableElementInterface * )[] $info @@ -72,7 +73,7 @@ final public function __construct( RetrievalMethod::class, X509Data::class, PGPData::class, - // SPKIData::class, + SPKIData::class, MgmtData::class, ], SchemaViolationException::class, diff --git a/src/XML/ds/AbstractSPKIDataType.php b/src/XML/ds/AbstractSPKIDataType.php new file mode 100644 index 00000000..6c5a961b --- /dev/null +++ b/src/XML/ds/AbstractSPKIDataType.php @@ -0,0 +1,115 @@ + $tuples + */ + final public function __construct( + protected array $tuples, + ) { + Assert::allIsArray($tuples, SchemaViolationException::class); + Assert::allCount($tuples, 2); + + foreach ($tuples as $tuple) { + list($spkisExp, $other) = $tuple; + Assert::isInstanceOf($spkisExp, SPKISexp::class, SchemaViolationException::class); + Assert::nullOrIsInstanceOf($other, SerializableElementInterface::class, SchemaViolationException::class); + } + } + + + /** + * Collect the value of the SPKISexp-property + * + * @return array<\SimpleSAML\XMLSecurity\XML\ds\SPKISexp, SimpleSAML\XML\SerializableElementInterface|null> + */ + public function getTuples(): array + { + return $this->tuples; + } + + + /** + * Convert XML into a SPKIData + * + * @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); + + $registry = ElementRegistry::getInstance(); + $tuples = []; + $tuple = [null, null]; + foreach ($xml->childNodes as $node) { + if ($node instanceof DOMElement) { + if ($node->namespaceURI === static::NS && $node->localName === 'SPKISexp') { + if ($tuple[0] !== null) { + $tuples[] = $tuple; + } + $tuple = [SPKISexp::fromXML($node), null]; + } elseif ($node->namespaceURI !== static::NS && $tuple[0] !== null) { + $handler = $registry->getElementHandler($node->namespaceURI, $node->localName); + $tuple[1] = ($handler === null) ? Chunk::fromXML($node) : $handler::fromXML($node); + $tuples[] = $tuple; + $tuple = [null, null]; + } + } + } + + if ($tuple[0] !== null) { + $tuples[] = $tuple; + } + + return new static($tuples); + } + + + /** + * Convert this SPKIData to XML. + * + * @param \DOMElement|null $parent The element we should append this SPKIData to. + * @return \DOMElement + */ + public function toXML(?DOMElement $parent = null): DOMElement + { + $e = $this->instantiateParentElement($parent); + + foreach ($this->getTuples() as $tuple) { + list($spkisExp, $other) = $tuple; + + $spkisExp->toXML($e); + $other?->toXML($e); + } + + return $e; + } +} diff --git a/src/XML/ds/KeyInfo.php b/src/XML/ds/KeyInfo.php index 59cd4fce..ae5d5a27 100644 --- a/src/XML/ds/KeyInfo.php +++ b/src/XML/ds/KeyInfo.php @@ -38,7 +38,7 @@ public static function fromXML(DOMElement $xml): static $retrievalMethod = RetrievalMethod::getChildrenOfClass($xml); $x509Data = X509Data::getChildrenOfClass($xml); $pgpData = PGPData::getChildrenOfClass($xml); - //$spkiData = SPKIData::getChildrenOfClass($xml); + $spkiData = SPKIData::getChildrenOfClass($xml); $mgmtData = MgmtData::getChildrenOfClass($xml); $other = self::getChildElementsFromXML($xml); @@ -48,7 +48,7 @@ public static function fromXML(DOMElement $xml): static $retrievalMethod, $x509Data, $pgpData, - //$spkiData, + $spkiData, $mgmtData, $other, ); diff --git a/src/XML/ds/SPKIData.php b/src/XML/ds/SPKIData.php new file mode 100644 index 00000000..c73e82a7 --- /dev/null +++ b/src/XML/ds/SPKIData.php @@ -0,0 +1,14 @@ +some', diff --git a/tests/XML/ds/SPKIDataTest.php b/tests/XML/ds/SPKIDataTest.php new file mode 100644 index 00000000..b07f0a74 --- /dev/null +++ b/tests/XML/ds/SPKIDataTest.php @@ -0,0 +1,70 @@ +assertEquals( + self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), + strval($SPKIData), + ); + } +} diff --git a/tests/XML/xenc/OriginatorKeyInfoTest.php b/tests/XML/xenc/OriginatorKeyInfoTest.php index 8b78e00c..7a4a70db 100644 --- a/tests/XML/xenc/OriginatorKeyInfoTest.php +++ b/tests/XML/xenc/OriginatorKeyInfoTest.php @@ -18,11 +18,15 @@ use SimpleSAML\XMLSecurity\XML\ds\PGPData; use SimpleSAML\XMLSecurity\XML\ds\PGPKeyID; use SimpleSAML\XMLSecurity\XML\ds\PGPKeyPacket; +use SimpleSAML\XMLSecurity\XML\ds\SPKIData; +use SimpleSAML\XMLSecurity\XML\ds\SPKISexp; use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; use SimpleSAML\XMLSecurity\XML\ds\X509Data; use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\xenc\CarriedKeyName; use SimpleSAML\XMLSecurity\XML\xenc\OriginatorKeyInfo; use SimpleSAML\XMLSecurity\XML\xenc\P; +use SimpleSAML\XMLSecurity\XML\xenc\Seed; use function dirname; use function openssl_x509_parse; @@ -88,6 +92,12 @@ public function setUp(): void */ public function testMarshalling(): void { + $SPKISexp1 = new SPKISexp('GpM6'); + $seed = new Seed('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI='); + $SPKISexp2 = new SPKISexp('GpM7'); + $SPKISexp3 = new SPKISexp('GpM8'); + $carriedKeyName = new CarriedKeyName('Some label'); + $originatorKeyInfo = new OriginatorKeyInfo( [ new KeyName('testkey'), @@ -102,6 +112,11 @@ public function testMarshalling(): void new PGPKeyPacket('GpM8'), [new P('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI=')], ), + new SPKIData([ + [$SPKISexp1, $seed], + [$SPKISexp2, null], + [$SPKISexp3, $carriedKeyName], + ]), new MgmtData('ManagementData'), new Chunk(DOMDocumentFactory::fromString( 'some', diff --git a/tests/XML/xenc/RecipientKeyInfoTest.php b/tests/XML/xenc/RecipientKeyInfoTest.php index e59658ea..55cf2ba3 100644 --- a/tests/XML/xenc/RecipientKeyInfoTest.php +++ b/tests/XML/xenc/RecipientKeyInfoTest.php @@ -18,11 +18,15 @@ use SimpleSAML\XMLSecurity\XML\ds\PGPData; use SimpleSAML\XMLSecurity\XML\ds\PGPKeyID; use SimpleSAML\XMLSecurity\XML\ds\PGPKeyPacket; +use SimpleSAML\XMLSecurity\XML\ds\SPKIData; +use SimpleSAML\XMLSecurity\XML\ds\SPKISexp; use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; use SimpleSAML\XMLSecurity\XML\ds\X509Data; use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\xenc\CarriedKeyName; use SimpleSAML\XMLSecurity\XML\xenc\P; use SimpleSAML\XMLSecurity\XML\xenc\RecipientKeyInfo; +use SimpleSAML\XMLSecurity\XML\xenc\Seed; use function dirname; use function openssl_x509_parse; @@ -88,6 +92,12 @@ public function setUp(): void */ public function testMarshalling(): void { + $SPKISexp1 = new SPKISexp('GpM6'); + $seed = new Seed('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI='); + $SPKISexp2 = new SPKISexp('GpM7'); + $SPKISexp3 = new SPKISexp('GpM8'); + $carriedKeyName = new CarriedKeyName('Some label'); + $recipientKeyInfo = new RecipientKeyInfo( [ new KeyName('testkey'), @@ -102,6 +112,11 @@ public function testMarshalling(): void new PGPKeyPacket('GpM8'), [new P('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI=')], ), + new SPKIData([ + [$SPKISexp1, $seed], + [$SPKISexp2, null], + [$SPKISexp3, $carriedKeyName], + ]), new MgmtData('ManagementData'), new Chunk(DOMDocumentFactory::fromString( 'some', diff --git a/tests/resources/xml/ds_KeyInfo.xml b/tests/resources/xml/ds_KeyInfo.xml index ed6730e4..1fa0b62b 100644 --- a/tests/resources/xml/ds_KeyInfo.xml +++ b/tests/resources/xml/ds_KeyInfo.xml @@ -9,6 +9,13 @@ GpM8 /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + + GpM6 + /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + GpM7 + GpM8 + Some label + ManagementData some diff --git a/tests/resources/xml/ds_SPKIData.xml b/tests/resources/xml/ds_SPKIData.xml new file mode 100644 index 00000000..ef4af6ca --- /dev/null +++ b/tests/resources/xml/ds_SPKIData.xml @@ -0,0 +1,7 @@ + + GpM6 + /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + GpM7 + GpM8 + Some label + diff --git a/tests/resources/xml/ds_Signature.xml b/tests/resources/xml/ds_Signature.xml index 9e23abb8..7b65c1c1 100644 --- a/tests/resources/xml/ds_Signature.xml +++ b/tests/resources/xml/ds_Signature.xml @@ -23,6 +23,13 @@ GpM8 /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + + GpM6 + /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + GpM7 + GpM8 + Some label + ManagementData some diff --git a/tests/resources/xml/xenc_OriginatorKeyInfo.xml b/tests/resources/xml/xenc_OriginatorKeyInfo.xml index 4472feab..720eaa1b 100644 --- a/tests/resources/xml/xenc_OriginatorKeyInfo.xml +++ b/tests/resources/xml/xenc_OriginatorKeyInfo.xml @@ -9,6 +9,13 @@ GpM8 /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + + GpM6 + /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + GpM7 + GpM8 + Some label + ManagementData some diff --git a/tests/resources/xml/xenc_RecipientKeyInfo.xml b/tests/resources/xml/xenc_RecipientKeyInfo.xml index 4dcff148..948b6fa4 100644 --- a/tests/resources/xml/xenc_RecipientKeyInfo.xml +++ b/tests/resources/xml/xenc_RecipientKeyInfo.xml @@ -9,6 +9,13 @@ GpM8 /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + + GpM6 + /CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI= + GpM7 + GpM8 + Some label + ManagementData some From 93ef5bcd77a94056e3c29420f13a1a1cb2158f9a Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Mon, 2 Dec 2024 00:27:26 +0100 Subject: [PATCH 13/15] Add ds:SPKIData element --- src/XML/ds/AbstractSPKIDataType.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/XML/ds/AbstractSPKIDataType.php b/src/XML/ds/AbstractSPKIDataType.php index 6c5a961b..5add02a3 100644 --- a/src/XML/ds/AbstractSPKIDataType.php +++ b/src/XML/ds/AbstractSPKIDataType.php @@ -9,10 +9,8 @@ use SimpleSAML\XML\Chunk; use SimpleSAML\XML\Exception\InvalidDOMElementException; use SimpleSAML\XML\Exception\SchemaViolationException; -use SimpleSAML\XML\Exception\TooManyElementsException; use SimpleSAML\XML\Registry\ElementRegistry; use SimpleSAML\XML\SerializableElementInterface; -use SimpleSAML\XML\XsNamespace as NS; use SimpleSAML\XMLSecurity\XML\ds\AbstractDsElement; /** From 041bb050e00f8e9eed636036cc9e7e3a777a17ac Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Tue, 3 Dec 2024 22:40:23 +0100 Subject: [PATCH 14/15] Add ds:PGPData element --- src/XML/ds/AbstractPGPDataType.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XML/ds/AbstractPGPDataType.php b/src/XML/ds/AbstractPGPDataType.php index b526fc47..081ed14c 100644 --- a/src/XML/ds/AbstractPGPDataType.php +++ b/src/XML/ds/AbstractPGPDataType.php @@ -104,7 +104,7 @@ public static function fromXML(DOMElement $xml): static * @param \DOMElement|null $parent The element we should append this PGPData to. * @return \DOMElement */ - public function toXML(DOMElement $parent = null): DOMElement + public function toXML(?DOMElement $parent = null): DOMElement { $e = $this->instantiateParentElement($parent); From 4fd66d36cf20c432935045c59089bf97182390a1 Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Tue, 3 Dec 2024 22:42:05 +0100 Subject: [PATCH 15/15] Add ds:SPKIData element --- src/XML/ds/AbstractSPKIDataType.php | 15 ++++++--------- tests/XML/ds/SPKIDataTest.php | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/XML/ds/AbstractSPKIDataType.php b/src/XML/ds/AbstractSPKIDataType.php index 5add02a3..46d3d0da 100644 --- a/src/XML/ds/AbstractSPKIDataType.php +++ b/src/XML/ds/AbstractSPKIDataType.php @@ -23,7 +23,7 @@ abstract class AbstractSPKIDataType extends AbstractDsElement /** * Initialize a SPKIData element. * - * @param array<\SimpleSAML\XMLSecurity\XML\ds\SPKISexp, SimpleSAML\XML\SerializableElementInterface|null> $tuples + * @param array{array{\SimpleSAML\XMLSecurity\XML\ds\SPKISexp, \SimpleSAML\XML\SerializableElementInterface|null}} $tuples */ final public function __construct( protected array $tuples, @@ -32,9 +32,8 @@ final public function __construct( Assert::allCount($tuples, 2); foreach ($tuples as $tuple) { - list($spkisExp, $other) = $tuple; - Assert::isInstanceOf($spkisExp, SPKISexp::class, SchemaViolationException::class); - Assert::nullOrIsInstanceOf($other, SerializableElementInterface::class, SchemaViolationException::class); + Assert::isInstanceOf($tuple[0], SPKISexp::class, SchemaViolationException::class); + Assert::nullOrIsInstanceOf($tuple[1], SerializableElementInterface::class, SchemaViolationException::class); } } @@ -42,7 +41,7 @@ final public function __construct( /** * Collect the value of the SPKISexp-property * - * @return array<\SimpleSAML\XMLSecurity\XML\ds\SPKISexp, SimpleSAML\XML\SerializableElementInterface|null> + * @return array{array{\SimpleSAML\XMLSecurity\XML\ds\SPKISexp, \SimpleSAML\XML\SerializableElementInterface|null}} */ public function getTuples(): array { @@ -102,10 +101,8 @@ public function toXML(?DOMElement $parent = null): DOMElement $e = $this->instantiateParentElement($parent); foreach ($this->getTuples() as $tuple) { - list($spkisExp, $other) = $tuple; - - $spkisExp->toXML($e); - $other?->toXML($e); + $tuple[0]->toXML($e); + $tuple[1]?->toXML($e); } return $e; diff --git a/tests/XML/ds/SPKIDataTest.php b/tests/XML/ds/SPKIDataTest.php index b07f0a74..0637897f 100644 --- a/tests/XML/ds/SPKIDataTest.php +++ b/tests/XML/ds/SPKIDataTest.php @@ -10,7 +10,7 @@ use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; use SimpleSAML\XMLSecurity\XML\ds\AbstractDsElement; -use SimpleSAML\XMLSecurity\XML\ds\AbstractSPKIData; +use SimpleSAML\XMLSecurity\XML\ds\AbstractSPKIDataType; use SimpleSAML\XMLSecurity\XML\ds\SPKIData; use SimpleSAML\XMLSecurity\XML\ds\SPKISexp; use SimpleSAML\XMLSecurity\XML\xenc\CarriedKeyName; @@ -25,7 +25,7 @@ * @package simplesamlphp/xml-security */ #[CoversClass(AbstractDsElement::class)] -#[CoversClass(AbstractSPKIData::class)] +#[CoversClass(AbstractSPKIDataType::class)] #[CoversClass(SPKIData::class)] final class SPKIDataTest extends TestCase {