Skip to content

Commit b3d0bb2

Browse files
committed
change psalm level to 2, add more type hints + return types to Crypt, ensure we treat "" as a null hash
1 parent d0d7983 commit b3d0bb2

File tree

2 files changed

+59
-26
lines changed

2 files changed

+59
-26
lines changed

psalm.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0"?>
22
<psalm
3-
errorLevel="3"
3+
errorLevel="2"
44
resolveFromConfigFile="true"
55
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
66
xmlns="https://getpsalm.org/schema/config"

src/Crypt.php

+58-25
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,18 @@ public function __construct(string $algorithm)
4646
*
4747
* If the return value matches $pw_db, then the plain text password ('pw') is correct.
4848
*
49-
* @param string $pw - plain text password
50-
* @param string $pw_db - hash from e.g. database (what we're comparing $pw to).
49+
* @param string $clearText - plain text password
50+
* @param ?string $passwordHash - hash from e.g. database (what we're comparing $pw to).
5151
* @return string if $pw is correct (hashes to $pw_db) then we return $pw_db. Else we return a new hash.
5252
*
5353
* @throws Exception
5454
*/
55-
public function crypt(string $clearText, string $passwordHash = null): string
55+
public function crypt(string $clearText, ?string $passwordHash = null): string
5656
{
57+
if (is_string($passwordHash) && empty($passwordHash)) {
58+
$passwordHash = null;
59+
}
60+
5761
$algorithm = $this->algorithm;
5862

5963
switch ($this->algorithm) {
@@ -114,11 +118,11 @@ public function crypt(string $clearText, string $passwordHash = null): string
114118

115119
case 'CRYPT':
116120
$prefix = false;
117-
if (!empty($passwordHash)) {
121+
if (!is_null($passwordHash)) {
118122
$prefix = (substr($passwordHash, 0, 7) == '{CRYPT}');
119123
$passwordHash = preg_replace('/^{CRYPT}/', '', $passwordHash);
120124
}
121-
if (empty($passwordHash)) {
125+
if (is_null($passwordHash)) {
122126
$passwordHash = '$2y$10$' . substr(sha1(random_bytes(8)), 0, 22);
123127
}
124128
$str = crypt($clearText, $passwordHash);
@@ -159,27 +163,31 @@ public function hashSha1(string $clearText, string $algorithm = 'SHA1'): string
159163
return "{{$algorithm}}{$hash}";
160164
}
161165

162-
public function hashSha1Salted(string $clearText, string $hash = null): string
166+
public function hashSha1Salted(string $clearText, ?string $hash = null): string
163167
{
164-
if (empty($hash)) {
168+
$hash = $this->changeEmptyHashToNull($hash);
169+
170+
if (is_null($hash)) {
165171
$salt = base64_encode(random_bytes(3)); // 4 char salt.
166172
} else {
167173
$salt = substr(base64_decode(substr($hash, 6)), 20);
168174
}
169175
return '{SSHA}' . base64_encode(sha1($clearText . $salt, true) . $salt);
170176
}
171177

172-
public function hashSha512Salted(string $clearText, string $hash = null): string
178+
public function hashSha512Salted(string $clearText, ?string $hash = null): string
173179
{
174-
if (empty($hash)) {
180+
$hash = $this->changeEmptyHashToNull($hash);
181+
182+
if (is_null($hash)) {
175183
$salt = base64_encode(random_bytes(16));
176184
} else {
177185
$salt = substr(base64_decode(substr($hash, 9)), 64);
178186
}
179187
return '{SSHA512}' . base64_encode(hash('sha512', $clearText . $salt, true) . $salt);
180188
}
181189

182-
public function hashSha512(string $clearText, string $algorithm = 'SHA512')
190+
public function hashSha512(string $clearText, string $algorithm = 'SHA512'): string
183191
{
184192
$prefix = '{SHA512}';
185193

@@ -203,20 +211,24 @@ public function hashSha256(string $clearText): string
203211
return '{SHA256}' . base64_encode(hash('sha256', $clearText, true));
204212
}
205213

206-
public function cryptMd5(string $clearText, string $hash = null, $algorithm = 'MD5-CRYPT')
214+
public function cryptMd5(string $clearText, ?string $hash = null, string $algorithm = 'MD5-CRYPT'): string
207215
{
208-
if (!empty($hash)) {
216+
$hash = $this->changeEmptyHashToNull($hash);
217+
218+
if (is_string($hash)) {
209219
$hash = preg_replace('/^{MD5.*}/', '', $hash);
210220
}
211-
if (empty($hash)) {
221+
if (is_null($hash)) {
212222
$hash = '$1$' . substr(sha1(random_bytes(8)), 0, 16);
213223
}
214224
return "{{$algorithm}}" . crypt($clearText, $hash);
215225
}
216226

217-
public function blowfishCrypt(string $clearText, string $hash = null, string $algorithm = 'BLF-CRYPT'): string
227+
public function blowfishCrypt(string $clearText, ?string $hash = null, string $algorithm = 'BLF-CRYPT'): string
218228
{
219-
if (!empty($hash)) {
229+
$hash = $this->changeEmptyHashToNull($hash);
230+
231+
if (is_string($hash)) {
220232
if ($algorithm == 'BLF-CRYPT') {
221233
$hash = preg_replace('/^{BLF-CRYPT}/', '', $hash);
222234
}
@@ -244,17 +256,19 @@ public function blowfishCrypt(string $clearText, string $hash = null, string $al
244256
return '{BLF-CRYPT}' . $r;
245257
}
246258

247-
public function sha256Crypt(string $clearText, string $hash = null, string $algorithm = 'SHA256-CRYPT'): string
259+
public function sha256Crypt(string $clearText, ?string $hash = null, string $algorithm = 'SHA256-CRYPT'): string
248260
{
249-
if (!empty($hash)) {
261+
$hash = $this->changeEmptyHashToNull($hash);
262+
263+
if (is_string($hash)) {
250264
$hash = preg_replace('/^{SHA256-CRYPT(\.B64)?}/', '', $hash);
251265

252266
if ($algorithm == 'SHA256-CRYPT.B64') {
253267
$hash = base64_decode($hash);
254268
}
255269
}
256270

257-
if (empty($hash)) {
271+
if (is_null($hash)) {
258272
$hash = '$5$' . substr(sha1(random_bytes(8)), 0, 16);
259273
}
260274

@@ -266,17 +280,19 @@ public function sha256Crypt(string $clearText, string $hash = null, string $algo
266280
return "{SHA256-CRYPT}" . $generated;
267281
}
268282

269-
public function sha512Crypt(string $pw, string $hash = null, string $algorithm = 'SHA512-CRYPT'): string
283+
public function sha512Crypt(string $pw, ?string $hash = null, string $algorithm = 'SHA512-CRYPT'): string
270284
{
271-
if (!empty($hash)) {
285+
$hash = $this->changeEmptyHashToNull($hash);
286+
287+
if (is_string($hash)) {
272288
$hash = preg_replace('/^{SHA512-CRYPT(\.B64)?}/', '', $hash);
273289

274290
if ($algorithm == 'SHA512-CRYPT.B64') {
275291
$hash = base64_decode($hash);
276292
}
277293
}
278294

279-
if (empty($hash)) {
295+
if (is_null($hash)) {
280296
$hash = '$6$' . substr(sha1(random_bytes(8)), 0, 16);
281297
}
282298

@@ -290,9 +306,17 @@ public function sha512Crypt(string $pw, string $hash = null, string $algorithm =
290306
return "{SHA512-CRYPT}$generated";
291307
}
292308

293-
public function argon2ICrypt(string $clearText, string $hash = null, $algorithm = 'ARGON2I'): string
309+
/**
310+
* @param string $clearText
311+
* @param string|null $hash
312+
* @param $algorithm
313+
* @return string
314+
*/
315+
public function argon2ICrypt(string $clearText, ?string $hash = null, string $algorithm = 'ARGON2I'): string
294316
{
295-
if (!empty($hash)) {
317+
$hash = $this->changeEmptyHashToNull($hash);
318+
319+
if (is_string($hash)) {
296320
$hash = preg_replace('/^{ARGON2I(\.B64)?}/', '', $hash);
297321
$orig_pwdb = $hash;
298322
if ($algorithm == 'ARGON2I.B64') {
@@ -325,13 +349,15 @@ public function argon2ICrypt(string $clearText, string $hash = null, $algorithm
325349
return "{ARGON2I.B64}" . base64_encode($generated);
326350
}
327351

328-
public function argon2idCrypt(string $clearText, string $hash = null, string $algorithm = 'ARGON2ID'): string
352+
public function argon2idCrypt(string $clearText, ?string $hash = null, string $algorithm = 'ARGON2ID'): string
329353
{
330354
if (!defined('PASSWORD_ARGON2ID')) {
331355
throw new Exception("$algorithm is not supported; requires PHP 7.3+");
332356
}
333357

334-
if (!empty($hash)) {
358+
$hash = $this->changeEmptyHashToNull($hash);
359+
360+
if (is_string($hash)) {
335361
$hash = preg_replace('/^{ARGON2ID(\.B64)?}/', '', $hash);
336362

337363
$orig_pwdb = $hash;
@@ -366,4 +392,11 @@ public function argon2idCrypt(string $clearText, string $hash = null, string $al
366392
}
367393
return '{ARGON2ID.B64}' . base64_encode($generated);
368394
}
395+
396+
private function changeEmptyHashToNull(?string $hash) : ?string {
397+
if (is_string($hash) && empty($hash)) {
398+
return $hash;
399+
}
400+
return $hash;
401+
}
369402
}

0 commit comments

Comments
 (0)