Completed
Push — master ( e03480...83fdca )
by Jonathan
04:06
created

ItemDecorator::isDecryptable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 9.4285
cc 2
eloc 6
nc 2
nop 0
crap 2
1
<?php
2
namespace Jsq\CacheEncryption\Envelope;
3
4
use Jsq\CacheEncryption\EncryptedValue as BaseEncryptedValue;
5
use Jsq\CacheEncryption\ItemDecorator as BaseItemDecorator;
6
use Jsq\CacheEncryption\InvalidArgumentException;
7
use Psr\Cache\CacheItemInterface;
8
9
class ItemDecorator extends BaseItemDecorator
10
{
11
    /** @var resource */
12
    private $publicKey;
13
    /** @var resource */
14
    private $privateKey;
15
16 171
    public function __construct(
17
        CacheItemInterface $decorated,
18
        $certificate,
19
        $key,
20
        $passPhrase,
21
        $cipher
22
    ) {
23 171
        parent::__construct($cipher, $decorated);
24 171
        $this->setPublicKey($certificate);
25 165
        $this->setPrivateKey($key, $passPhrase);
26 162
    }
27
28 162
    public function __destruct()
29
    {
30 162
        openssl_pkey_free($this->publicKey);
31 162
        openssl_pkey_free($this->privateKey);
32 162
    }
33
34 132
    protected function isDecryptable()
35
    {
36 132
        $data = $this->getDecorated()->get();
37
38
        return $data instanceof EncryptedValue
39 132
            && $this->validateSignature(
40 93
                $this->getKey() . $data->getCipherText(),
41 93
                $data->getSignature()
42 132
            );
43
    }
44
45 111
    protected function encrypt($data): BaseEncryptedValue
46
    {
47 111
        $key = $this->generateIv();
48 111
        $iv = $this->generateIv();
49 111
        $cipherText = $this->encryptString(serialize($data), $key, $iv);
50
51 111
        return new EncryptedValue(
52 111
            $cipherText,
53 111
            $this->getCipherMethod(),
54 111
            $iv,
55 111
            $this->encryptEnvelopeKey($key),
56 111
            $this->signString($this->getKey() . $cipherText)
57 111
        );
58
    }
59
60 66 View Code Duplication
    protected 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...
61
    {
62 66
        if (!$data instanceof EncryptedValue) return null;
63
64 66
        return unserialize($this->decryptString(
65 66
            $data->getCipherText(),
66 66
            $data->getMethod(),
67 66
            $this->decryptEnvelopeKey($data->getEnvelopeKey()),
68 66
            $data->getInitializationVector()
69 66
        ));
70
    }
71
72 171
    private function setPublicKey($cert)
73
    {
74 171
        $publicKey = @openssl_pkey_get_public($cert);
75 171
        if (!$this->validateOpenSslKey($publicKey)) {
76 6
            throw new InvalidArgumentException('Unable to create public key'
77
                . ' from provided certificate. Certificate must be a valid x509'
78 6
                . ' certificate, a PEM encoded certificate, or a path to a file'
79 6
                . ' containing a PEM encoded certificate.');
80
        }
81
82 165
        $this->publicKey = $publicKey;
83 165
    }
84
85 165
    private function setPrivateKey($key, $passPhrase)
86
    {
87 165
        $this->privateKey = @openssl_pkey_get_private($key, $passPhrase);
88 165
        if (!$this->validateOpenSslKey($this->privateKey)) {
89 3
            throw new InvalidArgumentException('Unable to create private key'
90
                . ' from provided key. Key must be a PEM encoded private key or'
91 3
                . ' a path to a file containing a PEM encoded private key.');
92
        }
93 162
    }
94
95 171
    private function validateOpenSslKey($key)
96
    {
97 171
        return is_resource($key) && 'OpenSSL key' === get_resource_type($key);
98
    }
99
100 111
    private function signString($string)
101
    {
102 111
        openssl_sign($string, $signature, $this->privateKey);
103
104 111
        return $signature;
105
    }
106
107 93
    private function validateSignature($signed, $signature)
108
    {
109 93
        return openssl_verify($signed, $signature, $this->publicKey);
110
    }
111
112 111
    private function encryptEnvelopeKey($key)
113
    {
114 111
        openssl_public_encrypt($key, $sealedKey, $this->publicKey);
115
116 111
        return $sealedKey;
117
    }
118
119 66
    private function decryptEnvelopeKey($sealedKey)
120
    {
121 66
        openssl_private_decrypt($sealedKey, $key, $this->privateKey);
122
123 66
        return $key;
124
    }
125
}
126