Completed
Push — master ( 456c00...ec5070 )
by Tony Karavasilev (Тони
08:30
created

ingForcingNativeHashing()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4

Importance

Changes 0
Metric Value
eloc 6
c 0
b 0
f 0
dl 0
loc 11
ccs 5
cts 5
cp 1
rs 10
cc 4
nc 5
nop 0
crap 4
1
<?php
2
3
/**
4
 * Abstraction for keyed hash objects like HMAC functions (keyed-hash message authentication code hash).
5
 */
6
7
namespace CryptoManana\Core\Abstractions\MessageDigestion;
8
9
use \CryptoManana\Core\Abstractions\MessageDigestion\AbstractHashAlgorithm as HashAlgorithm;
10
use \CryptoManana\Core\Interfaces\MessageDigestion\DigestionKeyInterface as KeyedHashing;
11
use \CryptoManana\Core\Interfaces\MessageDigestion\ObjectHashingInterface as ObjectHashing;
12
use \CryptoManana\Core\Interfaces\MessageDigestion\FileHashingInterface as FileHashing;
13
use \CryptoManana\Core\Traits\MessageDigestion\DigestionKeyTrait as DigestionKey;
14
use \CryptoManana\Core\Traits\MessageDigestion\ObjectHashingTrait as HashObjects;
15
use \CryptoManana\Core\Traits\MessageDigestion\FileHashingTrait as HashFiles;
16
17
/**
18
 * Class AbstractKeyedHashFunction - Abstraction for keyed hash classes.
19
 *
20
 * @package CryptoManana\Core\Abstractions\MessageDigestion
21
 *
22
 * @mixin DigestionKey
23
 * @mixin HashObjects
24
 * @mixin HashFiles
25
 */
26
abstract class AbstractKeyedHashFunction extends HashAlgorithm implements KeyedHashing, ObjectHashing, FileHashing
27
{
28
    /**
29
     * Data salting capabilities.
30
     *
31
     * {@internal Reusable implementation of `DigestionKeyInterface`. }}
32
     */
33
    use DigestionKey;
34
35
    /**
36
     * Object hashing capabilities.
37
     *
38
     * {@internal Reusable implementation of `ObjectHashingInterface`. }}
39
     */
40
    use HashObjects;
41
42
    /**
43
     * File hashing capabilities.
44
     *
45
     * {@internal Reusable implementation of `FileHashingInterface`. }}
46
     */
47
    use HashFiles;
48
49
    /**
50
     * The internal name of the algorithm.
51
     */
52
    const ALGORITHM_NAME = 'none';
53
54
    /**
55
     * Flag to force native code polyfill realizations, if available.
56
     *
57
     * @var bool Flag to force native realizations.
58
     */
59
    protected $useNative = false;
60
61
    /**
62
     * The key string property storage.
63
     *
64
     * @var string The digestion key string value.
65
     */
66
    protected $key = '';
67
68
    /**
69
     * Unkeyed hash algorithm constructor.
70
     */
71 396
    public function __construct()
72
    {
73 396
    }
74
75
    /**
76
     * Calculates a hash value for the given data.
77
     *
78
     * @param string $data The input string.
79
     *
80
     * @return string The digest.
81
     * @throws \Exception Validation errors.
82
     */
83 140
    public function hashData($data)
84
    {
85 140
        if (!is_string($data)) {
86 14
            throw new \InvalidArgumentException('The data for hashing must be a string or a binary string.');
87
        }
88
89 126
        $data = $this->addSaltString($data);
90
91 126
        $digest = hash_hmac(
92 126
            static::ALGORITHM_NAME,
93
            $data,
94 126
            $this->key,
95 126
            ($this->digestFormat === self::DIGEST_OUTPUT_RAW)
96
        );
97
98 126
        $digest = $this->changeOutputFormat($digest);
99
100 126
        return $digest;
101
    }
102
103
    /**
104
     * Calculates a hash value for the content of the given filename and location.
105
     *
106
     * @param string $filename The full path and name of the file for hashing.
107
     *
108
     * @return string The digest.
109
     * @throws \Exception Validation errors.
110
     */
111 66
    public function hashFile($filename)
112
    {
113 66
        if (!is_string($filename)) {
114 22
            throw new \InvalidArgumentException('The file path must be of type string.');
115
        }
116
117 44
        $this->validateFileNamePath($filename);
118
119 22
        $useFileSalting = $this->isFileSaltingForcingNativeHashing();
120
121 22
        if ($this->useNative || $useFileSalting) {
122 22
            $oldSalt = $this->salt;
123 22
            $oldMode = $this->saltingMode;
124
125 22
            $this->salt = ($useFileSalting) ? $this->salt : '';
126 22
            $this->saltingMode = ($useFileSalting) ? $this->saltingMode : self::SALTING_MODE_NONE;
127
128 22
            $digest = $this->hashData(file_get_contents($filename));
129
130 22
            $this->setSalt($oldSalt)->setSaltingMode($oldMode);
131
        } else {
132 22
            $digest = hash_hmac_file(
133 22
                static::ALGORITHM_NAME,
134
                $filename,
135 22
                $this->key,
136 22
                ($this->digestFormat === self::DIGEST_OUTPUT_RAW)
137
            );
138
139 22
            $digest = $this->changeOutputFormat($digest);
140
        }
141
142 22
        return $digest;
143
    }
144
145
    /**
146
     * Get debug information for the class instance.
147
     *
148
     * @return array Debug information.
149
     */
150 22
    public function __debugInfo()
151
    {
152
        return [
153 22
            'standard' => static::ALGORITHM_NAME,
154 22
            'type' => 'keyed digestion or HMAC',
155 22
            'key' => $this->key,
156 22
            'salt' => $this->salt,
157 22
            'mode' => $this->saltingMode,
158
        ];
159
    }
160
}
161