Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0641859

Browse filesBrowse files
committed
[Security] Allow to set a fixed algorithm
1 parent 54e1d12 commit 0641859
Copy full SHA for 0641859

File tree

13 files changed

+192
-64
lines changed
Filter options

13 files changed

+192
-64
lines changed

‎UPGRADE-4.3.md

Copy file name to clipboardExpand all lines: UPGRADE-4.3.md
-5Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,6 @@ Security
209209
* Not implementing the methods `__serialize` and `__unserialize` in classes implementing
210210
the `TokenInterface` is deprecated
211211

212-
SecurityBundle
213-
--------------
214-
215-
* Configuring encoders using `argon2i` or `bcrypt` as algorithm has been deprecated, use `auto` instead.
216-
217212
TwigBridge
218213
----------
219214

‎UPGRADE-5.0.md

Copy file name to clipboardExpand all lines: UPGRADE-5.0.md
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,6 @@ SecurityBundle
509509
changed to underscores.
510510
Before: `my-cookie` deleted the `my_cookie` cookie (with an underscore).
511511
After: `my-cookie` deletes the `my-cookie` cookie (with a dash).
512-
* Configuring encoders using `argon2i` or `bcrypt` as algorithm is not supported anymore, use `auto` instead.
513512

514513
Serializer
515514
----------

‎src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/CHANGELOG.md
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ CHANGELOG
1414
option is deprecated and will be disabled in Symfony 5.0. This affects to cookies
1515
with dashes in their names. For example, starting from Symfony 5.0, the `my-cookie`
1616
name will delete `my-cookie` (with a dash) instead of `my_cookie` (with an underscore).
17-
* Deprecated configuring encoders using `argon2i` as algorithm, use `auto` instead
1817

1918
4.2.0
2019
-----

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+53-14Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
use Symfony\Component\DependencyInjection\Reference;
2929
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
3030
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
31-
use Symfony\Component\Security\Core\Encoder\Argon2iPasswordEncoder;
3231
use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder;
3332
use Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder;
3433
use Symfony\Component\Security\Core\User\UserProviderInterface;
@@ -538,32 +537,72 @@ private function createEncoder(array $config)
538537

539538
// bcrypt encoder
540539
if ('bcrypt' === $config['algorithm']) {
541-
@trigger_error('Configuring an encoder with "bcrypt" as algorithm is deprecated since Symfony 4.3, use "auto" instead.', E_USER_DEPRECATED);
542-
543540
return [
544-
'class' => 'Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder',
545-
'arguments' => [$config['cost'] ?? 13],
541+
'class' => NativePasswordEncoder::class,
542+
'arguments' => [
543+
$config['time_cost'] ?? null,
544+
(($config['memory_cost'] ?? 0) << 10) ?: null,
545+
$config['cost'] ?? null,
546+
\PASSWORD_BCRYPT,
547+
],
546548
];
547549
}
548550

