Skip to content

Commit

Permalink
Fix regression in #170
Browse files Browse the repository at this point in the history
  • Loading branch information
paragonie-security committed Apr 11, 2023
1 parent 90be713 commit b314846
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 9 deletions.
41 changes: 32 additions & 9 deletions src/Purpose.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,26 @@

use ParagonIE\Paseto\Exception\ExceptionCode;
use ParagonIE\Paseto\Exception\InvalidPurposeException;
use ParagonIE\Paseto\Keys\{Base\AsymmetricPublicKey, Base\AsymmetricSecretKey, Base\SymmetricKey};
use ParagonIE\Paseto\Keys\Version3\{AsymmetricPublicKey as V3AsymmetricPublicKey,
use ParagonIE\Paseto\Keys\{
AsymmetricPublicKey as LegacyAsymmetricPublicKey,
AsymmetricSecretKey as LegacyAsymmetricSecretKey,
SymmetricKey as LegacySymmetricKey
};
use ParagonIE\Paseto\Keys\Base\{
AsymmetricPublicKey,
AsymmetricSecretKey,
SymmetricKey
};
use ParagonIE\Paseto\Keys\Version3\{
AsymmetricPublicKey as V3AsymmetricPublicKey,
AsymmetricSecretKey as V3AsymmetricSecretKey,
SymmetricKey as V3SymmetricKey};
use ParagonIE\Paseto\Keys\Version4\{AsymmetricPublicKey as V4AsymmetricPublicKey,
SymmetricKey as V3SymmetricKey
};
use ParagonIE\Paseto\Keys\Version4\{
AsymmetricPublicKey as V4AsymmetricPublicKey,
AsymmetricSecretKey as V4AsymmetricSecretKey,
SymmetricKey as V4SymmetricKey};
SymmetricKey as V4SymmetricKey
};
use function get_class;
use function hash_equals;
use function in_array;
Expand Down Expand Up @@ -45,10 +58,12 @@ final class Purpose
* @const array<string, string>
*/
const SENDING_KEY_MAP = [
LegacySymmetricKey::class => 'local',
SymmetricKey::class => 'local',
V3SymmetricKey::class => 'local',
V4SymmetricKey::class => 'local',
AsymmetricSecretKey::class => 'public',
LegacyAsymmetricSecretKey::class => 'public',
V3AsymmetricSecretKey::class => 'public',
V4AsymmetricSecretKey::class => 'public',
];
Expand All @@ -68,10 +83,12 @@ final class Purpose
* @const array<string, string>
*/
const RECEIVING_KEY_MAP = [
LegacySymmetricKey::class => 'local',
SymmetricKey::class => 'local',
V3SymmetricKey::class => 'local',
V4SymmetricKey::class => 'local',
AsymmetricPublicKey::class => 'public',
LegacyAsymmetricPublicKey::class => 'public',
V3AsymmetricPublicKey::class => 'public',
V4AsymmetricPublicKey::class => 'public',
];
Expand Down Expand Up @@ -147,11 +164,14 @@ public static function public(): self
public static function fromSendingKey(SendingKey $key): self
{
if (empty(self::$sendingKeyToPurpose)) {
/** @var array<string, string> */
self::$sendingKeyToPurpose = self::SENDING_KEY_MAP;
}
$keyClass = get_class($key);
if (!array_key_exists($keyClass, self::$sendingKeyToPurpose)) {
throw new InvalidPurposeException('Unknown key class:' . $keyClass);
}

return new self(self::$sendingKeyToPurpose[get_class($key)]);
return new self(self::$sendingKeyToPurpose[$keyClass]);
}

/**
Expand All @@ -165,8 +185,11 @@ public static function fromSendingKey(SendingKey $key): self
public static function fromReceivingKey(ReceivingKey $key): self
{
if (empty(self::$receivingKeyToPurpose)) {
/** @var array<string, string> */
self::$sendingKeyToPurpose = self::RECEIVING_KEY_MAP;
self::$receivingKeyToPurpose = self::RECEIVING_KEY_MAP;
}
$keyClass = get_class($key);
if (!array_key_exists($keyClass, self::$receivingKeyToPurpose)) {
throw new InvalidPurposeException('Unknown key class:' . $keyClass);
}

