Passed
Branch php80 (d71885)
by Tim
01:59
created

KeyInfo::getId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\XML\ds;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\XML\Chunk;
10
use SimpleSAML\XML\Exception\InvalidDOMElementException;
11
use SimpleSAML\XMLSecurity\Constants as C;
12
use SimpleSAML\XMLSecurity\Exception\InvalidArgumentException;
13
use SimpleSAML\XMLSecurity\XML\xenc\EncryptedData;
14
use SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey;
15
16
/**
17
 * Class representing a ds:KeyInfo element.
18
 *
19
 * @package simplesamlphp/xml-security
20
 */
21
final class KeyInfo extends AbstractDsElement
22
{
23
    /**
24
     * The Id attribute on this element.
25
     *
26
     * @var string|null
27
     */
28
    protected ?string $Id = null;
29
30
    /**
31
     * The various key information elements.
32
     *
33
     * Array with various elements describing this key.
34
     * Unknown elements will be represented by \SimpleSAML\XML\Chunk.
35
     *
36
     * @var (\SimpleSAML\XML\Chunk|
0 ignored issues
show
Documentation Bug introduced by
The doc comment (\SimpleSAML\XML\Chunk| at position 3 could not be parsed: the token is null at position 3.
Loading history...
37
     *       \SimpleSAML\XMLSecurity\XML\ds\KeyName|
38
     *       \SimpleSAML\XMLSecurity\XML\ds\X509Data|
39
     *       \SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey)[]
40
     */
41
    protected array $info = [];
42
43
44
    /**
45
     * Initialize a KeyInfo element.
46
     *
47
     * @param (\SimpleSAML\XML\Chunk|
48
     *         \SimpleSAML\XMLSecurity\XML\ds\KeyName|
49
     *         \SimpleSAML\XMLSecurity\XML\ds\X509Data|
50
     *         \SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey)[] $info
51
     * @param string|null $Id
52
     */
53
    public function __construct(array $info, ?string $Id = null)
54
    {
55
        $this->setInfo($info);
56
        $this->setId($Id);
57
    }
58
59
60
    /**
61
     * Collect the value of the Id-property
62
     *
63
     * @return string|null
64
     */
65
    public function getId(): ?string
66
    {
67
        return $this->Id;
68
    }
69
70
71
    /**
72
     * Set the value of the Id-property
73
     *
74
     * @param string|null $id
75
     */
76
    private function setId(string $Id = null): void
77
    {
78
        Assert::nullOrValidNCName($Id);
79
        $this->Id = $Id;
80
    }
81
82
83
    /**
84
     * Collect the value of the info-property
85
     *
86
     * @return (\SimpleSAML\XML\Chunk|
0 ignored issues
show
Documentation Bug introduced by
The doc comment (\SimpleSAML\XML\Chunk| at position 3 could not be parsed: the token is null at position 3.
Loading history...
87
     *          \SimpleSAML\XMLSecurity\XML\ds\KeyName|
88
     *          \SimpleSAML\XMLSecurity\XML\ds\X509Data|
89
     *          \SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey)[]
90
     */
91
    public function getInfo(): array
92
    {
93
        return $this->info;
94
    }
95
96
97
    /**
98
     * Set the value of the info-property
99
     *
100
     * @param (\SimpleSAML\XML\Chunk|
101
     *         \SimpleSAML\XMLSecurity\XML\ds\KeyName|
102
     *         \SimpleSAML\XMLSecurity\XML\ds\X509Data|
103
     *         \SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey)[] $info
104
     * @throws \SimpleSAML\Assert\AssertionFailedException  if $info contains
105
     *   anything other than KeyName, X509Data, EncryptedKey or Chunk
106
     */
107
    private function setInfo(array $info): void
108
    {
109
        Assert::notEmpty($info, 'ds:KeyInfo cannot be empty', InvalidArgumentException::class);
110
        Assert::allIsInstanceOfAny(
111
            $info,
112
            [Chunk::class, KeyName::class, X509Data::class, EncryptedKey::class],
113
            'KeyInfo can only contain instances of KeyName, X509Data, EncryptedKey or Chunk.',
114
            InvalidArgumentException::class,
115
        );
116
        $this->info = $info;
117
    }
118
119
120
    /**
121
     * Convert XML into a KeyInfo
122
     *
123
     * @param \DOMElement $xml The XML element we should load
124
     * @return static
125
     *
126
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
127
     *   If the qualified name of the supplied element is wrong
128
     */
129
    public static function fromXML(DOMElement $xml): static
130
    {
131
        Assert::same($xml->localName, 'KeyInfo', InvalidDOMElementException::class);
132
        Assert::same($xml->namespaceURI, KeyInfo::NS, InvalidDOMElementException::class);
133
134
        $Id = self::getAttribute($xml, 'Id', null);
135
        $info = [];
136
137
        foreach ($xml->childNodes as $n) {
138
            if (!($n instanceof DOMElement)) {
139
                continue;
140
            } elseif ($n->namespaceURI === self::NS) {
141
                $info[] = match ($n->localName) {
142
                    'KeyName' => KeyName::fromXML($n),
143
                    'X509Data' => X509Data::fromXML($n),
144
                    default => new Chunk($n),
145
                };
146
            } elseif ($n->namespaceURI === C::NS_XENC) {
147
                $info[] = match ($n->localName) {
148
                    'EncryptedData' => EncryptedData::fromXML($n),
149
                    'EncryptedKey' => EncryptedKey::fromXML($n),
150
                    default => new Chunk($n),
151
                };
152
            } else {
153
                $info[] = new Chunk($n);
154
                break;
155
            }
156
        }
157
158
        return new static($info, $Id);
159
    }
160
161
    /**
162
     * Convert this KeyInfo to XML.
163
     *
164
     * @param \DOMElement|null $parent The element we should append this KeyInfo to.
165
     * @return \DOMElement
166
     */
167
    public function toXML(DOMElement $parent = null): DOMElement
168
    {
169
        $e = $this->instantiateParentElement($parent);
170
171
        if ($this->Id !== null) {
172
            $e->setAttribute('Id', $this->Id);
173
        }
174
175
        foreach ($this->info as $n) {
176
            $n->toXML($e);
177
        }
178
179
        return $e;
180
    }
181
}
182