Passed
Pull Request — master (#431)
by El
02:52
created

FormatV2::isValid()   F

Complexity

Conditions 26
Paths 124

Size

Total Lines 93
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 26

Importance

Changes 0
Metric Value
cc 26
eloc 44
nc 124
nop 2
dl 0
loc 93
ccs 44
cts 44
cp 1
crap 26
rs 3.9666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * PrivateBin
4
 *
5
 * a zero-knowledge paste bin
6
 *
7
 * @link      https://github.com/PrivateBin/PrivateBin
8
 * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
9
 * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
10
 * @version   1.2.1
11
 */
12
13
namespace PrivateBin;
14
15
/**
16
 * FormatV2
17
 *
18
 * Provides validation function for version 2 format of pastes & comments.
19
 */
20
class FormatV2
21
{
22
    /**
23
     * version 2 format validator
24
     *
25
     * Checks if the given array is a proper version 2 formatted, encrypted message.
26
     *
27
     * @access public
28
     * @static
29
     * @param  array $message
30
     * @param  bool  $isComment
31
     * @return bool
32
     */
33 37
    public static function isValid($message, $isComment = false)
34
    {
35 37
        $required_keys = array('adata', 'v', 'ct');
36 37
        if ($isComment) {
37 11
            $required_keys[] = 'pasteid';
38 11
            $required_keys[] = 'parentid';
39
        } else {
40 27
            $required_keys[] = 'meta';
41
        }
42
43
        // Make sure no additionnal keys were added.
44 37
        if (count(array_keys($message)) != count($required_keys)) {
45 1
            return false;
46
        }
47
48
        // Make sure required fields are present.
49 37
        foreach ($required_keys as $k) {
50 37
            if (!array_key_exists($k, $message)) {
51 37
                return false;
52
            }
53
        }
54
55 37
        $cipherParams = $isComment ? $message['adata'] : $message['adata'][0];
56
57
        // Make sure some fields are base64 data:
58
        // - initialization vector
59 37
        if (!base64_decode($cipherParams[0], true)) {
60 1
            return false;
61
        }
62
        // - salt
63 37
        if (!base64_decode($cipherParams[1], true)) {
64 1
            return false;
65
        }
66
        // - cipher text
67 37
        if (!($ct = base64_decode($message['ct'], true))) {
68 1
            return false;
69
        }
70
71
        // Make sure some fields have a reasonable size:
72
        // - initialization vector
73 37
        if (strlen($cipherParams[0]) > 24) {
74 1
            return false;
75
        }
76
        // - salt
77 37
        if (strlen($cipherParams[1]) > 14) {
78 1
            return false;
79
        }
80
81
        // Make sure some fields contain no unsupported values:
82
        // - version
83 37
        if (!(is_int($message['v']) || is_float($message['v'])) || (float) $message['v'] < 2) {
84 1
            return false;
85
        }
86
        // - iterations, refuse less then 10000 iterations (minimum NIST recommendation)
87 37
        if (!is_int($cipherParams[2]) || $cipherParams[2] <= 10000) {
88 1
            return false;
89
        }
90
        // - key size
91 37
        if (!in_array($cipherParams[3], array(128, 192, 256), true)) {
92 1
            return false;
93
        }
94
        // - tag size
95 37
        if (!in_array($cipherParams[4], array(64, 96, 128), true)) {
96 1
            return false;
97
        }
98
        // - algorithm, must be AES
99 37
        if ($cipherParams[5] !== 'aes') {
100 1
            return false;
101
        }
102
        // - mode
103 37
        if (!in_array($cipherParams[6], array('ctr', 'cbc', 'gcm'), true)) {
104 1
            return false;
105
        }
106
        // - compression
107 37
        if (!in_array($cipherParams[7], array('zlib', 'none'), true)) {
108 1
            return false;
109
        }
110
111
        // Reject data if entropy is too low
112 37
        if (strlen($ct) > strlen(gzdeflate($ct))) {
113 1
            return false;
114
        }
115
116
        // require only the key 'expire' in the metadata of pastes
117 37
        if (!$isComment && (
118 27
            count($message['meta']) === 0 ||
119 27
            !array_key_exists('expire', $message['meta']) ||
120 37
            count($message['meta']) > 1
121
        )) {
122 1
            return false;
123
        }
124
125 37
        return true;
126
    }
127
}
128