Skip to content

Commit

Permalink
Add SensitiveParameter attribute to sensitive parameters
Browse files Browse the repository at this point in the history
Adds `#[SensitiveParameter]` to all potentially sensitive parameters,
including key material, certificates and passphrases.
  • Loading branch information
slknijnenburg committed Nov 7, 2024
1 parent 8cf0783 commit b0e12fc
Show file tree
Hide file tree
Showing 17 changed files with 160 additions and 47 deletions.
7 changes: 6 additions & 1 deletion src/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Lcobucci\JWT\Signer\InvalidKeyProvided;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Token\RegisteredClaimGiven;
use SensitiveParameter;

/** @immutable */
interface Builder
Expand Down Expand Up @@ -81,5 +82,9 @@ public function withClaim(string $name, mixed $value): Builder;
* @throws InvalidKeyProvided When issue key is invalid/incompatible.
* @throws ConversionFailed When signature could not be converted.
*/
public function getToken(Signer $signer, Key $key): UnencryptedToken;
public function getToken(
Signer $signer,
#[SensitiveParameter]
Key $key,
): UnencryptedToken;
}
6 changes: 6 additions & 0 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Lcobucci\JWT\Encoding\JoseEncoder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Validation\Constraint;
use SensitiveParameter;

/**
* Configuration container for the JWT Builder and Parser
Expand All @@ -28,7 +29,9 @@ final class Configuration

private function __construct(
private readonly Signer $signer,
#[SensitiveParameter]
private readonly Key $signingKey,
#[SensitiveParameter]
private readonly Key $verificationKey,
Encoder $encoder,
Decoder $decoder,
Expand All @@ -43,7 +46,9 @@ private function __construct(

public static function forAsymmetricSigner(
Signer $signer,
#[SensitiveParameter]
Key $signingKey,
#[SensitiveParameter]
Key $verificationKey,
Encoder $encoder = new JoseEncoder(),
Decoder $decoder = new JoseEncoder(),
Expand All @@ -59,6 +64,7 @@ public static function forAsymmetricSigner(

public static function forSymmetricSigner(
Signer $signer,
#[SensitiveParameter]
Key $key,
Encoder $encoder = new JoseEncoder(),
Decoder $decoder = new JoseEncoder(),
Expand Down
2 changes: 2 additions & 0 deletions src/JwtFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Lcobucci\JWT\Validation\ValidAt;
use Lcobucci\JWT\Validation\Validator;
use Psr\Clock\ClockInterface as Clock;
use SensitiveParameter;

use function assert;

Expand All @@ -35,6 +36,7 @@ public function now(): DateTimeImmutable
/** @param Closure(Builder, DateTimeImmutable):Builder $customiseBuilder */
public function issue(
Signer $signer,
#[SensitiveParameter]
Key $signingKey,
Closure $customiseBuilder,
): UnencryptedToken {
Expand Down
14 changes: 12 additions & 2 deletions src/Signer.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Lcobucci\JWT\Signer\Ecdsa\ConversionFailed;
use Lcobucci\JWT\Signer\InvalidKeyProvided;
use Lcobucci\JWT\Signer\Key;
use SensitiveParameter;

interface Signer
{
Expand All @@ -28,7 +29,11 @@ public function algorithmId(): string;
* @throws InvalidKeyProvided When issue key is invalid/incompatible.
* @throws ConversionFailed When signature could not be converted.
*/
public function sign(string $payload, Key $key): string;
public function sign(
string $payload,
#[SensitiveParameter]
Key $key,
): string;

/**
* Returns if the expected hash matches with the data and key
Expand All @@ -39,5 +44,10 @@ public function sign(string $payload, Key $key): string;
* @throws InvalidKeyProvided When issue key is invalid/incompatible.
* @throws ConversionFailed When signature could not be converted.
*/
public function verify(string $expected, string $payload, Key $key): bool;
public function verify(
string $expected,
string $payload,
#[SensitiveParameter]
Key $key,
): bool;
}
16 changes: 12 additions & 4 deletions src/Signer/Blake2b.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Lcobucci\JWT\Signer;

use Lcobucci\JWT\Signer;
use SensitiveParameter;

use function hash_equals;
use function sodium_crypto_generichash;
Expand All @@ -18,8 +19,11 @@ public function algorithmId(): string
return 'BLAKE2B';
}

