ItemDecorator::setPublicKey()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

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