diff --git a/src/XML/ds/X509Data.php b/src/XML/ds/X509Data.php index eb518427..b9c68947 100644 --- a/src/XML/ds/X509Data.php +++ b/src/XML/ds/X509Data.php @@ -10,6 +10,7 @@ use SimpleSAML\XML\Constants as C; use SimpleSAML\XML\Exception\InvalidDOMElementException; use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException; +use SimpleSAML\XMLSecurity\XML\dsig11\X509Digest; /** * Class representing a ds:X509Data element. @@ -24,7 +25,8 @@ final class X509Data extends AbstractDsElement * @param (\SimpleSAML\XML\Chunk| * \SimpleSAML\XMLSecurity\XML\ds\X509Certificate| * \SimpleSAML\XMLSecurity\XML\ds\X509IssuerSerial| - * \SimpleSAML\XMLSecurity\XML\ds\X509SubjectName)[] $data + * \SimpleSAML\XMLSecurity\XML\ds\X509SubjectName| + * \SimpleSAML\XMLSecurity\XML\dsig11\X509Digest)[] $data */ public function __construct( protected array $data, @@ -32,7 +34,7 @@ public function __construct( Assert::maxCount($data, C::UNBOUNDED_LIMIT); Assert::allIsInstanceOfAny( $data, - [Chunk::class, X509Certificate::class, X509IssuerSerial::class, X509SubjectName::class], + [Chunk::class, X509Certificate::class, X509IssuerSerial::class, X509SubjectName::class, X509Digest::class], InvalidArgumentException::class, ); } @@ -44,7 +46,8 @@ public function __construct( * @return (\SimpleSAML\XML\Chunk| * \SimpleSAML\XMLSecurity\XML\ds\X509Certificate| * \SimpleSAML\XMLSecurity\XML\ds\X509IssuerSerial| - * \SimpleSAML\XMLSecurity\XML\ds\X509SubjectName)[] + * \SimpleSAML\XMLSecurity\XML\ds\X509SubjectName| + * \SimpleSAML\XMLSecurity\XML\dsig11\X509Digest)[] */ public function getData(): array { @@ -80,6 +83,7 @@ public static function fromXML(DOMElement $xml): static 'X509Certificate' => X509Certificate::fromXML($n), 'X509IssuerSerial' => X509IssuerSerial::fromXML($n), 'X509SubjectName' => X509SubjectName::fromXML($n), + 'X509Digest' => X509Digest::fromXML($n), default => new Chunk($n), }; } diff --git a/tests/XML/ds/X509DataTest.php b/tests/XML/ds/X509DataTest.php index bedb2f73..85fa3cfd 100644 --- a/tests/XML/ds/X509DataTest.php +++ b/tests/XML/ds/X509DataTest.php @@ -10,6 +10,9 @@ use SimpleSAML\XML\DOMDocumentFactory; use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XMLSecurity\Constants as C; +use SimpleSAML\XMLSecurity\CryptoEncoding\PEM; +use SimpleSAML\XMLSecurity\Key; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; use SimpleSAML\XMLSecurity\XML\ds\AbstractDsElement; use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; @@ -18,8 +21,11 @@ use SimpleSAML\XMLSecurity\XML\ds\X509IssuerSerial; use SimpleSAML\XMLSecurity\XML\ds\X509SerialNumber; use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\dsig11\X509Digest; +use function base64_encode; use function dirname; +use function hex2bin; use function openssl_x509_parse; use function str_replace; use function strval; @@ -42,6 +48,8 @@ final class X509DataTest extends TestCase /** @var array */ private static array $certData; + /** @var string */ + private static string $digest; /** */ @@ -78,6 +86,11 @@ public static function setUpBeforeClass(): void self::$certData = openssl_x509_parse( PEMCertificatesMock::getPlainCertificate(PEMCertificatesMock::SELFSIGNED_CERTIFICATE), ); + + $key = new Key\X509Certificate(PEM::fromString(PEMCertificatesMock::getPlainCertificate())); + /** @var string $binary */ + $binary = hex2bin($key->getRawThumbprint(C::DIGEST_SHA256)); + self::$digest = base64_encode($binary); } @@ -101,6 +114,7 @@ public function testMarshalling(): void new X509SerialNumber('2'), ), new X509SubjectName(self::$certData['name']), + new X509Digest(self::$digest, C::DIGEST_SHA256), new Chunk(DOMDocumentFactory::fromString( 'other', )->documentElement), diff --git a/tests/resources/xml/ds_X509Data.xml b/tests/resources/xml/ds_X509Data.xml index fd4ab385..f8711fe9 100644 --- a/tests/resources/xml/ds_X509Data.xml +++ b/tests/resources/xml/ds_X509Data.xml @@ -6,5 +6,6 @@ 2 /CN=selfsigned.simplesamlphp.org/O=SimpleSAMLphp HQ/L=Honolulu/ST=Hawaii/C=US + 6tN39Q9d6IevlAWLeM7lQGazUnVlJOe1wCk3sro2rfE= other