Passed
Push — master ( cb6d98...316304 )
by Tim
02:20
created

EncryptedElementTrait::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 4
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\XML;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\XML\AbstractXMLElement;
10
use SimpleSAML\XML\Exception\InvalidDOMElementException;
11
use SimpleSAML\XMLSecurity\XML\xenc\EncryptedData;
12
use SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey;
13
use SimpleSAML\XMLSecurity\XMLSecEnc;
14
use SimpleSAML\XMLSecurity\XMLSecurityKey;
15
16
/**
17
 * Trait aggregating functionality for encrypted elements.
18
 *
19
 * @package simplesamlphp/saml2
20
 */
21
trait EncryptedElementTrait
22
{
23
    /**
24
     * The current encrypted ID.
25
     *
26
     * @var \SimpleSAML\XMLSecurity\XML\xenc\EncryptedData
27
     * @psalm-suppress PropertyNotSetInConstructor
28
     */
29
    protected EncryptedData $encryptedData;
30
31
    /**
32
     * A list of encrypted keys.
33
     *
34
     * @var \SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey[]
35
     */
36
    protected array $encryptedKeys = [];
37
38
39
    /**
40
     * Constructor for encrypted elements.
41
     *
42
     * @param \SimpleSAML\XMLSecurity\XML\xenc\EncryptedData $encryptedData The EncryptedData object.
43
     * @param \SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey[] $encryptedKeys An array of zero or more EncryptedKey objects.
44
     */
45
    public function __construct(EncryptedData $encryptedData, array $encryptedKeys)
46
    {
47
        $this->setEncryptedData($encryptedData);
48
        $this->setEncryptedKeys($encryptedKeys);
49
    }
50
51
52
    /**
53
     * Get the EncryptedData object.
54
     *
55
     * @return \SimpleSAML\XMLSecurity\XML\xenc\EncryptedData
56
     */
57
    public function getEncryptedData(): EncryptedData
58
    {
59
        return $this->encryptedData;
60
    }
61
62
63
    /**
64
     * @param \SimpleSAML\XMLSecurity\XML\xenc\EncryptedData $encryptedData
65
     */
66
    protected function setEncryptedData(EncryptedData $encryptedData): void
67
    {
68
        $this->encryptedData = $encryptedData;
69
    }
70
71
72
    /**
73
     * Get the array of EncryptedKey objects
74
     *
75
     * @return \SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey[]
76
     */
77
    public function getEncryptedKeys(): array
78
    {
79
        return $this->encryptedKeys;
80
    }
81
82
83
    /**
84
     * @param \SimpleSAML\XMLSecurity\XML\xenc\EncryptedKey[] $encryptedKeys
85
     */
86
    protected function setEncryptedKeys(array $encryptedKeys): void
87
    {
88
        Assert::allIsInstanceOf(
89
            $encryptedKeys,
90
            EncryptedKey::class,
91
            'All encrypted keys in <' . $this->getQualifiedName() . '> must be an instance of EncryptedKey.'
92
        );
93
94
        $this->encryptedKeys = $encryptedKeys;
95
    }
96
97
98
    /**
99
     * Create an encrypted element from a given unencrypted element and a key.
100
     *
101
     * @param \SimpleSAML\XML\AbstractXMLElement $element
102
     * @param \SimpleSAML\XMLSecurity\XMLSecurityKey $key
103
     *
104
     * @return \SimpleSAML\XMLSecurity\XML\EncryptedElementInterface
105
     * @throws \Exception
106
     */
107
    public static function fromUnencryptedElement(
108
        AbstractXMLElement $element,
109
        XMLSecurityKey $key
110
    ): EncryptedElementInterface {
111
        $xml = $element->toXML();
112
113
        $enc = new XMLSecEnc();
114
        $enc->setNode($xml);
115
        $enc->type = XMLSecEnc::Element;
116
117
        switch ($key->type) {
118
            case XMLSecurityKey::TRIPLEDES_CBC:
119
            case XMLSecurityKey::AES128_CBC:
120
            case XMLSecurityKey::AES192_CBC:
121
            case XMLSecurityKey::AES256_CBC:
122
            case XMLSecurityKey::AES128_GCM:
123
            case XMLSecurityKey::AES192_GCM:
124
            case XMLSecurityKey::AES256_GCM:
125
                $symmetricKey = $key;
126
                break;
127
128
            case XMLSecurityKey::RSA_1_5:
129
            case XMLSecurityKey::RSA_SHA1:
130
            case XMLSecurityKey::RSA_SHA256:
131
            case XMLSecurityKey::RSA_SHA384:
132
            case XMLSecurityKey::RSA_SHA512:
133
            case XMLSecurityKey::RSA_OAEP:
134
            case XMLSecurityKey::RSA_OAEP_MGF1P:
135
                $symmetricKey = new XMLSecurityKey(XMLSecurityKey::AES128_CBC);
136
                $symmetricKey->generateSessionKey();
137
138
                $enc->encryptKey($key, $symmetricKey);
139
140
                break;
141
142
            default:
143
                throw new \Exception('Unknown key type for encryption: ' . $key->type);
144
        }
145
146
        $dom = $enc->encryptNode($symmetricKey);
147
        /** @var \SimpleSAML\XMLSecurity\XML\xenc\EncryptedData $encData */
148
        $encData = EncryptedData::fromXML($dom);
149
        return new static($encData, []);
0 ignored issues
show
Bug Best Practice introduced by
The expression return new static($encData, array()) returns the type SimpleSAML\XMLSecurity\XML\EncryptedElementTrait which is incompatible with the type-hinted return SimpleSAML\XMLSecurity\X...cryptedElementInterface.
Loading history...
150
    }
151
152
153
    /**
154
     * @inheritDoc
155
     * @return \SimpleSAML\XMLSecurity\XML\EncryptedElementInterface
156
     *
157
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException if the qualified name of the supplied element is wrong
158
     */
159
    public static function fromXML(DOMElement $xml): object
160
    {
161
        Assert::same($xml->localName, AbstractXMLElement::getClassName(static::class), InvalidDOMElementException::class);
162
        Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
0 ignored issues
show
Bug introduced by
The constant SimpleSAML\XMLSecurity\X...cryptedElementTrait::NS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
163
164
        $ed = EncryptedData::getChildrenOfClass($xml);
165
        Assert::count($ed, 1, 'No more or less than one EncryptedData element allowed in ' .
166
            AbstractXMLElement::getClassName(static::class) . '.');
167
168
        $ek = EncryptedKey::getChildrenOfClass($xml);
169
170
        return new static($ed[0], $ek);
0 ignored issues
show
Bug Best Practice introduced by
The expression return new static($ed[0], $ek) returns the type SimpleSAML\XMLSecurity\XML\EncryptedElementTrait which is incompatible with the documented return type SimpleSAML\XMLSecurity\X...cryptedElementInterface.
Loading history...
171
    }
172
173
174
    /**
175
     * @inheritDoc
176
     */
177
    public function toXML(DOMElement $parent = null): DOMElement
178
    {
179
        $e = $this->instantiateParentElement($parent);
180
181
        $this->encryptedData->toXML($e);
182
183
        foreach ($this->encryptedKeys as $key) {
184
            $key->toXML($e);
185
        }
186
187
        return $e;
188
    }
189
190
191
    abstract public function instantiateParentElement(DOMElement $parent = null): DOMElement;
192
193
194
    abstract public function getQualifiedName(): string;
195
}
196