Passed
Pull Request — master (#225)
by Jaime Pérez
02:37
created

EncryptedElementTrait::fromUnencryptedElement()   B

Complexity

Conditions 11
Paths 11

Size

Total Lines 41
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 27
c 1
b 0
f 0
nc 11
nop 2
dl 0
loc 41
rs 7.3166

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace SAML2\XML;
6
7
use DOMElement;
8
use RobRichards\XMLSecLibs\XMLSecEnc;
9
use RobRichards\XMLSecLibs\XMLSecurityKey;
10
use SAML2\Utils;
11
use SAML2\XML\xenc\EncryptedData;
12
use SAML2\XML\xenc\EncryptedKey;
13
use Webmozart\Assert\Assert;
14
15
/**
16
 * Trait aggregating functionality for encrypted elements.
17
 *
18
 * @package simplesamlphp/saml2
19
 */
20
trait EncryptedElementTrait
21
{
22
23
    /**
24
     * The current encrypted ID.
25
     *
26
     * @var \SAML2\XML\xenc\EncryptedData
27
     * @psalm-suppress PropertyNotSetInConstructor
28
     */
29
    protected $encryptedData;
30
31
    /**
32
     * A list of encrypted keys.
33
     *
34
     * @var \SAML2\XML\xenc\EncryptedKey[]
35
     */
36
    protected $encryptedKeys = [];
37
38
39
    /**
40
     * Constructor for encrypted elements.
41
     *
42
     * @param \SAML2\XML\xenc\EncryptedData $encryptedData The EncryptedData object.
43
     * @param \SAML2\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
    abstract public function instantiateParentElement(DOMElement $parent = null): DOMElement;
53
54
55
    abstract public function getQualifiedName(): string;
56
57
58
    /**
59
     * Get the EncryptedData object.
60
     *
61
     * @return \SAML2\XML\xenc\EncryptedData
62
     */
63
    public function getEncryptedData(): EncryptedData
64
    {
65
        return $this->encryptedData;
66
    }
67
68
69
    /**
70
     * @param \SAML2\XML\xenc\EncryptedData $encryptedData
71
     */
72
    protected function setEncryptedData(EncryptedData $encryptedData): void
73
    {
74
        $this->encryptedData = $encryptedData;
75
    }
76
77
78
    /**
79
     * Get the array of EncryptedKey objects
80
     *
81
     * @return \SAML2\XML\xenc\EncryptedKey[]
82
     */
83
    public function getEncryptedKeys(): array
84
    {
85
        return $this->encryptedKeys;
86
    }
87
88
89
    /**
90
     * @param \SAML2\XML\xenc\EncryptedKey[] $encryptedKeys
91
     */
92
    protected function setEncryptedKeys(array $encryptedKeys): void
93
    {
94
        Assert::allIsInstanceOf(
95
            $encryptedKeys,
96
            EncryptedKey::class,
97
            'All encrypted keys in <' . $this->getQualifiedName() . '> must be an instance of EncryptedKey.'
98
        );
99
        $this->encryptedKeys = $encryptedKeys;
100
    }
101
102
103
    /**
104
     * Create an encrypted element from a given unencrypted element and a key.
105
     *
106
     * @param \SAML2\XML\AbstractXMLElement $element
107
     * @param \RobRichards\XMLSecLibs\XMLSecurityKey $key
108
     *
109
     * @return \SAML2\XML\EncryptedElementInterface
110
     * @throws \Exception
111
     */
112
    public static function fromUnencryptedElement(
113
        AbstractXMLElement $element,
114
        XMLSecurityKey $key
115
    ): EncryptedElementInterface {
116
        $xml = $element->toXML();
117
118
        Utils::getContainer()->debugMessage($xml, 'encrypt');
119
120
        $enc = new XMLSecEnc();
121
        $enc->setNode($xml);
122
        $enc->type = XMLSecEnc::Element;
123
124
        switch ($key->type) {
125
            case XMLSecurityKey::TRIPLEDES_CBC:
126
            case XMLSecurityKey::AES128_CBC:
127
            case XMLSecurityKey::AES192_CBC:
128
            case XMLSecurityKey::AES256_CBC:
129
                $symmetricKey = $key;
130
                break;
131
132
            case XMLSecurityKey::RSA_1_5:
133
            case XMLSecurityKey::RSA_SHA1:
134
            case XMLSecurityKey::RSA_SHA256:
135
            case XMLSecurityKey::RSA_SHA384:
136
            case XMLSecurityKey::RSA_SHA512:
137
            case XMLSecurityKey::RSA_OAEP_MGF1P:
138
                $symmetricKey = new XMLSecurityKey(XMLSecurityKey::AES128_CBC);
139
                $symmetricKey->generateSessionKey();
140
141
                $enc->encryptKey($key, $symmetricKey);
142
143
                break;
144
145
            default:
146
                throw new \Exception('Unknown key type for encryption: ' . $key->type);
147
        }
148
149
        $dom = $enc->encryptNode($symmetricKey);
150
        /** @var \SAML2\XML\xenc\EncryptedData $encData */
151
        $encData = EncryptedData::fromXML($dom);
152
        return new static($encData, []);
153
    }
154
155
156
    /**
157
     * @inheritDoc
158
     * @return \SAML2\XML\AbstractXMLElement
159
     */
160
    public static function fromXML(DOMElement $xml): object
161
    {
162
        Assert::same($xml->localName, AbstractXMLElement::getClassName(static::class));
163
        Assert::same($xml->namespaceURI, static::NS);
164
165
        $ed = EncryptedData::getChildrenOfClass($xml);
166
        Assert::count($ed, 1, 'No more or less than one EncryptedData element allowed in ' .
167
            AbstractXMLElement::getClassName(static::class) . '.');
168
169
        $ek = EncryptedKey::getChildrenOfClass($xml);
170
171
        return new static($ed[0], $ek);
172
    }
173
174
175
    /**
176
     * @inheritDoc
177
     */
178
    public function toXML(DOMElement $parent = null): DOMElement
179
    {
180
        $e = $this->instantiateParentElement($parent);
181
182
        $this->encryptedData->toXML($e);
183
184
        foreach ($this->encryptedKeys as $key) {
185
            $key->toXML($e);
186
        }
187
188
        return $e;
189
    }
190
}
191