Skip to content

Commit

Permalink
Fixed directory on persistent secret key not being created automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
mnavarrocarter committed Dec 29, 2020
1 parent dc26265 commit 0fc4a77
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 6 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"require-dev": {
"phpunit/phpunit": "^9.0",
"friendsofphp/php-cs-fixer": "^2.16",
"vimeo/psalm": "^3.7"
"vimeo/psalm": "^3.7",
"adlawson/vfs": "^0.12.1"
},
"scripts": {
"lint": "php-cs-fixer fix --ansi",
Expand Down
62 changes: 61 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions src/key/SecretKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

namespace Legatus\Support;

use RuntimeException;
use SodiumException;

/**
Expand All @@ -27,16 +28,21 @@ class SecretKey
private string $bytes;

/**
* @param string $filename
* @param string $filename
* @param Random|null $random
*
* @return SecretKey
*
* @throws SodiumException
*/
public static function persistent(string $filename): SecretKey
public static function persistent(string $filename, Random $random = null): SecretKey
{
if (!is_file($filename)) {
$key = static::generate();
$dir = dirname($filename);
if (!is_dir($dir) && !mkdir($dir, 0750, true) && !is_dir($dir)) {
throw new RuntimeException("Could not create directory \"$dir\"");
}
$key = static::generate($random);
file_put_contents($filename, $key->toString());
}

Expand Down Expand Up @@ -100,7 +106,7 @@ public function decrypt(string $cipher, string $nonce): string
private function guard(): void
{
if (strlen($this->bytes) !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
throw new \RuntimeException(sprintf('The key length must be %s bytes in size', SODIUM_CRYPTO_SECRETBOX_KEYBYTES));
throw new RuntimeException(sprintf('The key length must be %s bytes in size', SODIUM_CRYPTO_SECRETBOX_KEYBYTES));
}
}

Expand Down
60 changes: 60 additions & 0 deletions tests/FixedRandom.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

/*
* @project Legatus Crypto
* @link https://github.com/legatus-php/crypto
* @package legatus/crypto
* @author Matias Navarro-Carter mnavarrocarter@gmail.com
* @license MIT
* @copyright 2021 Matias Navarro-Carter
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Legatus\Support;

/**
* Class FixedRandom.
*/
final class FixedRandom implements Random
{
private string $bytes;

/**
* @param int $bytes
*
* @return FixedRandom
*/
public static function ofLength(int $bytes): FixedRandom
{
return self::fromUint8Array(...range(0, $bytes));
}

/**
* @param int ...$bytes
*
* @return FixedRandom
*/
public static function fromUint8Array(int ...$bytes): FixedRandom
{
return new self(implode('', array_map('chr', $bytes)));
}

public function __construct(string $bytes)
{
$this->bytes = $bytes;
}

/**
* @param int $bytes
*
* @return string
*/
public function read(int $bytes): string
{
return substr($this->bytes, 0, $bytes);
}
}
43 changes: 43 additions & 0 deletions tests/SecretKeyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

/*
* @project Legatus Crypto
* @link https://github.com/legatus-php/crypto
* @package legatus/crypto
* @author Matias Navarro-Carter mnavarrocarter@gmail.com
* @license MIT
* @copyright 2021 Matias Navarro-Carter
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Legatus\Support;

use PHPUnit\Framework\TestCase;
use Vfs\FileSystem;

class SecretKeyTest extends TestCase
{
public function testItGeneratesASecretKey(): void
{
$random = FixedRandom::ofLength(32);
$key = SecretKey::generate($random)->toString();
self::assertSame('AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8', $key);
}

public function testItGeneratesAPersistentSecretKey(): void
{
$fs = FileSystem::factory('vfs://');
$fs->mount();

$random = FixedRandom::ofLength(32);
$key = SecretKey::persistent('vfs://data/secret.key', $random)->toString();
self::assertSame('AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8', $key);
self::assertFileExists('vfs://data/secret.key');

$fs->unmount();
}
}

0 comments on commit 0fc4a77

Please sign in to comment.