Skip to content

Commit ae05f56

Browse files
authored
refactor(cryptography): several fixes and improvements (#1764)
1 parent f9c246d commit ae05f56

File tree

6 files changed

+44
-18
lines changed

6 files changed

+44
-18
lines changed

packages/cryptography/src/Encryption/EncryptedData.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,18 @@ public static function unserialize(string $data): self
3838
throw EncryptedDataWasInvalid::dueToInvalidFormat();
3939
}
4040

41+
$payload = base64_decode($decoded['payload'], strict: true);
42+
$iv = base64_decode($decoded['iv'], strict: true);
43+
$tag = base64_decode($decoded['tag'], strict: true);
44+
45+
if ($payload === false || $iv === false || $tag === false) {
46+
throw EncryptedDataWasInvalid::dueToInvalidFormat();
47+
}
48+
4149
return new self(
42-
payload: base64_decode($decoded['payload'], strict: true),
43-
iv: base64_decode($decoded['iv'], strict: true),
44-
tag: base64_decode($decoded['tag'], strict: true),
50+
payload: $payload,
51+
iv: $iv,
52+
tag: $tag,
4553
signature: new Signature($decoded['signature']),
4654
algorithm: EncryptionAlgorithm::from($decoded['algorithm']),
4755
);

packages/cryptography/src/Encryption/EncryptionKey.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ public static function generate(EncryptionAlgorithm $algorithm): self
3333
*/
3434
public static function fromString(?string $key, EncryptionAlgorithm $algorithm): self
3535
{
36-
return new self(base64_decode($key ?: '', strict: true), $algorithm);
36+
$decoded = base64_decode($key ?: '', strict: true);
37+
38+
if ($decoded === false) {
39+
$decoded = '';
40+
}
41+
42+
return new self($decoded, $algorithm);
3743
}
3844

3945
public function toString(): string

packages/cryptography/src/Password/BcryptConfig.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
namespace Tempest\Cryptography\Password;
44

5-
use Tempest\Cryptography\Password\HashingAlgorithm;
6-
75
final class BcryptConfig implements PasswordHashingConfig
86
{
97
public HashingAlgorithm $algorithm = HashingAlgorithm::BCRYPT;

packages/cryptography/src/Password/Exceptions/HashingFailed.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,9 @@ public static function forEmptyPassword(): self
1515
{
1616
return new self('Could not hash an empty password.');
1717
}
18+
19+
public static function forInvalidHashingAlgorithm(): self
20+
{
21+
return new self('The specified hashing algorithm is not supported.');
22+
}
1823
}

packages/cryptography/src/Password/GenericPasswordHasher.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
namespace Tempest\Cryptography\Password;
44

5+
use Error;
56
use Tempest\Cryptography\Password\Exceptions\HashingFailed;
6-
use Tempest\Cryptography\Password\HashingAlgorithm;
7+
use ValueError;
78

89
final class GenericPasswordHasher implements PasswordHasher
910
{
@@ -17,22 +18,24 @@ public function __construct(
1718

1819
public function hash(#[\SensitiveParameter] string $password): string
1920
{
20-
$hash = password_hash($password, $this->algorithm->value, $this->config->options);
21-
22-
if ($hash === false) {
23-
throw HashingFailed::forUnknownReason();
21+
if ($password === '') {
22+
throw HashingFailed::forEmptyPassword();
2423
}
2524

26-
if (mb_strlen($password) === 0) {
27-
throw HashingFailed::forEmptyPassword();
25+
try {
26+
$hash = password_hash($password, $this->algorithm->value, $this->config->options);
27+
} catch (ValueError) {
28+
throw HashingFailed::forInvalidHashingAlgorithm();
29+
} catch (Error) {
30+
throw HashingFailed::forUnknownReason();
2831
}
2932

3033
return $hash;
3134
}
3235

3336
public function verify(#[\SensitiveParameter] string $password, #[\SensitiveParameter] string $hash): bool
3437
{
35-
if (mb_strlen($hash) === 0) {
38+
if ($password === '' || $hash === '') {
3639
return false;
3740
}
3841

@@ -41,11 +44,19 @@ public function verify(#[\SensitiveParameter] string $password, #[\SensitivePara
4144

4245
public function needsRehash(#[\SensitiveParameter] string $hash): bool
4346
{
47+
if ($hash === '') {
48+
return false;
49+
}
50+
4451
return password_needs_rehash($hash, $this->algorithm->value, $this->config->options);
4552
}
4653

4754
public function analyze(#[\SensitiveParameter] string $hash): ?Hash
4855
{
56+
if ($hash === '') {
57+
return null;
58+
}
59+
4960
$info = password_get_info($hash);
5061

5162
if ($info['algo'] === null) {

packages/cryptography/src/Password/PasswordHasher.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
namespace Tempest\Cryptography\Password;
44

5-
use Tempest\Cryptography\Password\HashingAlgorithm;
6-
75
interface PasswordHasher
86
{
97
public HashingAlgorithm $algorithm {
@@ -16,7 +14,7 @@ interface PasswordHasher
1614
public function hash(#[\SensitiveParameter] string $password): string;
1715

1816
/**
19-
* Checks if the given pain-text password matches the given hash.
17+
* Checks if the given plain-text password matches the given hash.
2018
*/
2119
public function verify(#[\SensitiveParameter] string $password, string $hash): bool;
2220

@@ -27,7 +25,7 @@ public function verify(#[\SensitiveParameter] string $password, string $hash): b
2725
public function needsRehash(#[\SensitiveParameter] string $hash): bool;
2826

2927
/**
30-
* Returns informations about the given hash, such as the algorithm used and its options.
28+
* Returns information about the given hash, such as the algorithm used and its options.
3129
*/
3230
public function analyze(#[\SensitiveParameter] string $hash): ?Hash;
3331
}

0 commit comments

Comments
 (0)