Skip to content

Commit

Permalink
Merge pull request #175 from oojacoboo/php8.4
Browse files Browse the repository at this point in the history
PHP 8.4 Support
  • Loading branch information
paragonie-security authored Jan 29, 2025
2 parents abecd5a + af4247a commit 2a69032
Show file tree
Hide file tree
Showing 27 changed files with 208 additions and 145 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
matrix:
operating-system: ['ubuntu-latest']
php-versions: ['8.1', '8.2', '8.3']
php-versions: ['8.1', '8.2', '8.3', '8.4']
phpunit-versions: ['latest']
steps:
- name: Checkout
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/.idea
/.phpunit.result.cache
/composer.lock
/vendor
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
"paragonie/sodium_compat": "^1|^2"
},
"require-dev": {
"phpunit/phpunit": "^9",
"vimeo/psalm": "^4|^5"
"phpunit/phpunit": "^10",
"vimeo/psalm": "dev-master"
},
"scripts": {
"full-test": [
Expand Down
9 changes: 5 additions & 4 deletions docs/Features.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ the fact that the header is always authenticated, and the suffix exists in the h

## Specifying Version and Purpose

In PASETO, the Version and Purpose are a part of the cryptographic material's identity
In PASETO, the Version and Purpose are a part of the cryptographic material's identity
(not just its raw bytes). That means that each key can be used with at most one of the
8 combinations of version and purpose.

Expand All @@ -65,7 +65,7 @@ PASETO tokens typically have this format:

[version].[purpose].[data]

However, it's possible to append optional data to the end of a PASETO, which will also be
However, it's possible to append optional data to the end of a PASETO, which will also be
authenticated. This yields the following format:

[version].[purpose].[data].[footer]
Expand Down Expand Up @@ -98,7 +98,7 @@ use ParagonIE\Paseto\Keys\Base\SymmetricKey;use ParagonIE\Paseto\Parser;use Para
/** @var SymmetricKey $key */
$parser = Parser::getLocal($key)
->addRule(
(new FooterJSON())
new FooterJSON
->setMaxLength(1024) // Maximum length of JSON payload in footer
->setMaxKeys(16) // Maximum number of object keys
->setMaxDepth(3) // Recursive depth to JSON structure
Expand All @@ -117,7 +117,8 @@ You can set the implicit assertions in the Builder...

```php
<?php
use ParagonIE\Paseto\Builder;use ParagonIE\Paseto\Keys\Base\SymmetricKey;
use ParagonIE\Paseto\Builder;
use ParagonIE\Paseto\Keys\Base\SymmetricKey;

/** @var SymmetricKey $key */
$builder = Builder::getLocal($key)
Expand Down
12 changes: 6 additions & 6 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

If you're not already familiar with PASETO, you can learn more about its features
[here](Features.md). If you were using an older version of PASETO, the
[migration guide](Migration.md) is worth a read.
[migration guide](Migration.md) is worth a read.

Most of the supporting documentation has been moved to the
Most of the supporting documentation has been moved to the
[PASETO specification](https://github.com/paseto-standard/paseto-spec) repository.

## How to use the PHP library
Expand Down Expand Up @@ -69,7 +69,7 @@ use ParagonIE\Paseto\Keys\Base\SymmetricKey;use ParagonIE\Paseto\Protocol\Versio
* We assume the same key $sharedKey was used from above.
* @var SymmetricKey $sharedKey
*/

$token = Version4::sign('some arbitrary data', $sharedKey);
```

Expand Down Expand Up @@ -129,7 +129,7 @@ $parser = Parser::getLocal($sharedKey, ProtocolCollection::v4())
->addRule(new IssuedBy('issuer defined during creation'));

// This is the same as:
$parser = (new Parser())
$parser = new Parser
->setKey($sharedKey)
// Adding rules to be checked against the token
->addRule(new ValidAt)
Expand Down Expand Up @@ -168,13 +168,13 @@ use ParagonIE\Paseto\Keys\Base\AsymmetricPublicKey;use ParagonIE\Paseto\Keys\Bas
* @var AsymmetricPublicKey $pk1
* @var AsymmetricPublicKey $pk2
*/
$keyring = (new ReceivingKeyRing())
$keyring = new ReceivingKeyRing
->setVersion(new Version4)
->setPurpose(Purpose::public())
->addKey('gandalf0', $pk1)
->addKey('legolas1', $pk2);

$otherKeyring = (new ReceivingKeyRing())
$otherKeyring = new ReceivingKeyRing
->setVersion(new Version4)
->setPurpose(Purpose::local())
->addKey('boromir2', $localKey);
Expand Down
37 changes: 19 additions & 18 deletions src/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ class Builder extends PasetoBase
* @throws PasetoException
*/
public function __construct(
JsonToken $baseToken = null,
ProtocolInterface $protocol = null,
SendingKey $key = null
?JsonToken $baseToken = null,
?ProtocolInterface $protocol = null,
?SendingKey $key = null
) {
if (!$baseToken) {
$baseToken = new JsonToken();
Expand Down Expand Up @@ -176,8 +176,8 @@ public function getImplicitAssertions(): array
*/
public static function getLocal(
SymmetricKey $key,
ProtocolInterface $version = null,
JsonToken $baseToken = null
?ProtocolInterface $version = null,
?JsonToken $baseToken = null
): self {
if (!$version) {
$version = $key->getProtocol();
Expand All @@ -202,8 +202,8 @@ public static function getLocal(
*/
public static function getLocalWithKeyRing(
SendingKeyRing $key,
ProtocolInterface $version = null,
JsonToken $baseToken = null
?ProtocolInterface $version = null,
?JsonToken $baseToken = null
): self {
if (!$version) {
$version = $key->getProtocol();
Expand All @@ -228,8 +228,8 @@ public static function getLocalWithKeyRing(
*/
public static function getPublic(
AsymmetricSecretKey $key,
ProtocolInterface $version = null,
JsonToken $baseToken = null
?ProtocolInterface $version = null,
?JsonToken $baseToken = null
): self {
if (!$version) {
$version = $key->getProtocol();
Expand All @@ -254,8 +254,8 @@ public static function getPublic(
*/
public static function getPublicWithKeyRing(
SendingKeyRing $key,
ProtocolInterface $version = null,
JsonToken $baseToken = null
?ProtocolInterface $version = null,
?JsonToken $baseToken = null
): self {
if (!$version) {
$version = $key->getProtocol();
Expand Down Expand Up @@ -308,7 +308,7 @@ public function setAudience(string $aud): self
* @param DateTimeInterface|null $time
* @return self
*/
public function setExpiration(DateTimeInterface $time = null): self
public function setExpiration(?DateTimeInterface $time = null): self
{
if (!$time) {
$time = new DateTime('NOW');
Expand Down Expand Up @@ -348,7 +348,7 @@ public function setImplicitAssertions(array $assertions): self
* @param DateTimeInterface|null $time
* @return self
*/
public function setIssuedAt(DateTimeInterface $time = null): self
public function setIssuedAt(?DateTimeInterface $time = null): self
{
if (!$time) {
$time = new DateTime('NOW');
Expand Down Expand Up @@ -384,7 +384,7 @@ public function setJti(string $id): self
* @param DateTimeInterface|null $time
* @return self
*/
public function setNotBefore(DateTimeInterface $time = null): self
public function setNotBefore(?DateTimeInterface $time = null): self
{
if (!$time) {
$time = new DateTime('NOW');
Expand Down Expand Up @@ -569,7 +569,7 @@ public function setJsonToken(JsonToken $token): self
*
* @return self
*/
public function setVersion(ProtocolInterface $version = null): self
public function setVersion(?ProtocolInterface $version = null): self
{
if (!$version) {
$version = new Version4();
Expand Down Expand Up @@ -615,6 +615,7 @@ public function toString(): string
->format(DateTime::ATOM);
}
$claims = json_encode($claimsArray, JSON_FORCE_OBJECT);
assert(is_string($claims));
$protocol = $this->version;
ProtocolCollection::throwIfUnsupported($protocol);

Expand Down Expand Up @@ -716,7 +717,7 @@ public function withClaims(array $claims): self
* @param DateTimeInterface|null $time
* @return self
*/
public function withExpiration(DateTimeInterface $time = null): self
public function withExpiration(?DateTimeInterface $time = null): self
{
return (clone $this)->setExpiration($time);
}
Expand Down Expand Up @@ -765,7 +766,7 @@ public function withImplicitAssertions(array $implicit): self
* @param DateTimeInterface|null $time
* @return self
*/
public function withIssuedAt(DateTimeInterface $time = null): self
public function withIssuedAt(?DateTimeInterface $time = null): self
{
return (clone $this)->setIssuedAt($time);
}
Expand Down Expand Up @@ -798,7 +799,7 @@ public function withJti(string $id): self
* @param DateTimeInterface|null $time
* @return self
*/
public function withNotBefore(DateTimeInterface $time = null): self
public function withNotBefore(?DateTimeInterface $time = null): self
{
return (clone $this)->setNotBefore($time);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Exception/PasetoException.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

/**
* Class PasetoException
*
* @package ParagonIE\Paseto\Exception
*/
class PasetoException extends Exception
Expand All @@ -16,7 +17,7 @@ class PasetoException extends Exception
* @param int $code
* @param Throwable|null $previous
*/
public function __construct($message = "", $code = 0, Throwable $previous = null)
public function __construct($message = "", $code = 0, ?Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
$this->setHelpfulMessage(ExceptionCode::explainErrorCode($code));
Expand Down
14 changes: 7 additions & 7 deletions src/JsonToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public function has(string $claim): bool
{
return array_key_exists($claim, $this->claims);
}

/**
* Set a claim to an arbitrary value.
*
Expand Down Expand Up @@ -241,7 +241,7 @@ public function setClaims(array $claims): self
* @param DateTimeInterface|null $time
* @return self
*/
public function setExpiration(DateTimeInterface $time = null): self
public function setExpiration(?DateTimeInterface $time = null): self
{
if (!$time) {
$time = new DateTime('NOW');
Expand Down Expand Up @@ -287,7 +287,7 @@ public function setFooterArray(array $footer = []): self
* @param DateTimeInterface|null $time
* @return self
*/
public function setIssuedAt(DateTimeInterface $time = null): self
public function setIssuedAt(?DateTimeInterface $time = null): self
{
if (!$time) {
$time = new DateTime('NOW');
Expand Down Expand Up @@ -326,7 +326,7 @@ public function setJti(string $id): self
* @param DateTimeInterface|null $time
* @return self
*/
public function setNotBefore(DateTimeInterface $time = null): self
public function setNotBefore(?DateTimeInterface $time = null): self
{
if (!$time) {
$time = new DateTime('NOW');
Expand Down Expand Up @@ -387,7 +387,7 @@ public function withClaims(array $claims): self
* @param DateTimeInterface|null $time
* @return self
*/
public function withExpiration(DateTimeInterface $time = null): self
public function withExpiration(?DateTimeInterface $time = null): self
{
return (clone $this)->setExpiration($time);
}
Expand Down Expand Up @@ -422,7 +422,7 @@ public function withFooterArray(array $footer = []): self
* @param DateTimeInterface|null $time
* @return self
*/
public function withIssuedAt(DateTimeInterface $time = null): self
public function withIssuedAt(?DateTimeInterface $time = null): self
{
return (clone $this)->setIssuedAt($time);
}
Expand Down Expand Up @@ -455,7 +455,7 @@ public function withJti(string $id): self
* @param DateTimeInterface|null $time
* @return self
*/
public function withNotBefore(DateTimeInterface $time = null): self
public function withNotBefore(?DateTimeInterface $time = null): self
{
return (clone $this)->setNotBefore($time);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Keys/AsymmetricSecretKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class AsymmetricSecretKey extends BaseAsymmetricSecretKey
{
public function __construct(
string $keyData,
ProtocolInterface $protocol = null
?ProtocolInterface $protocol = null
) {
if (is_null($protocol)) {
$protocol = new Version4();
Expand Down
12 changes: 9 additions & 3 deletions src/Keys/Base/AsymmetricPublicKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ public static function v4(string $keyMaterial): V4AsymmetricPublicKey
*
* @throws Exception
*/
public static function newVersionKey(string $keyMaterial, ProtocolInterface $protocol = null): self
public static function newVersionKey(
string $keyMaterial,
?ProtocolInterface $protocol = null,
): self
{
$protocol = $protocol ?? new Version4();

Expand Down Expand Up @@ -155,7 +158,10 @@ abstract public function encodePem(): string;
* @throws Exception
* @throws TypeError
*/
public static function fromEncodedString(string $encoded, ProtocolInterface $version = null): self
public static function fromEncodedString(
string $encoded,
?ProtocolInterface $version = null,
): self
{
if (!$version) {
$version = new Version4();
Expand All @@ -175,7 +181,7 @@ public static function fromEncodedString(string $encoded, ProtocolInterface $ver
*
* @throws Exception
*/
public static function importPem(string $pem, ProtocolInterface $protocol = null): self
public static function importPem(string $pem, ?ProtocolInterface $protocol = null): self
{
$protocol = $protocol ?? new Version4();

Expand Down
8 changes: 4 additions & 4 deletions src/Keys/Base/AsymmetricSecretKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public static function v4(string $keyMaterial): V4AsymmetricSecretKey
* @throws Exception
* @throws TypeError
*/
public static function generate(ProtocolInterface $protocol = null): self
public static function generate(?ProtocolInterface $protocol = null): self
{
$protocol = $protocol ?? new Version4;
if (hash_equals($protocol::header(), Version3::HEADER)) {
Expand All @@ -178,7 +178,7 @@ public static function generate(ProtocolInterface $protocol = null): self
*
* @throws Exception
*/
public static function newVersionKey(string $keyMaterial, ProtocolInterface $protocol = null): self
public static function newVersionKey(string $keyMaterial, ?ProtocolInterface $protocol = null): self
{
$protocol = $protocol ?? new Version4();

Expand Down Expand Up @@ -216,7 +216,7 @@ abstract public function encodePem(): string;
* @throws Exception
* @throws TypeError
*/
public static function fromEncodedString(string $encoded, ProtocolInterface $version = null): self
public static function fromEncodedString(string $encoded, ?ProtocolInterface $version = null): self
{
if ($version && hash_equals($version::header(), Version3::HEADER)) {
return V3AsymmetricSecretKey::fromEncodedString($encoded);
Expand All @@ -232,7 +232,7 @@ public static function fromEncodedString(string $encoded, ProtocolInterface $ver
*
* @throws Exception
*/
public static function importPem(string $pem, ProtocolInterface $protocol = null): self
public static function importPem(string $pem, ?ProtocolInterface $protocol = null): self
{
$protocol = $protocol ?? new Version4();

Expand Down
Loading

0 comments on commit 2a69032

Please sign in to comment.