HasBaseEncryption   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 18
eloc 43
c 1
b 0
f 0
dl 0
loc 110
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A setEncryptionAad() 0 8 4
A getEncryptedField() 0 7 2
A getDecryptedValue() 0 6 2
A getEncryptionException() 0 3 1
B decryptValue() 0 38 9
1
<?php
2
3
namespace LeKoala\Encrypt;
4
5
use Exception;
6
use SilverStripe\ORM\DataObject;
7
use ParagonIE\CipherSweet\CipherSweet;
8
use ParagonIE\CipherSweet\EncryptedField;
9
use ParagonIE\CipherSweet\Exception\InvalidCiphertextException;
10
11
trait HasBaseEncryption
12
{
13
    /**
14
     * @var Exception
15
     */
16
    protected $encryptionException;
17
18
    /**
19
     * @var string
20
     */
21
    protected $encryptionAad = '';
22
23
    /**
24
     * @var string
25
     */
26
    protected $previousEncryptionAad = '';
27
28
    /**
29
     * @return Exception
30
     */
31
    public function getEncryptionException()
32
    {
33
        return $this->encryptionException;
34
    }
35
36
    /**
37
     * @param CipherSweet $engine
38
     * @return EncryptedField
39
     */
40
    public function getEncryptedField($engine = null)
41
    {
42
        if ($engine === null) {
43
            $engine = EncryptHelper::getCipherSweet();
44
        }
45
        $encryptedField = new EncryptedField($engine, $this->tableName, $this->name);
46
        return $encryptedField;
47
    }
48
49
    /**
50
     * Decrypt current value using underlying EncryptedField instance
51
     *
52
     * @return string
53
     */
54
    public function getDecryptedValue()
55
    {
56
        if (EncryptHelper::isEncrypted($this->value)) {
57
            return $this->decryptValue($this->value);
58
        }
59
        return $this->value;
60
    }
61
62
    /**
63
     * @param DataObject $record
64
     * @return void
65
     */
66
    protected function setEncryptionAad($record)
67
    {
68
        $field = EncryptHelper::getAadSource();
69
        if (!$field) {
70
            return;
71
        }
72
        if ($record && isset($record->$field)) {
73
            $this->encryptionAad = (string)$record->$field;
74
        }
75
    }
76
77
    /**
78
     * Decrypt a value using underlying EncryptedField instance
79
     *
80
     * @param string $value
81
     * @return string
82
     */
83
    protected function decryptValue($value)
84
    {
85
        if (!$value) {
86
            return $value;
87
        }
88
        if (!EncryptHelper::isEncrypted($value)) {
89
            return $value;
90
        }
91
        $decrypted = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $decrypted is dead and can be removed.
Loading history...
92
        $aad = $this->encryptionAad;
93
        try {
94
            $decrypted = $this->getEncryptedField()->decryptValue($value, $aad);
95
        } catch (InvalidCiphertextException $ex) {
96
            $this->encryptionException = $ex;
97
            // rotate backend ?
98
            if (EncryptHelper::getAutomaticRotation()) {
99
                $encryption = EncryptHelper::getEncryption($value);
100
                $engine = EncryptHelper::getEngineForEncryption($encryption);
101
                $oldEncryptedField = $this->getEncryptedField($engine);
102
                $decrypted = $oldEncryptedField->decryptValue($value, $aad);
103
                // this could throw another error that won't be catched if the old configuration is invalid
104
            } else {
105
                $decrypted = $value;
106
            }
107
        } catch (Exception $ex) {
108
            // This is a temporary fix for records written with AAD enabled but saved improperly
109
            // This is not needed if resetFieldValues is used
110
            if ($ex->getMessage() == "Invalid ciphertext" && $aad) {
111
                try {
112
                    $decrypted = $this->getEncryptedField()->decryptValue($value, "0");
113
                } catch (Exception $ex) {
114
                    $this->encryptionException = $ex;
115
                }
116
            } else {
117
                $this->encryptionException = $ex;
118
            }
119
        }
120
        return $decrypted;
121
    }
122
}
123