Skip to content

Commit

Permalink
Merge pull request #11 from paragonie/v2-dev
Browse files Browse the repository at this point in the history
PASERK Version 2 (removes deprecated protocol versions)
  • Loading branch information
paragonie-security authored Jun 3, 2022
2 parents 27aa8ae + 87960f4 commit 41da5e9
Show file tree
Hide file tree
Showing 79 changed files with 855 additions and 2,436 deletions.
27 changes: 1 addition & 26 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,13 @@ name: CI
on: [push]

jobs:
moderate:
name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
operating-system: ['ubuntu-latest']
php-versions: ['7.1', '7.2', '7.3']
phpunit-versions: ['latest']
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
extensions: gmp, mbstring, intl, sodium
ini-values: max_execution_time=180

- name: Install dependencies
run: composer install

- name: Test Suite
run: composer test

modern:
name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
operating-system: ['ubuntu-latest']
php-versions: ['7.4', '8.0', '8.1']
php-versions: ['8.1']
phpunit-versions: ['latest']
steps:
- name: Checkout
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ The PASERK Specification can be found [in this repository](https://github.com/pa
composer require paragonie/paserk
```

### PASERK Library Versions

* PASERK PHP Version 2
* Requires PHP 8.1+
* PASETO versions: `v3`, `v4`
* This means only the corresponding `k3` and `k4` modes are implemented.
* [PASERK PHP Version 1](https://github.com/paragonie/paserk-php/tree/v1.x)
* Requires PHP 7.1+
* PASETO versions: `v1`, `v2`, `v3`, `v4`
* This provides a stable reference implementation for the PASERK specification.

## Documentation

See [this directory](docs) for the documentation.
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@
}
},
"require": {
"php": "^7.1|^8",
"php": "^8.1",
"ext-gmp": "*",
"ext-json": "*",
"ext-openssl": "*",
"paragonie/easy-ecc": "^1",
"paragonie/hidden-string": "^1|^2",
"paragonie/paseto": ">=2.2"
"paragonie/paseto": "^3"
},
"require-dev": {
"phpunit/phpunit": "^7|^8|^9",
"phpunit/phpunit": "^9",
"vimeo/psalm": "^4"
},
"scripts": {
Expand Down
16 changes: 8 additions & 8 deletions docs/Types/Pid.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Example code:
```php
<?php
use ParagonIE\Paserk\Types\Pid;
use ParagonIE\Paseto\Protocol\Version2;
use ParagonIE\Paseto\Protocol\Version3;
use ParagonIE\Paseto\Protocol\Version4;
use ParagonIE\Paseto\Keys\AsymmetricSecretKey;
use ParagonIE\Paseto\Keys\AsymmetricPublicKey;
Expand All @@ -16,21 +16,21 @@ $examplePublicKeyV4 = $exampleSecretKeyV4->getPublicKey();
$publicIdV4 = Pid::encodePublic($examplePublicKeyV4);
var_dump($publicIdV4);

// Now let's change the version to v2
$exampleSecretKeyV2 = new AsymmetricSecretKey($exampleSecretKeyV4->raw(), new Version2);
$examplePublicKeyV2 = $exampleSecretKeyV2->getPublicKey();
$publicIdV2 = Pid::encodePublic($examplePublicKeyV2);
var_dump($publicIdV2);
// Now let's change the version to v3
$exampleSecretKeyV3 = new AsymmetricSecretKey($exampleSecretKeyV4->raw(), new Version3);
$examplePublicKeyV3 = $exampleSecretKeyV2->getPublicKey();
$publicIdV3 = Pid::encodePublic($examplePublicKeyV3);
var_dump($publicIdV3);

// This will always be bool(false)
var_dump($publicIdV2 === $publicIdV4);
var_dump($publicIdV3 === $publicIdV4);
```

Example output:

```
string(51) "k4.pid.7YHEK_2Pbpe1pB3520MjzTe2sGcA0pV54SyIt2qMgAcq"
string(51) "k2.pid.Yh_AqamsJznJMNU6qZ2xZGSs9IyW3b12e7W-rR6wLYDw"
string(51) "k3.pid.Yh_AqamsJznJMNU6qZ2xZGSs9IyW3b12e7W-rR6wLYDw"
bool(false)
```

Expand Down
14 changes: 7 additions & 7 deletions docs/Types/Sid.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Example code:
```php
<?php
use ParagonIE\Paserk\Types\Sid;
use ParagonIE\Paseto\Protocol\Version2;
use ParagonIE\Paseto\Protocol\Version3;
use ParagonIE\Paseto\Protocol\Version4;
use ParagonIE\Paseto\Keys\AsymmetricSecretKey;

Expand All @@ -14,20 +14,20 @@ $exampleSecretKeyV4 = AsymmetricSecretKey::generate(new Version4());
$secretIdV4 = Sid::encodeSecret($exampleSecretKeyV4);
var_dump($secretIdV4);

// Now let's change the version to v2
$exampleSecretKeyV2 = new AsymmetricSecretKey($exampleSecretKeyV4->raw(), new Version2);
$secretIdV2 = Sid::encodeSecret($exampleSecretKeyV2);
var_dump($secretIdV2);
// Now let's change the version to v3
$exampleSecretKeyV3 = new AsymmetricSecretKey($exampleSecretKeyV4->raw(), new Version3);
$secretIdV3 = Sid::encodeSecret($exampleSecretKeyV3);
var_dump($secretIdV3);

// This will always be bool(false)
var_dump($secretIdV2 === $secretIdV4);
var_dump($secretIdV3 === $secretIdV4);
```

Example output:

```
string(51) "k4.sid.Vt47YKER1_S7N2zj8CjpQMfoKdOu5l1vq_RctB9CYqhO"
string(51) "k2.sid.sESo8mlDN5bjjO-vnZ96QJ-jrgbg-YO35emyHC19V3bD"
string(51) "k3.sid.sESo8mlDN5bjjO-vnZ96QJ-jrgbg-YO35emyHC19V3bD"
bool(false)
```

Expand Down
6 changes: 3 additions & 3 deletions src/ConstraintTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
trait ConstraintTrait
{
/** @var ?ProtocolCollection $collection */
protected $collection;
protected ?ProtocolCollection $collection = null;

/**
* Specify the allowed protocols for this PASERK type.
*
* @param ProtocolCollection|null $collection
* @return self
* @return static
*/
public function setProtocolsAllowed(?ProtocolCollection $collection = null): self
public function setProtocolsAllowed(?ProtocolCollection $collection = null): static
{
$this->collection = $collection;
return $this;
Expand Down
6 changes: 2 additions & 4 deletions src/IdCommonTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
Sid
};
use ParagonIE\Paseto\Protocol\{
Version1,
Version2,
Version3,
Version4
};
Expand Down Expand Up @@ -56,13 +54,13 @@ final public static function decode(...$args): void
public static function encode(ProtocolInterface $version, string $paserk): string
{
$header = Util::getPaserkHeader($version) . '.' . self::getTypeLabel() . '.';
if ($version instanceof Version1 || $version instanceof Version3) {
if ($version instanceof Version3) {
$hash = Binary::safeSubstr(
hash('sha384', $header . $paserk, true),
0,
33
);
} elseif ($version instanceof Version2 || $version instanceof Version4) {
} elseif ($version instanceof Version4) {
$hash = sodium_crypto_generichash(
$header . $paserk,
'',
Expand Down
8 changes: 3 additions & 5 deletions src/Operations/Key/SealingPublicKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use ParagonIE\Paserk\PaserkException;
use ParagonIE\Paseto\Keys\AsymmetricPublicKey;
use ParagonIE\Paseto\Protocol\Version1;
use Exception;

/**
* Class SealingPublicKey
Expand All @@ -14,14 +14,12 @@ class SealingPublicKey extends AsymmetricPublicKey
{
/**
* @return AsymmetricPublicKey
*
* @throws PaserkException
* @throws Exception
*/
public function toPasetoKey(): AsymmetricPublicKey
{
if ($this->protocol instanceof Version1) {
throw new PaserkException("Version 1 keys cannot be converted!");
}

return new AsymmetricPublicKey(
$this->key,
$this->protocol
Expand Down
28 changes: 6 additions & 22 deletions src/Operations/Key/SealingSecretKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
declare(strict_types=1);
namespace ParagonIE\Paserk\Operations\Key;

use ParagonIE\Paserk\PaserkException;
use ParagonIE\EasyECC\ECDSA\{
PublicKey,
SecretKey
Expand All @@ -13,9 +12,8 @@
AsymmetricSecretKey
};
use ParagonIE\Paseto\Protocol\{
Version1,
Version2,
Version3
Version3,
Version4
};
use ParagonIE\Paseto\ProtocolInterface;
use ParagonIE\Paseto\Util;
Expand Down Expand Up @@ -46,14 +44,8 @@ class SealingSecretKey extends AsymmetricSecretKey
*/
public static function generate(ProtocolInterface $protocol = null): AsymmetricSecretKey
{
$protocol = $protocol ?? new Version2;

if (hash_equals($protocol::header(), Version1::HEADER)) {
$rsa = Version1::getRsa();
/** @var array<string, string> $keypair */
$keypair = $rsa->createKey(4096);
return new self(Util::dos2unix($keypair['privatekey']), $protocol);
} elseif (hash_equals($protocol::header(), Version3::HEADER)) {
$protocol = $protocol ?? new Version4;
if (hash_equals($protocol::header(), Version3::HEADER)) {
return new self(
Util::dos2unix(SecretKey::generate(Version3::CURVE)->exportPem()),
$protocol
Expand All @@ -69,14 +61,11 @@ public static function generate(ProtocolInterface $protocol = null): AsymmetricS

/**
* @return AsymmetricSecretKey
* @throws PaserkException
*
* @throws Exception
*/
public function toPasetoKey(): AsymmetricSecretKey
{
if ($this->protocol instanceof Version1) {
throw new PaserkException("Version 1 keys cannot be converted!");
}

return new AsymmetricSecretKey(
$this->key,
$this->protocol
Expand All @@ -92,11 +81,6 @@ public function toPasetoKey(): AsymmetricSecretKey
public function getPublicKey(): AsymmetricPublicKey
{
switch ($this->protocol::header()) {
case Version1::HEADER:
return new SealingPublicKey(
Version1::RsaGetPublicKey($this->key),
$this->protocol
);
case Version3::HEADER:
/** @var PublicKey $pk */
$pk = SecretKey::importPem($this->key)->getPublicKey();
Expand Down
14 changes: 4 additions & 10 deletions src/Operations/PBKW.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

use ParagonIE\HiddenString\HiddenString;
use ParagonIE\Paserk\Operations\PBKW\{
PBKWv1,
PBKWv2,
PBKWv3,
PBKWv4
};
Expand All @@ -15,6 +13,7 @@
SymmetricKey
};
use ParagonIE\Paseto\ProtocolInterface;
use TypeError;
use function
array_pop,
explode,
Expand All @@ -30,8 +29,7 @@ class PBKW
const DOMAIN_SEPARATION_ENCRYPT = "\xff";
const DOMAIN_SEPARATION_AUTH = "\xfe";

/** @var PBKWInterface $wrapper */
protected $wrapper;
protected PBKWInterface $wrapper;

/**
* PBKW constructor.
Expand All @@ -50,10 +48,6 @@ public function __construct(PBKWInterface $wrapper)
public static function forVersion(ProtocolInterface $version): self
{
switch ($version::header()) {
case 'v1':
return new PBKW(new PBKWv1());
case 'v2':
return new PBKW(new PBKWv2());
case 'v3':
return new PBKW(new PBKWv3());
case 'v4':
Expand Down Expand Up @@ -106,7 +100,7 @@ public function localPwUnwrap(
$password
);
if (!($unwrapped instanceof SymmetricKey)) {
throw new \TypeError();
throw new TypeError();
}
return $unwrapped;
}
Expand Down Expand Up @@ -155,7 +149,7 @@ public function secretPwUnwrap(
$password
);
if (!($unwrapped instanceof AsymmetricSecretKey)) {
throw new \TypeError();
throw new TypeError();
}
return $unwrapped;
}
Expand Down
Loading

0 comments on commit 41da5e9

Please sign in to comment.