AbstractKeyedHashFunction::hashFile()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 6

Importance

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