Completed
Push — master ( f15022...630d96 )
by Neomerx
02:54
created

SymmetricCrypt::getMethod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php namespace Limoncello\Crypt;
2
3
/**
4
 * Copyright 2015-2016 [email protected] (www.neomerx.com)
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use Limoncello\Crypt\Contracts\DecryptInterface;
20
use Limoncello\Crypt\Contracts\EncryptInterface;
21
22
/**
23
 * @package Limoncello\Crypt
24
 */
25
class SymmetricCrypt extends BaseCrypt implements EncryptInterface, DecryptInterface
26
{
27
    /**
28
     * @var string
29
     */
30
    private $method;
31
32
    /**
33
     * @var string
34
     */
35
    private $password;
36
37
    /**
38
     * Such as OPENSSL_RAW_DATA, OPENSSL_ZERO_PADDING.
39
     *
40
     * @var int
41
     */
42
    private $options;
43
44
    /**
45
     * @var string
46
     */
47
    private $initializationVector = null;
48
49
    /**
50
     * @param string $method
51
     * @param string $password
52
     */
53 3
    public function __construct($method, $password)
54
    {
55 3
        $this->setMethod($method)->setPassword($password)->asRaw();
56 3
    }
57
58
    /**
59
     * @inheritdoc
60
     */
61 1 View Code Duplication
    public function decrypt($data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
    {
63 1
        assert(is_string($data) === true);
64
65 1
        $this->clearErrors();
66
67 1
        $decrypted = $this->openSslDecrypt(
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->openSslDecrypt($d...nitializationVector()); of type string|false adds false to the return on line 77 which is incompatible with the return type declared by the interface Limoncello\Crypt\Contrac...cryptInterface::decrypt of type string. It seems like you forgot to handle an error condition.
Loading history...
68
            $data,
69 1
            $this->getMethod(),
70 1
            $this->getPassword(),
71 1
            $this->getOptions(),
72 1
            $this->getInitializationVector()
73
        );
74
75 1
        $decrypted !== false ?: $this->throwException(new CryptException($this->getErrorMessage()));
76
77 1
        return $decrypted;
78
    }
79
80
    /**
81
     * @inheritdoc
82
     */
83 3 View Code Duplication
    public function encrypt($data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
84
    {
85 3
        assert(is_string($data) === true);
86
87 3
        $this->clearErrors();
88
89 3
        $encrypted = $this->openSslEncrypt(
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->openSslEncrypt($d...nitializationVector()); of type string|false adds false to the return on line 99 which is incompatible with the return type declared by the interface Limoncello\Crypt\Contrac...cryptInterface::encrypt of type string. It seems like you forgot to handle an error condition.
Loading history...
90
            $data,
91 3
            $this->getMethod(),
92 3
            $this->getPassword(),
93 3
            $this->getOptions(),
94 3
            $this->getInitializationVector()
95
        );
96
97 3
        $encrypted !== false ?: $this->throwException(new CryptException($this->getErrorMessage()));
98
99 2
        return $encrypted;
100
    }
101
102
    /**
103
     * @return string
104
     */
105 3
    public function getPassword()
106
    {
107 3
        return $this->password;
108
    }
109
110
    /**
111
     * @return string
112
     */
113 3
    public function getMethod()
114
    {
115 3
        return $this->method;
116
    }
117
118
    /**
119
     * @param string $method
120
     *
121
     * @return $this
122
     */
123 3
    public function setMethod($method)
124
    {
125 3
        assert(is_string($method) === true && in_array($method, openssl_get_cipher_methods(true)) === true);
126
127 3
        $this->method = $method;
128
129 3
        return $this;
130
    }
131
132
    /**
133
     * @param string $password
134
     *
135
     * @return $this
136
     */
137 3
    public function setPassword($password)
138
    {
139 3
        assert(is_string($password) === true && empty($password) === false);
140
141 3
        $this->password = $password;
142
143 3
        return $this;
144
    }
145
146
    /**
147
     * @param null|string $value
148
     *
149
     * @return $this
150
     */
151 1
    public function resetInitializationVector($value = null)
152
    {
153 1
        assert(is_string($value) === true || $value === null);
154
155 1
        $this->initializationVector = $value;
156
157 1
        return $this;
158
    }
159
160
    /**
161
     * @return string
162
     */
163 3
    public function getInitializationVector()
164
    {
165 3
        if ($this->initializationVector === null) {
166 2
            $this->initializationVector = $this->generateInitializationVector();
167
        }
168
169 3
        return $this->initializationVector;
170
    }
171
172
    /**
173
     * @return $this
174
     */
175 3
    public function asRaw()
176
    {
177 3
        return $this->setOption(OPENSSL_RAW_DATA);
178
    }
179
180
    /**
181
     * @return $this
182
     */
183 1
    public function asBase64()
184
    {
185 1
        return $this->clearOption(OPENSSL_RAW_DATA);
186
    }
187
188
    /**
189
     * @return $this
190
     */
191 1
    public function withZeroPadding()
192
    {
193 1
        return $this->setOption(OPENSSL_ZERO_PADDING);
194
    }
195
196
    /**
197
     * @return $this
198
     */
199 3
    public function withoutZeroPadding()
200
    {
201 3
        return $this->clearOption(OPENSSL_ZERO_PADDING);
202
    }
203
204
    /**
205
     * @return int
206
     */
207 3
    protected function getOptions()
208
    {
209 3
        return $this->options;
210
    }
211
212
    /**
213
     * @param int $options
214
     *
215
     * @return $this
216
     */
217 3
    protected function setOptions($options)
218
    {
219 3
        assert(is_int($options) === true);
220
221 3
        $this->options = $options;
222
223 3
        return $this;
224
    }
225
226
    /**
227
     * @return string
228
     */
229 2
    protected function generateInitializationVector()
230
    {
231 2
        $vector = openssl_random_pseudo_bytes(openssl_cipher_iv_length($this->getMethod()));
232
233 2
        return $vector;
234
    }
235
236
    /**
237
     * @param int $option
238
     *
239
     * @return $this
240
     */
241 3 View Code Duplication
    protected function setOption($option)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
242
    {
243 3
        assert(is_int($option) === true);
244
245 3
        $this->setOptions($this->getOptions() | $option);
246
247 3
        return $this;
248
    }
249
250
    /**
251
     * @param int $option
252
     *
253
     * @return $this
254
     */
255 3 View Code Duplication
    protected function clearOption($option)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
256
    {
257 3
        assert(is_int($option) === true);
258
259 3
        $this->setOptions($this->getOptions() & ~$option);
260
261 3
        return $this;
262
    }
263
264
    /**
265
     * We need this wrapper for testing purposes so we can mock system call to Open SSL.
266
     *
267
     * @param string $data
268
     * @param string $method
269
     * @param string $password
270
     * @param int    $options
271
     * @param string $initializationVector
272
     *
273
     * @return string|false
274
     */
275 1
    protected function openSslDecrypt($data, $method, $password, $options, $initializationVector)
276
    {
277 1
        return openssl_decrypt($data, $method, $password, $options, $initializationVector);
278
    }
279
280
    /**
281
     * We need this wrapper for testing purposes so we can mock system call to Open SSL.
282
     *
283
     * @param string $data
284
     * @param string $method
285
     * @param string $password
286
     * @param int    $options
287
     * @param string $initializationVector
288
     *
289
     * @return string|false
290
     */
291 2
    protected function openSslEncrypt($data, $method, $password, $options, $initializationVector)
292
    {
293 2
        return openssl_encrypt($data, $method, $password, $options, $initializationVector);
294
    }
295
}
296