549551
// Argon2i encoder
550552
if ('argon2i' === $config['algorithm']) {
551-
@trigger_error('Configuring an encoder with "argon2i" as algorithm is deprecated since Symfony 4.3, use "auto" instead.', E_USER_DEPRECATED);
553+
if (SodiumPasswordEncoder::isSupported() && !($hasSodiumArgon2id = \defined('SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13'))) {
554+
return [
555+
'class' => SodiumPasswordEncoder::class,
556+
'arguments' => [
557+
$config['time_cost'] ?? null,
558+
(($config['memory_cost'] ?? 0) << 10) ?: null,
559+
],
560+
];
561+
}
552562

553-
if (!Argon2iPasswordEncoder::isSupported()) {
554-
if (\extension_loaded('sodium') && !\defined('SODIUM_CRYPTO_PWHASH_SALTBYTES')) {
555-
throw new InvalidConfigurationException('The installed libsodium version does not have support for Argon2i. Use "auto" instead.');
563+
if (!\defined('PASSWORD_ARGON2I')) {
564+
if ($hasSodiumArgon2id ?? false) {
565+
throw new InvalidConfigurationException('Algorithm "argon2i" is not available. You should either use "argon2id", downgrade your sodium extension or use a different encoder.');
556566
}
567+
throw new InvalidConfigurationException('Algorithm "argon2i" is not available. You should either install the sodium extension, upgrade to PHP 7.2+ or use a different encoder.');
568+
}
557569

558-
throw new InvalidConfigurationException('Argon2i algorithm is not supported. Install the libsodium extension or use "auto" instead.');
570+
return [
571+
'class' => NativePasswordEncoder::class,
572+
'arguments' => [
573+
$config['time_cost'] ?? null,
574+
(($config['memory_cost'] ?? 0) << 10) ?: null,
575+
$config['cost'] ?? null,
576+
\PASSWORD_ARGON2I,
577+
],
578+
];
579+
}
580+
581+
if ('argon2id' === $config['algorithm']) {
582+
if (($hasSodium = SodiumPasswordEncoder::isSupported()) && \defined('SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13')) {
583+
return [
584+
'class' => SodiumPasswordEncoder::class,
585+
'arguments' => [
586+
$config['time_cost'] ?? null,
587+
(($config['memory_cost'] ?? 0) << 10) ?: null,
588+
],
589+
];
590+
}
591+
592+
if (!\defined('PASSWORD_ARGON2ID')) {
593+
if (\defined('PASSWORD_ARGON2I') || $hasSodium) {
594+
throw new InvalidConfigurationException(sprintf('Algorithm "argon2id" is not available. You can either use "argon2i", upgrade to PHP 7.3+, %s sodium extension or use a different encoder.', $hasSodium ? 'upgrade your' : 'install the'));
595+
}
596+
throw new InvalidConfigurationException(sprintf('Algorithm "argon2id" is not available. You should either %s sodium extension, upgrade to PHP 7.3+ or use a different encoder.', $hasSodium ? 'upgrade your' : 'install the'));
559597
}
560598

561599
return [
562-
'class' => 'Symfony\Component\Security\Core\Encoder\Argon2iPasswordEncoder',
600+
'class' => NativePasswordEncoder::class,
563601
'arguments' => [
564-
$config['memory_cost'],
565-
$config['time_cost'],
566-
$config['threads'],
602+
$config['time_cost'] ?? null,
603+
(($config['memory_cost'] ?? 0) << 10) ?: null,
604+
$config['cost'] ?? null,
605+
\PASSWORD_ARGON2ID,
567606
],
568607
];
569608
}

‎src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
+6-15Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
use Symfony\Component\DependencyInjection\ContainerBuilder;
1919
use Symfony\Component\DependencyInjection\Reference;
2020
use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
21-
use Symfony\Component\Security\Core\Encoder\Argon2iPasswordEncoder;
21+
use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder;
2222
use Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder;
2323

2424
abstract class CompleteConfigurationTest extends TestCase
@@ -377,14 +377,9 @@ public function testEncodersWithLibsodium()
377377
]], $container->getDefinition('security.encoder_factory.generic')->getArguments());
378378
}
379379

380-
/**
381-
* @group legacy
382-
*
383-
* @expectedDeprecation Configuring an encoder with "argon2i" as algorithm is deprecated since Symfony 4.3, use "auto" instead.
384-
*/
385380
public function testEncodersWithArgon2i()
386381
{
387-
if (!Argon2iPasswordEncoder::isSupported()) {
382+
if (!($sodium = SodiumPasswordEncoder::isSupported() && !\defined('SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13')) && !\defined('PASSWORD_ARGON2I')) {
388383
$this->markTestSkipped('Argon2i algorithm is not supported.');
389384
}
390385

@@ -429,19 +424,15 @@ public function testEncodersWithArgon2i()
429424
'arguments' => [8, 102400, 15],
430425
],
431426
'JMS\FooBundle\Entity\User7' => [
432-
'class' => 'Symfony\Component\Security\Core\Encoder\Argon2iPasswordEncoder',
433-
'arguments' => [256, 1, 2],
427+
'class' => $sodium ? SodiumPasswordEncoder::class : NativePasswordEncoder::class,
428+
'arguments' => $sodium ? [256, 1] : [1, 262144, null, \PASSWORD_ARGON2I],
434429
],
435430
]], $container->getDefinition('security.encoder_factory.generic')->getArguments());
436431
}
437432