return new self(self::$receivingKeyToPurpose[get_class($key)]);
Expand Down
126 changes: 126 additions & 0 deletions tests/PurposeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php
declare(strict_types=1);
namespace ParagonIE\Paseto\Tests;

use ParagonIE\Paseto\Keys\{
AsymmetricSecretKey as LegacyAsymmetricSecretKey,
SymmetricKey as LegacySymmetricKey
};
use ParagonIE\Paseto\Keys\Base\{
AsymmetricPublicKey,
AsymmetricSecretKey,
SymmetricKey
};
use ParagonIE\Paseto\Keys\Version3\{
AsymmetricSecretKey as V3AsymmetricSecretKey,
SymmetricKey as V3SymmetricKey
};
use ParagonIE\Paseto\Keys\Version4\{
AsymmetricSecretKey as V4AsymmetricSecretKey,
SymmetricKey as V4SymmetricKey
};
use ParagonIE\Paseto\{
Exception\InvalidPurposeException,
Purpose,
ReceivingKey,
SendingKey
};
use PHPUnit\Framework\TestCase;
use Exception;

class PurposeTest extends TestCase
{
protected bool $setUpAtRuntime = false;
protected AsymmetricSecretKey $bsk;
protected AsymmetricPublicKey $bpk;
protected SymmetricKey $bk;
protected AsymmetricSecretKey $lsk;
protected AsymmetricPublicKey $lpk;
protected SymmetricKey $lk;
protected AsymmetricSecretKey $sk3;
protected AsymmetricPublicKey $pk3;
protected SymmetricKey $k3;
protected AsymmetricSecretKey $sk4;
protected AsymmetricPublicKey $pk4;
protected SymmetricKey $k4;

/**
* @return void
*
* @throws Exception
*/
public function setUp(): void
{
$this->bsk = AsymmetricSecretKey::generate();
$this->bpk = $this->bsk->getPublicKey();
$this->bk = SymmetricKey::generate();

$this->lsk = LegacyAsymmetricSecretKey::generate();
$this->lpk = $this->lsk->getPublicKey();
$this->lk = LegacySymmetricKey::generate();

$this->sk3 = V3AsymmetricSecretKey::generate();
$this->pk3 = $this->sk3->getPublicKey();
$this->k3 = V3SymmetricKey::generate();

$this->sk4 = V4AsymmetricSecretKey::generate();
$this->pk4 = $this->sk4->getPublicKey();
$this->k4 = V4SymmetricKey::generate();
}

public function receivingKeyProvider(): array
{
if (!$this->setUpAtRuntime) {
$this->setUp();
}
return [
[$this->bk, 'local'],
[$this->lpk, 'public'],
[$this->pk3, 'public'],
[$this->pk4, 'public'],
[$this->lk, 'local']
];
}

public function sendingKeyProvider(): array
{
if (!$this->setUpAtRuntime) {
$this->setUp();
}
return [
[$this->bk, 'local'],
[$this->lsk, 'public'],
[$this->sk3, 'public'],
[$this->sk4, 'public'],
[$this->lk, 'local']
];
}

/**
* @dataProvider receivingKeyProvider
*
* @param ReceivingKey $key
* @param string $expected
* @return void
* @throws InvalidPurposeException
*/
public function testReceivingMapping(ReceivingKey $key, string $expected): void
{
$purpose = Purpose::fromReceivingKey($key);
$this->assertSame($expected, $purpose->rawString());
}

/**
* @dataProvider sendingKeyProvider
*
* @param SendingKey $key
* @param string $expected
* @return void
* @throws InvalidPurposeException
*/
public function testSendingMapping(SendingKey $key, string $expected): void
{
$purpose = Purpose::fromSendingKey($key);
$this->assertSame($expected, $purpose->rawString());
}
}

0 comments on commit b314846

Please sign in to comment.