From b5fed62f0d82acbb12c8ebfb9dea5d2a16345dd1 Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Mon, 2 Dec 2024 00:27:26 +0100 Subject: [PATCH] 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