438-
/**
439-
* @group legacy
440-
*/
441433
public function testEncodersWithBCrypt()
442434
{
443435
$container = $this->getContainer('bcrypt_encoder');
444-
445436
$this->assertEquals([[
446437
'JMS\FooBundle\Entity\User1' => [
447438
'class' => 'Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder',
@@ -481,8 +472,8 @@ public function testEncodersWithBCrypt()
481472
'arguments' => [8, 102400, 15],
482473
],
483474
'JMS\FooBundle\Entity\User7' => [
484-
'class' => 'Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder',
485-
'arguments' => [15],
475+
'class' => NativePasswordEncoder::class,
476+
'arguments' => [null, null, 15, \PASSWORD_BCRYPT],
486477
],
487478
]], $container->getDefinition('security.encoder_factory.generic')->getArguments());
488479
}

‎src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/argon2i_encoder.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/argon2i_encoder.php
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
'algorithm' => 'argon2i',
99
'memory_cost' => 256,
1010
'time_cost' => 1,
11-
'threads' => 2,
1211
],
1312
],
1413
]);

‎src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/argon2i_encoder.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/argon2i_encoder.xml
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</imports>
1111

1212
<sec:config>
13-
<sec:encoder class="JMS\FooBundle\Entity\User7" algorithm="argon2i" memory_cost="256" time_cost="1" threads="2" />
13+
<sec:encoder class="JMS\FooBundle\Entity\User7" algorithm="argon2i" memory_cost="256" time_cost="1" />
1414
</sec:config>
1515

1616
</container>

‎src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/argon2i_encoder.yml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/argon2i_encoder.yml
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,3 @@ security:
77
algorithm: argon2i
88
memory_cost: 256
99
time_cost: 1
10-
threads: 2

‎src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php
+54-15Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
use Symfony\Bundle\SecurityBundle\Command\UserPasswordEncoderCommand;
1616
use Symfony\Component\Console\Application as ConsoleApplication;
1717
use Symfony\Component\Console\Tester\CommandTester;
18-
use Symfony\Component\Security\Core\Encoder\Argon2iPasswordEncoder;
19-
use Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder;
2018
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
2119
use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder;
2220
use Symfony\Component\Security\Core\Encoder\Pbkdf2PasswordEncoder;
@@ -55,9 +53,6 @@ public function testEncodeNoPasswordNoInteraction()
5553
$this->assertEquals($statusCode, 1);
5654
}
5755

58-
/**
59-
* @group legacy
60-
*/
6156
public function testEncodePasswordBcrypt()
6257
{
6358
$this->setupBcrypt();
@@ -70,18 +65,15 @@ public function testEncodePasswordBcrypt()
7065
$output = $this->passwordEncoderCommandTester->getDisplay();
7166
$this->assertStringContainsString('Password encoding succeeded', $output);
7267

73-
$encoder = new BCryptPasswordEncoder(17);
68+
$encoder = new NativePasswordEncoder(null, null, 17, \PASSWORD_BCRYPT);
7469
preg_match('# Encoded password\s{1,}([\w+\/$.]+={0,2})\s+#', $output, $matches);
7570
$hash = $matches[1];
7671
$this->assertTrue($encoder->isPasswordValid($hash, 'password', null));
7772
}
7873