public function sign(string $payload, Key $key): string
{
public function sign(
string $payload,
#[SensitiveParameter]
Key $key,
): string {
$actualKeyLength = 8 * strlen($key->contents());

if ($actualKeyLength < self::MINIMUM_KEY_LENGTH_IN_BITS) {
Expand All @@ -29,8 +33,12 @@ public function sign(string $payload, Key $key): string
return sodium_crypto_generichash($payload, $key->contents());
}

public function verify(string $expected, string $payload, Key $key): bool
{
public function verify(
string $expected,
string $payload,
#[SensitiveParameter]
Key $key,
): bool {
return hash_equals($expected, $this->sign($payload, $key));
}
}
16 changes: 12 additions & 4 deletions src/Signer/Ecdsa.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use Lcobucci\JWT\Signer\Ecdsa\MultibyteStringConverter;
use Lcobucci\JWT\Signer\Ecdsa\SignatureConverter;
use SensitiveParameter;

use const OPENSSL_KEYTYPE_EC;

Expand All @@ -15,16 +16,23 @@ public function __construct(
) {
}

final public function sign(string $payload, Key $key): string
{
final public function sign(
string $payload,
#[SensitiveParameter]
Key $key,
): string {
return $this->converter->fromAsn1(
$this->createSignature($key->contents(), $key->passphrase(), $payload),
$this->pointLength(),
);
}

final public function verify(string $expected, string $payload, Key $key): bool
{
final public function verify(
string $expected,
string $payload,
#[SensitiveParameter]
Key $key,
): bool {
return $this->verifySignature(
$this->converter->toAsn1($expected, $this->pointLength()),
$payload,
Expand Down
16 changes: 12 additions & 4 deletions src/Signer/Eddsa.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Lcobucci\JWT\Signer;

use Lcobucci\JWT\Signer;
use SensitiveParameter;
use SodiumException;

use function sodium_crypto_sign_detached;
Expand All @@ -16,17 +17,24 @@ public function algorithmId(): string
return 'EdDSA';
}

public function sign(string $payload, Key $key): string
{
public function sign(
string $payload,
#[SensitiveParameter]
Key $key,
): string {
try {
return sodium_crypto_sign_detached($payload, $key->contents());
} catch (SodiumException $sodiumException) {
throw new InvalidKeyProvided($sodiumException->getMessage(), 0, $sodiumException);
}
}

public function verify(string $expected, string $payload, Key $key): bool
{
public function verify(
string $expected,
string $payload,
#[SensitiveParameter]
Key $key,
): bool {
try {
return sodium_crypto_sign_verify_detached($expected, $payload, $key->contents());
} catch (SodiumException $sodiumException) {
Expand Down
16 changes: 12 additions & 4 deletions src/Signer/Hmac.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
namespace Lcobucci\JWT\Signer;

use Lcobucci\JWT\Signer;
use SensitiveParameter;

use function hash_equals;
use function hash_hmac;
use function strlen;

abstract class Hmac implements Signer
{
final public function sign(string $payload, Key $key): string
{
final public function sign(
string $payload,
#[SensitiveParameter]
Key $key,
): string {
$actualKeyLength = 8 * strlen($key->contents());
$expectedKeyLength = $this->minimumBitsLengthForKey();

Expand All @@ -23,8 +27,12 @@ final public function sign(string $payload, Key $key): string
return hash_hmac($this->algorithm(), $payload, $key->contents(), true);
}

final public function verify(string $expected, string $payload, Key $key): bool
{
final public function verify(
string $expected,
string $payload,
#[SensitiveParameter]
Key $key,
): bool {
return hash_equals($expected, $this->sign($payload, $key));
}

Expand Down
8 changes: 6 additions & 2 deletions src/Signer/Key/InMemory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Lcobucci\JWT\Signer\InvalidKeyProvided;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\SodiumBase64Polyfill;
use SensitiveParameter;
use SplFileObject;
use Throwable;

Expand All @@ -15,8 +16,11 @@
final class InMemory implements Key
{
/** @param non-empty-string $contents */
private function __construct(public readonly string $contents, public readonly string $passphrase)
{
private function __construct(
public readonly string $contents,
#[SensitiveParameter]
public readonly string $passphrase,
) {
}

/** @param non-empty-string $contents */
Expand Down
23 changes: 17 additions & 6 deletions src/Signer/OpenSSL.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use Lcobucci\JWT\Signer;
use OpenSSLAsymmetricKey;
use SensitiveParameter;

use function array_key_exists;
use function assert;
Expand Down Expand Up @@ -40,7 +41,9 @@ abstract class OpenSSL implements Signer
* @throws InvalidKeyProvided
*/
final protected function createSignature(
#[SensitiveParameter]
string $pem,
#[SensitiveParameter]
string $passphrase,
string $payload,
): string {
Expand All @@ -56,8 +59,12 @@ final protected function createSignature(
}

/** @throws CannotSignPayload */
private function getPrivateKey(string $pem, string $passphrase): OpenSSLAsymmetricKey
{
private function getPrivateKey(
#[SensitiveParameter]
string $pem,
#[SensitiveParameter]
string $passphrase,
): OpenSSLAsymmetricKey {
return $this->validateKey(openssl_pkey_get_private($pem, $passphrase));
}

Expand All @@ -74,8 +81,10 @@ final protected function verifySignature(
}

/** @throws InvalidKeyProvided */
private function getPublicKey(string $pem): OpenSSLAsymmetricKey
{
private function getPublicKey(
#[SensitiveParameter]
string $pem,
): OpenSSLAsymmetricKey {
return $this->validateKey(openssl_pkey_get_public($pem));
}

Expand All @@ -84,8 +93,10 @@ private function getPublicKey(string $pem): OpenSSLAsymmetricKey
*
* @throws InvalidKeyProvided
*/
private function validateKey(OpenSSLAsymmetricKey|bool $key): OpenSSLAsymmetricKey
{
private function validateKey(
#[SensitiveParameter]
OpenSSLAsymmetricKey|bool $key,
): OpenSSLAsymmetricKey {
if (is_bool($key)) {
throw InvalidKeyProvided::cannotBeParsed($this->fullOpenSSLErrorString());
}
Expand Down
17 changes: 13 additions & 4 deletions src/Signer/Rsa.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,28 @@

namespace Lcobucci\JWT\Signer;

use SensitiveParameter;

use const OPENSSL_KEYTYPE_RSA;

abstract class Rsa extends OpenSSL
{
private const MINIMUM_KEY_LENGTH = 2048;

final public function sign(string $payload, Key $key): string
{
final public function sign(
string $payload,
#[SensitiveParameter]
Key $key,
): string {
return $this->createSignature($key->contents(), $key->passphrase(), $payload);
}

final public function verify(string $expected, string $payload, Key $key): bool
{
final public function verify(
string $expected,
string $payload,
#[SensitiveParameter]
Key $key,
): bool {
return $this->verifySignature($expected, $payload, $key->contents());
}

Expand Down
8 changes: 6 additions & 2 deletions src/Token/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Lcobucci\JWT\Signer;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\UnencryptedToken;
use SensitiveParameter;

use function array_diff;
use function array_merge;
Expand Down Expand Up @@ -141,8 +142,11 @@ private function encode(array $items): string
);
}

public function getToken(Signer $signer, Key $key): UnencryptedToken
{
public function getToken(
Signer $signer,
#[SensitiveParameter]
Key $key,
): UnencryptedToken {
$headers = $this->headers;
$headers['alg'] = $signer->algorithmId();

Expand Down
Loading

0 comments on commit b0e12fc

Please sign in to comment.