66
77use DOMElement ;
88use SimpleSAML \Assert \Assert ;
9- use SimpleSAML \XML \ElementInterface ;
9+ use SimpleSAML \XML \Chunk ;
1010use SimpleSAML \XML \Exception \InvalidDOMElementException ;
1111use SimpleSAML \XML \Exception \SchemaViolationException ;
1212use SimpleSAML \XML \Exception \TooManyElementsException ;
1313use SimpleSAML \XML \ExtendableElementTrait ;
1414use SimpleSAML \XML \SchemaValidatableElementInterface ;
1515use SimpleSAML \XML \SchemaValidatableElementTrait ;
16+ use SimpleSAML \XML \SerializableElementInterface ;
1617use SimpleSAML \XML \XsNamespace as NS ;
18+ use SimpleSAML \XMLSecurity \Constants as C ;
19+ use SimpleSAML \XMLSecurity \XML \dsig11 \ECKeyValue ;
20+
21+ use function array_merge ;
22+ use function array_pop ;
1723
1824/**
1925 * Class representing a ds:KeyValue element.
2228 */
2329final class KeyValue extends AbstractDsElement implements SchemaValidatableElementInterface
2430{
25- use ExtendableElementTrait;
31+ // We use our own getter instead of the trait's one, so we prevent their use by marking them private
32+ use ExtendableElementTrait {
33+ getElements as private ;
34+ setElements as private ;
35+ }
2636 use SchemaValidatableElementTrait;
2737
2838
@@ -33,33 +43,38 @@ final class KeyValue extends AbstractDsElement implements SchemaValidatableEleme
3343 /**
3444 * Initialize an KeyValue.
3545 *
36- * @param \SimpleSAML\XMLSecurity\XML\ds\RSAKeyValue|null $RSAKeyValue
37- * @param \SimpleSAML\XML\SerializableElementInterface|null $element
46+ * @param \SimpleSAML\XML\SerializableElementInterface $keyValue
3847 */
3948 final public function __construct (
40- protected ?RSAKeyValue $ RSAKeyValue ,
41- ?ElementInterface $ element = null ,
49+ protected RSAKeyValue |DSAKeyValue |ECKeyValue |SerializableElementInterface $ keyValue ,
4250 ) {
43- Assert::false (
44- is_null ($ RSAKeyValue ) && is_null ($ element ),
45- 'A <ds:KeyValue> requires either a RSAKeyValue or an element in namespace ##other ' ,
46- SchemaViolationException::class,
47- );
48-
49- if ($ element !== null ) {
50- $ this ->setElements ([$ element ]);
51+ if (
52+ !($ keyValue instanceof RSAKeyValue
53+ || $ keyValue instanceof DSAKeyValue
54+ || $ keyValue instanceof ECKeyValue)
55+ ) {
56+ Assert::true (
57+ (($ keyValue instanceof Chunk) ? $ keyValue ->getNamespaceURI () : $ keyValue ::getNameSpaceURI ())
58+ !== C::NS_XDSIG ,
59+ 'A <ds:KeyValue> requires either a RSAKeyValue, DSAKeyValue, ECKeyValue '
60+ . 'or an element in namespace ##other ' ,
61+ SchemaViolationException::class,
62+ );
5163 }
5264 }
5365
5466
5567 /**
5668 * Collect the value of the RSAKeyValue-property
5769 *
58- * @return \SimpleSAML\XMLSecurity\XML\ds\RSAKeyValue|null
70+ * @return \SimpleSAML\XMLSecurity\XML\ds\RSAKeyValue|
71+ * \SimpleSAML\XMLSecurity\XML\ds\DSAKeyValue|
72+ * \SimpleSAML\XMLSecurity\XML\dsig11\ECKeyValue|
73+ * \SimpeSAML\XML\SerializableElementInterface
5974 */
60- public function getRSAKeyValue (): ? RSAKeyValue
75+ public function getKeyValue (): RSAKeyValue | DSAKeyValue | ECKeyValue | SerializableElementInterface
6176 {
62- return $ this ->RSAKeyValue ;
77+ return $ this ->keyValue ;
6378 }
6479
6580
@@ -77,23 +92,20 @@ public static function fromXML(DOMElement $xml): static
7792 Assert::same ($ xml ->localName , 'KeyValue ' , InvalidDOMElementException::class);
7893 Assert::same ($ xml ->namespaceURI , KeyValue::NS , InvalidDOMElementException::class);
7994
80- $ RSAKeyValue = RSAKeyValue::getChildrenOfClass ($ xml );
81- Assert::maxCount (
82- $ RSAKeyValue ,
83- 1 ,
84- 'A <ds:KeyValue> can contain exactly one <ds:RSAKeyValue> ' ,
85- TooManyElementsException::class,
95+ $ keyValue = array_merge (
96+ RSAKeyValue::getChildrenOfClass ($ xml ),
97+ DSAKeyValue::getChildrenOfClass ($ xml ),
98+ self ::getChildElementsFromXML ($ xml ),
8699 );
87100
88- $ elements = self ::getChildElementsFromXML ($ xml );
89- Assert::maxCount (
90- $ elements ,
101+ Assert::count (
102+ $ keyValue ,
91103 1 ,
92- 'A <ds:KeyValue> can contain exactly one element in namespace ##other ' ,
104+ 'A <ds:KeyValue> must contain exactly one child element ' ,
93105 TooManyElementsException::class,
94106 );
95107
96- return new static (array_pop ($ RSAKeyValue ), array_pop ( $ elements ));
108+ return new static (array_pop ($ keyValue ));
97109 }
98110
99111
@@ -107,13 +119,7 @@ public function toXML(?DOMElement $parent = null): DOMElement
107119 {
108120 $ e = $ this ->instantiateParentElement ($ parent );
109121
110- $ this ->getRSAKeyValue ()?->toXML($ e );
111-
112- foreach ($ this ->elements as $ elt ) {
113- if (!$ elt ->isEmptyElement ()) {
114- $ elt ->toXML ($ e );
115- }
116- }
122+ $ this ->getKeyValue ()->toXML ($ e );
117123
118124 return $ e ;
119125 }
0 commit comments