79-
/**
80-
* @group legacy
81-
*/
8274
public function testEncodePasswordArgon2i()
8375
{
84-
if (!Argon2iPasswordEncoder::isSupported()) {
76+
if (!($sodium = SodiumPasswordEncoder::isSupported() && !\defined('SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13')) && !\defined('PASSWORD_ARGON2I')) {
8577
$this->markTestSkipped('Argon2i algorithm not available.');
8678
}
8779
$this->setupArgon2i();
@@ -94,7 +86,28 @@ public function testEncodePasswordArgon2i()
9486
$output = $this->passwordEncoderCommandTester->getDisplay();
9587
$this->assertStringContainsString('Password encoding succeeded', $output);
9688

97-
$encoder = new Argon2iPasswordEncoder();
89+
$encoder = $sodium ? new SodiumPasswordEncoder() : new NativePasswordEncoder(null, null, null, \PASSWORD_ARGON2I);
90+
preg_match('# Encoded password\s+(\$argon2i?\$[\w,=\$+\/]+={0,2})\s+#', $output, $matches);
91+
$hash = $matches[1];
92+
$this->assertTrue($encoder->isPasswordValid($hash, 'password', null));
93+
}
94+
95+
public function testEncodePasswordArgon2id()
96+
{
97+
if (!($sodium = (SodiumPasswordEncoder::isSupported() && \defined('SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13'))) && !\defined('PASSWORD_ARGON2ID')) {
98+
$this->markTestSkipped('Argon2id algorithm not available.');
99+
}
100+
$this->setupArgon2id();
101+
$this->passwordEncoderCommandTester->execute([
102+
'command' => 'security:encode-password',
103+
'password' => 'password',
104+
'user-class' => 'Custom\Class\Argon2id\User',
105+
], ['interactive' => false]);
106+
107+
$output = $this->passwordEncoderCommandTester->getDisplay();
108+
$this->assertStringContainsString('Password encoding succeeded', $output);
109+
110+
$encoder = $sodium ? new SodiumPasswordEncoder() : new NativePasswordEncoder(null, null, null, \PASSWORD_ARGON2ID);
98111
preg_match('# Encoded password\s+(\$argon2id?\$[\w,=\$+\/]+={0,2})\s+#', $output, $matches);
99112
$hash = $matches[1];
100113
$this->assertTrue($encoder->isPasswordValid($hash, 'password', null));
@@ -195,12 +208,9 @@ public function testEncodePasswordNativeOutput()
195208
$this->assertStringNotContainsString(' Generated salt ', $this->passwordEncoderCommandTester->getDisplay());
196209
}
197210

198-
/**
199-
* @group legacy
200-
*/
201211
public function testEncodePasswordArgon2iOutput()
202212
{
203-
if (!Argon2iPasswordEncoder::isSupported()) {
213+
if (!(SodiumPasswordEncoder::isSupported() && !\defined('SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13')) && !\defined('PASSWORD_ARGON2I')) {
204214
$this->markTestSkipped('Argon2i algorithm not available.');
205215
}
206216

@@ -214,6 +224,22 @@ public function testEncodePasswordArgon2iOutput()
214224
$this->assertStringNotContainsString(' Generated salt ', $this->passwordEncoderCommandTester->getDisplay());
215225
}
216226

227+
public function testEncodePasswordArgon2idOutput()
228+
{
229+
if (!(SodiumPasswordEncoder::isSupported() && \defined('SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13')) && !\defined('PASSWORD_ARGON2ID')) {
230+
$this->markTestSkipped('Argon2id algorithm not available.');
231+
}
232+
233+
$this->setupArgon2id();
234+
$this->passwordEncoderCommandTester->execute([
235+
'command' => 'security:encode-password',
236+
'password' => 'p@ssw0rd',
237+
'user-class' => 'Custom\Class\Argon2id\User',
238+
], ['interactive' => false]);
239+
240+
$this->assertStringNotContainsString(' Generated salt ', $this->passwordEncoderCommandTester->getDisplay());
241+
}
242+
217243
public function testEncodePasswordSodiumOutput()
218244
{
219245
if (!SodiumPasswordEncoder::isSupported()) {
@@ -317,6 +343,19 @@ private function setupArgon2i()
317343
$this->passwordEncoderCommandTester = new CommandTester($passwordEncoderCommand);
318344
}
319345

346+
private function setupArgon2id()
347+
{
348+
putenv('COLUMNS='.(119 + \strlen(PHP_EOL)));
349+
$kernel = $this->createKernel(['test_case' => 'PasswordEncode', 'root_config' => 'argon2id.yml']);
350+
$kernel->boot();
351+
352+
$application = new Application($kernel);
353+
354+
$passwordEncoderCommand = $application->get('security:encode-password');
355+
356+
$this->passwordEncoderCommandTester = new CommandTester($passwordEncoderCommand);
357+
}
358+
320359
private function setupBcrypt()
321360
{
322361
putenv('COLUMNS='.(119 + \strlen(PHP_EOL)));
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
imports:
2+
- { resource: config.yml }
3+
4+
security:
5+
encoders:
6+
Custom\Class\Argon2id\User:
7+
algorithm: argon2id

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.