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