Skip to content

Commit

Permalink
Add ds:PGPData element
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Nov 30, 2024
1 parent 6f5c6f9 commit bf9e836
Show file tree
Hide file tree
Showing 16 changed files with 292 additions and 8 deletions.
3 changes: 2 additions & 1 deletion src/XML/ds/AbstractKeyInfoType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
);
}
Expand Down
120 changes: 120 additions & 0 deletions src/XML/ds/AbstractPGPDataType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity\XML\ds;

use DOMElement;
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\XML\ds\AbstractDsElement;

use function array_pop;

/**
* Abstract class representing the PGPDataType.
*
* @package simplesamlphp/xml-security
*/
abstract class AbstractPGPDataType extends AbstractDsElement
{
use ExtendableElementTrait;

/** @var \SimpleSAML\XML\XsNamespace */
public const XS_ANY_ELT_NAMESPACE = NS::OTHER;


/**
* Initialize a PGPData element.
*
* @param \SimpleSAML\XMLSecurity\XML\ds\PGPKeyID|null $pgpKeyId
* @param \SimpleSAML\XMLSecurity\XML\ds\PGPKeyPacket|null $pgpKeyPacket
* @param array<\SimpleSAML\XML\SerializableElementInterface> $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;
}
}
4 changes: 2 additions & 2 deletions src/XML/ds/KeyInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -47,7 +47,7 @@ public static function fromXML(DOMElement $xml): static
$keyValue,
$retrievalMethod,
$x509Data,
//$pgpData,
$pgpData,
//$spkiData,
$mgmtData,
$other,
Expand Down
14 changes: 14 additions & 0 deletions src/XML/ds/PGPData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity\XML\ds;

/**
* Class representing a ds:PGPData element.
*
* @package simplesaml/xml-security
*/
final class PGPData extends AbstractPGPDataType
{
}
2 changes: 1 addition & 1 deletion src/XML/element.registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
'Manifest' => '\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',
Expand Down
5 changes: 3 additions & 2 deletions src/XML/xenc/OriginatorKeyInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -61,7 +62,7 @@ public static function fromXML(DOMElement $xml): static
$keyValue,
$retrievalMethod,
$x509Data,
//$pgpData,
$pgpData,
//$spkiData,
$mgmtData,
$other,
Expand Down
5 changes: 3 additions & 2 deletions src/XML/xenc/RecipientKeyInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -61,7 +62,7 @@ public static function fromXML(DOMElement $xml): static
$keyValue,
$retrievalMethod,
$x509Data,
//$pgpData,
$pgpData,
//$spkiData,
$mgmtData,
$other,
Expand Down
9 changes: 9 additions & 0 deletions tests/XML/ds/KeyInfoTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(
'<ssp:Chunk xmlns:ssp="urn:x-simplesamlphp:namespace">some</ssp:Chunk>',
)->documentElement),
Expand Down
95 changes: 95 additions & 0 deletions tests/XML/ds/PGPDataTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity\Test\XML\ds;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait;
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;
use SimpleSAML\XMLSecurity\XML\ds\AbstractDsElement;
use SimpleSAML\XMLSecurity\XML\ds\AbstractPGPDataType;
use SimpleSAML\XMLSecurity\XML\ds\PGPData;
use SimpleSAML\XMLSecurity\XML\ds\PGPKeyID;
use SimpleSAML\XMLSecurity\XML\ds\PGPKeyPacket;
use SimpleSAML\XMLSecurity\XML\xenc\P;

use function dirname;
use function strval;

/**
* Class \SimpleSAML\XMLSecurity\Test\XML\ds\PGPDataTest
*
* @package simplesamlphp/xml-security
*/
#[CoversClass(AbstractDsElement::class)]
#[CoversClass(AbstractPGPDataType::class)]
#[CoversClass(PGPData::class)]
final class PGPDataTest extends TestCase
{
use SchemaValidationTestTrait;
use SerializableElementTestTrait;

/**
*/
public static function setUpBeforeClass(): void
{
self::$testedClass = PGPData::class;

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

self::$xmlRepresentation = DOMDocumentFactory::fromFile(
dirname(__FILE__, 3) . '/resources/xml/ds_PGPData.xml',
);
}


/**
*/
public function testMarshalling(): void
{
$pgpKeyId = new PGPKeyID('GpM7');
$pgpKeyPacket = new PGPKeyPacket('GpM8');
$p = new P('/CTj03d1DB5e2t7CTo9BEzCf5S9NRzwnBgZRlm32REI=');

$pgpData = new PGPData($pgpKeyId, $pgpKeyPacket, [$p]);

$this->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);
}
}
9 changes: 9 additions & 0 deletions tests/XML/xenc/OriginatorKeyInfoTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(
'<ssp:Chunk xmlns:ssp="urn:x-simplesamlphp:namespace">some</ssp:Chunk>',
)->documentElement),
Expand Down
Loading

0 comments on commit bf9e836

Please sign in to comment.