Issues (5)

src/Comodojo/Cookies/EncryptedCookie.php (1 issue)

Severity
1
<?php namespace Comodojo\Cookies;
2
3
use \phpseclib\Crypt\AES;
4
use \Comodojo\Exception\CookieException;
5
6
/**
7
 * AES-encrypted cookie
8
 *
9
 * @package     Comodojo Spare Parts
10
 * @author      Marco Giovinazzi <[email protected]>
11
 * @license     MIT
12
 *
13
 * LICENSE:
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
 * THE SOFTWARE.
22
 */
23
24
class EncryptedCookie extends AbstractCookie {
25
26
    /*
27
     * AES key
28
     *
29
     * @var int
30
     */
31
    private $key = null;
32
33
    /**
34
     * Encrypted cookie constructor
35
     *
36
     * Setup cookie name and key
37
     *
38
     * @param string $name
39
     * @param string $key
40
     * @param int $max_cookie_size
41
     *
42
     * @throws CookieException
43
     */
44 42
    public function __construct($name, $key, $max_cookie_size = null) {
45
46 42
        if ( empty($key) OR !is_scalar($key) ) throw new CookieException("Invalid secret key");
47
48 42
        parent::__construct($name, $max_cookie_size);
49
50 42
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function setValue($value, $serialize = true) {
56
57
        if ( !is_scalar($value) && $serialize === false ) throw new CookieException("Cannot set non-scalar value without serialization");
58
59
        if ( $serialize === true ) $value = serialize($value);
60
61
        $cipher = new AES(AES::MODE_ECB);
62 24
63
        $cipher->setKeyLength(256);
64 24
65
        $cipher->setKey(self::encryptKey($this->key));
66 24
67
        // added base64 encoding to avoid problems with binary data
68 24
69
        $cookie_value = base64_encode($cipher->encrypt($value));
70 24
71
        if ( strlen($cookie_value) > $this->max_cookie_size ) throw new CookieException("Cookie size larger than ".$this->max_cookie_size." bytes");
72 24
73
        $this->value = $cookie_value;
74
75
        return $this;
76 24
77
    }
78 24
79
    /**
80 18
     * {@inheritdoc}
81
     */
82 18
    public function getValue($unserialize = true) {
83
84
        $cipher = new AES(AES::MODE_ECB);
85
86
        $cipher->setKeyLength(256);
87
88
        $cipher->setKey(self::encryptKey($this->key));
89
90
        // added base64 encoding to avoid problems with binary data
91
92
        $encoded_cookie = base64_decode($this->value);
93 18
94
        if ( $encoded_cookie === false ) throw new CookieException("Cookie data cannot be decoded");
95 18
96
        $cookie = $cipher->decrypt($encoded_cookie);
97 18
98
        if ( $cookie === false ) throw new CookieException("Cookie data cannot be dectypted");
0 ignored issues
show
The condition $cookie === false is always false.
Loading history...
99 18
100
        return ($unserialize === true) ? unserialize($cookie) : $cookie;
101
102
    }
103 18
104
    /**
105 18
     * Static method to quickly create a cookie
106
     *
107 18
     * @param string $name
108
     *  The cookie name
109 18
     *
110
     * @param string $key
111 18
     *
112
     * @param array $properties
113
     *  Array of properties cookie should have
114
     *
115
     * @return  EncryptedCookie
116
     * @throws  CookieException
117
     */
118
    public static function create($name, $key, array $properties = [], $serialize = true) {
119
120
        try {
121
122
            $class = get_called_class();
123
124
            $cookie = new $class($name, $key);
125
126
            CookieTools::setCookieProperties($cookie, $properties, $serialize);
127
128 6
        } catch (CookieException $ce) {
129
130
            throw $ce;
131
132 6
        }
133
134 6
        return $cookie;
135
136 6
    }
137
138 6
    /**
139
     * Static method to quickly get a cookie
140
     *
141
     * @param string $name
142
     *  The cookie name
143
     *
144 6
     * @param string $key
145
     *
146
     * @return EncryptedCookie
147
     * @throws CookieException
148
     */
149
    public static function retrieve($name, $key) {
150
151
        try {
152
153
            $class = get_called_class();
154
155
            $cookie = new $class($name, $key);
156
157
            $return = $cookie->load();
158
159 6
        } catch (CookieException $ce) {
160
161
            throw $ce;
162
163 6
        }
164
165 6
        return $return;
166
167 6
    }
168
169 6
    /**
170
     * Hash the key to generate a valid aes key value
171 6
     *
172
     * @param string $key
173
     *
174
     * @return string
175
     */
176
    protected static function encryptKey($key) {
177
178
        return hash('sha256', $key);
179
180
    }
181
182
}
183