Completed
Push — master ( 8fe1b2...42aba3 )
by Michael
03:39
created

OpensslWrapper::tagRequired()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php declare(strict_types=1);
2
3
/**
4
 * OpensslWrapper.php
5
 *
6
 * PHP version 7
7
 *
8
 * @category Dcrypt
9
 * @package  Dcrypt
10
 * @author   Michael Meyer (mmeyer2k) <[email protected]>
11
 * @license  http://opensource.org/licenses/MIT The MIT License (MIT)
12
 * @link     https://github.com/mmeyer2k/dcrypt
13
 */
14
15
namespace Dcrypt;
16
17
/**
18
 * A wrapper around any openssl_* functions.
19
 *
20
 * @category Dcrypt
21
 * @package  Dcrypt
22
 * @author   Michael Meyer (mmeyer2k) <[email protected]>
23
 * @license  http://opensource.org/licenses/MIT The MIT License (MIT)
24
 * @link     https://github.com/mmeyer2k/dcrypt
25
 */
26
class OpensslWrapper
27
{
28
    /**
29
     * OpenSSL encrypt wrapper function
30
     *
31
     * @param string $input  Data to decrypt
32
     * @param string $method Cipher method to use
33
     * @param string $key    Key string
34
     * @param string $iv     Initialization vector
35
     * @return string
36
     */
37 View Code Duplication
    protected static function openssl_encrypt(string $input, string $method, string $key, string $iv, string &$tag): string
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...
38
    {
39
        if (OpensslStatic::tagRequired($method)) {
0 ignored issues
show
Bug introduced by
The method tagRequired() cannot be called from this context as it is declared protected in class Dcrypt\OpensslWrapper.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
40
            $ret = \openssl_encrypt($input, $method, $key, OPENSSL_RAW_DATA, $iv, $tag, '', 4);
41
        } else {
42
            $ret = \openssl_encrypt($input, $method, $key, OPENSSL_RAW_DATA, $iv);
43
        }
44
45
        return self::returnOrException($ret);
46
    }
47
48
    /**
49
     * OpenSSL decrypt wrapper function
50
     *
51
     * @param string $input  Data to decrypt
52
     * @param string $method Cipher method to use
53
     * @param string $key    Key string
54
     * @param string $iv     Initialization vector
55
     * @return string
56
     */
57 View Code Duplication
    protected static function openssl_decrypt(string $input, string $method, string $key, string $iv, string $tag): string
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...
58
    {
59
        if (OpensslStatic::tagRequired($method)) {
0 ignored issues
show
Bug introduced by
The method tagRequired() cannot be called from this context as it is declared protected in class Dcrypt\OpensslWrapper.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
60
            $ret = \openssl_decrypt($input, $method, $key, OPENSSL_RAW_DATA, $iv, $tag, '');
61
        } else {
62
            $ret = \openssl_decrypt($input, $method, $key, OPENSSL_RAW_DATA, $iv);
63
        }
64
65
        return self::returnOrException($ret);
66
    }
67
68
    /**
69
     * Throw an exception if openssl function returns false
70
     *
71
     * @param string|bool $data
72
     * @return string
73
     * @throws \Exception
74
     */
75
    private static function returnOrException($data): string
76
    {
77
        if ($data === false) {
78
            throw new \Exception('OpenSSL failed to encrypt/decrypt message.');
79
        }
80
81
        return $data;
82
    }
83
84
    /**
85
     * Get IV size for specified CIPHER.
86
     *
87
     * @param string $cipher
88
     * @return int
89
     * @throws \Exception
90
     */
91
    protected static function ivSize(string $cipher): int
92
    {
93
        $ret = \openssl_cipher_iv_length($cipher);
94
95
        if ($ret === false) {
96
            throw new \Exception("Failed to determine correct IV size.");
97
        }
98
99
        return $ret;
100
    }
101
102
    /**
103
     * Get a correctly sized IV for the specified cipher
104
     *
105
     * @param string $cipher
106
     * @return string
107
     * @throws \Exception
108
     */
109
    protected static function ivGenerate(string $cipher): string
110
    {
111
        $size = self::ivSize($cipher);
112
113
        if ($size === 0) {
114
            return '';
115
        }
116
117
        return \random_bytes($size);
118
    }
119
120
    /**
121
     * Determines if the provided cipher requires a tag
122
     *
123
     * @param string $cipher
124
     * @return bool
125
     */
126
    protected static function tagRequired(string $cipher): bool
127
    {
128
        $cipher = strtolower($cipher);
129
130
        $needle_tips = [
131
            '-gcm',
132
            '-ccm',
133
        ];
134
135
        foreach ($needle_tips as $needle) {
136
            if (strpos($cipher, $needle)) {
137
                return true;
138
            }
139
        }
140
141
        return false;
142
    }
143
}
144