primo commit
This commit is contained in:
618
libraries/vendor/web-token/jwt-library/Encryption/JWEBuilder.php
vendored
Normal file
618
libraries/vendor/web-token/jwt-library/Encryption/JWEBuilder.php
vendored
Normal file
@ -0,0 +1,618 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Encryption;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Jose\Component\Core\AlgorithmManager;
|
||||
use Jose\Component\Core\JWK;
|
||||
use Jose\Component\Core\Util\Base64UrlSafe;
|
||||
use Jose\Component\Core\Util\JsonConverter;
|
||||
use Jose\Component\Core\Util\KeyChecker;
|
||||
use Jose\Component\Encryption\Algorithm\ContentEncryptionAlgorithm;
|
||||
use Jose\Component\Encryption\Algorithm\KeyEncryption\DirectEncryption;
|
||||
use Jose\Component\Encryption\Algorithm\KeyEncryption\KeyAgreement;
|
||||
use Jose\Component\Encryption\Algorithm\KeyEncryption\KeyAgreementWithKeyWrapping;
|
||||
use Jose\Component\Encryption\Algorithm\KeyEncryption\KeyEncryption;
|
||||
use Jose\Component\Encryption\Algorithm\KeyEncryption\KeyWrapping;
|
||||
use Jose\Component\Encryption\Algorithm\KeyEncryptionAlgorithm;
|
||||
use Jose\Component\Encryption\Compression\CompressionMethod;
|
||||
use Jose\Component\Encryption\Compression\CompressionMethodManager;
|
||||
use LogicException;
|
||||
use RuntimeException;
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
use function is_string;
|
||||
|
||||
class JWEBuilder
|
||||
{
|
||||
protected ?JWK $senderKey = null;
|
||||
|
||||
protected ?string $payload = null;
|
||||
|
||||
protected ?string $aad = null;
|
||||
|
||||
protected array $recipients = [];
|
||||
|
||||
protected array $sharedProtectedHeader = [];
|
||||
|
||||
protected array $sharedHeader = [];
|
||||
|
||||
private ?CompressionMethod $compressionMethod = null;
|
||||
|
||||
private ?string $keyManagementMode = null;
|
||||
|
||||
private ?ContentEncryptionAlgorithm $contentEncryptionAlgorithm = null;
|
||||
|
||||
private readonly AlgorithmManager $keyEncryptionAlgorithmManager;
|
||||
|
||||
private readonly AlgorithmManager $contentEncryptionAlgorithmManager;
|
||||
|
||||
public function __construct(
|
||||
AlgorithmManager $algorithmManager,
|
||||
null|AlgorithmManager $contentEncryptionAlgorithmManager = null,
|
||||
private readonly null|CompressionMethodManager $compressionManager = null
|
||||
) {
|
||||
if ($compressionManager !== null) {
|
||||
trigger_deprecation(
|
||||
'web-token/jwt-library',
|
||||
'3.3.0',
|
||||
'The parameter "$compressionManager" is deprecated and will be removed in 4.0.0. Compression is not recommended for JWE. Please set "null" instead.'
|
||||
);
|
||||
}
|
||||
if ($contentEncryptionAlgorithmManager !== null) {
|
||||
trigger_deprecation(
|
||||
'web-token/jwt-library',
|
||||
'3.3.0',
|
||||
'The parameter "$contentEncryptionAlgorithmManager" is deprecated and will be removed in 4.0.0. Please set all algorithms in the first argument and set "null" instead.'
|
||||
);
|
||||
$this->keyEncryptionAlgorithmManager = $algorithmManager;
|
||||
$this->contentEncryptionAlgorithmManager = $contentEncryptionAlgorithmManager;
|
||||
} else {
|
||||
$keyEncryptionAlgorithms = [];
|
||||
$contentEncryptionAlgorithms = [];
|
||||
foreach ($algorithmManager->all() as $algorithm) {
|
||||
if ($algorithm instanceof KeyEncryptionAlgorithm) {
|
||||
$keyEncryptionAlgorithms[] = $algorithm;
|
||||
}
|
||||
if ($algorithm instanceof ContentEncryptionAlgorithm) {
|
||||
$contentEncryptionAlgorithms[] = $algorithm;
|
||||
}
|
||||
}
|
||||
$this->keyEncryptionAlgorithmManager = new AlgorithmManager($keyEncryptionAlgorithms);
|
||||
$this->contentEncryptionAlgorithmManager = new AlgorithmManager($contentEncryptionAlgorithms);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the current data.
|
||||
*/
|
||||
public function create(): self
|
||||
{
|
||||
$this->senderKey = null;
|
||||
$this->payload = null;
|
||||
$this->aad = null;
|
||||
$this->recipients = [];
|
||||
$this->sharedProtectedHeader = [];
|
||||
$this->sharedHeader = [];
|
||||
$this->compressionMethod = null;
|
||||
$this->keyManagementMode = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key encryption algorithm manager.
|
||||
*/
|
||||
public function getKeyEncryptionAlgorithmManager(): AlgorithmManager
|
||||
{
|
||||
return $this->keyEncryptionAlgorithmManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content encryption algorithm manager.
|
||||
*/
|
||||
public function getContentEncryptionAlgorithmManager(): AlgorithmManager
|
||||
{
|
||||
return $this->contentEncryptionAlgorithmManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the compression method manager.
|
||||
* @deprecated This method is deprecated and will be removed in v4.0. Compression is not recommended for JWE.
|
||||
*/
|
||||
public function getCompressionMethodManager(): null|CompressionMethodManager
|
||||
{
|
||||
return $this->compressionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the payload of the JWE to build.
|
||||
*/
|
||||
public function withPayload(string $payload): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->payload = $payload;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Additional Authenticated Data of the JWE to build.
|
||||
*/
|
||||
public function withAAD(?string $aad): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->aad = $aad;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shared protected header of the JWE to build.
|
||||
*/
|
||||
public function withSharedProtectedHeader(array $sharedProtectedHeader): self
|
||||
{
|
||||
$this->checkDuplicatedHeaderParameters($sharedProtectedHeader, $this->sharedHeader);
|
||||
foreach ($this->recipients as $recipient) {
|
||||
$this->checkDuplicatedHeaderParameters($sharedProtectedHeader, $recipient->getHeader());
|
||||
}
|
||||
$clone = clone $this;
|
||||
$clone->sharedProtectedHeader = $sharedProtectedHeader;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shared header of the JWE to build.
|
||||
*/
|
||||
public function withSharedHeader(array $sharedHeader): self
|
||||
{
|
||||
$this->checkDuplicatedHeaderParameters($this->sharedProtectedHeader, $sharedHeader);
|
||||
foreach ($this->recipients as $recipient) {
|
||||
$this->checkDuplicatedHeaderParameters($sharedHeader, $recipient->getHeader());
|
||||
}
|
||||
$clone = clone $this;
|
||||
$clone->sharedHeader = $sharedHeader;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a recipient to the JWE to build.
|
||||
*/
|
||||
public function addRecipient(JWK $recipientKey, array $recipientHeader = []): self
|
||||
{
|
||||
$this->checkDuplicatedHeaderParameters($this->sharedProtectedHeader, $recipientHeader);
|
||||
$this->checkDuplicatedHeaderParameters($this->sharedHeader, $recipientHeader);
|
||||
$clone = clone $this;
|
||||
$completeHeader = array_merge($clone->sharedHeader, $recipientHeader, $clone->sharedProtectedHeader);
|
||||
$clone->checkAndSetContentEncryptionAlgorithm($completeHeader);
|
||||
$keyEncryptionAlgorithm = $clone->getKeyEncryptionAlgorithm($completeHeader);
|
||||
if ($clone->keyManagementMode === null) {
|
||||
$clone->keyManagementMode = $keyEncryptionAlgorithm->getKeyManagementMode();
|
||||
} else {
|
||||
if (! $clone->areKeyManagementModesCompatible(
|
||||
$clone->keyManagementMode,
|
||||
$keyEncryptionAlgorithm->getKeyManagementMode()
|
||||
)) {
|
||||
throw new InvalidArgumentException('Foreign key management mode forbidden.');
|
||||
}
|
||||
}
|
||||
|
||||
$compressionMethod = $clone->getCompressionMethod($completeHeader);
|
||||
if ($compressionMethod !== null) {
|
||||
if ($clone->compressionMethod === null) {
|
||||
$clone->compressionMethod = $compressionMethod;
|
||||
} elseif ($clone->compressionMethod->name() !== $compressionMethod->name()) {
|
||||
throw new InvalidArgumentException('Incompatible compression method.');
|
||||
}
|
||||
}
|
||||
if ($compressionMethod === null && $clone->compressionMethod !== null) {
|
||||
throw new InvalidArgumentException('Inconsistent compression method.');
|
||||
}
|
||||
$clone->checkKey($keyEncryptionAlgorithm, $recipientKey);
|
||||
$clone->recipients[] = [
|
||||
'key' => $recipientKey,
|
||||
'header' => $recipientHeader,
|
||||
'key_encryption_algorithm' => $keyEncryptionAlgorithm,
|
||||
];
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
//TODO: Verify if the key is compatible with the key encryption algorithm like is done to the ECDH-ES
|
||||
/**
|
||||
* Set the sender JWK to be used instead of the internal generated JWK
|
||||
*/
|
||||
public function withSenderKey(JWK $senderKey): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$completeHeader = array_merge($clone->sharedHeader, $clone->sharedProtectedHeader);
|
||||
$keyEncryptionAlgorithm = $clone->getKeyEncryptionAlgorithm($completeHeader);
|
||||
if ($clone->keyManagementMode === null) {
|
||||
$clone->keyManagementMode = $keyEncryptionAlgorithm->getKeyManagementMode();
|
||||
} else {
|
||||
if (! $clone->areKeyManagementModesCompatible(
|
||||
$clone->keyManagementMode,
|
||||
$keyEncryptionAlgorithm->getKeyManagementMode()
|
||||
)) {
|
||||
throw new InvalidArgumentException('Foreign key management mode forbidden.');
|
||||
}
|
||||
}
|
||||
$clone->checkKey($keyEncryptionAlgorithm, $senderKey);
|
||||
$clone->senderKey = $senderKey;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the JWE.
|
||||
*/
|
||||
public function build(): JWE
|
||||
{
|
||||
if ($this->payload === null) {
|
||||
throw new LogicException('Payload not set.');
|
||||
}
|
||||
if (count($this->recipients) === 0) {
|
||||
throw new LogicException('No recipient.');
|
||||
}
|
||||
|
||||
$additionalHeader = [];
|
||||
$cek = $this->determineCEK($additionalHeader);
|
||||
|
||||
$recipients = [];
|
||||
foreach ($this->recipients as $recipient) {
|
||||
$recipient = $this->processRecipient($recipient, $cek, $additionalHeader);
|
||||
$recipients[] = $recipient;
|
||||
}
|
||||
|
||||
if ((is_countable($additionalHeader) ? count($additionalHeader) : 0) !== 0 && count($this->recipients) === 1) {
|
||||
$sharedProtectedHeader = array_merge($additionalHeader, $this->sharedProtectedHeader);
|
||||
} else {
|
||||
$sharedProtectedHeader = $this->sharedProtectedHeader;
|
||||
}
|
||||
$encodedSharedProtectedHeader = count($sharedProtectedHeader) === 0 ? '' : Base64UrlSafe::encodeUnpadded(
|
||||
JsonConverter::encode($sharedProtectedHeader)
|
||||
);
|
||||
|
||||
[$ciphertext, $iv, $tag] = $this->encryptJWE($cek, $encodedSharedProtectedHeader);
|
||||
|
||||
return new JWE(
|
||||
$ciphertext,
|
||||
$iv,
|
||||
$tag,
|
||||
$this->aad,
|
||||
$this->sharedHeader,
|
||||
$sharedProtectedHeader,
|
||||
$encodedSharedProtectedHeader,
|
||||
$recipients
|
||||
);
|
||||
}
|
||||
|
||||
private function checkAndSetContentEncryptionAlgorithm(array $completeHeader): void
|
||||
{
|
||||
$contentEncryptionAlgorithm = $this->getContentEncryptionAlgorithm($completeHeader);
|
||||
if ($this->contentEncryptionAlgorithm === null) {
|
||||
$this->contentEncryptionAlgorithm = $contentEncryptionAlgorithm;
|
||||
} elseif ($contentEncryptionAlgorithm->name() !== $this->contentEncryptionAlgorithm->name()) {
|
||||
throw new InvalidArgumentException('Inconsistent content encryption algorithm');
|
||||
}
|
||||
}
|
||||
|
||||
private function processRecipient(array $recipient, string $cek, array &$additionalHeader): Recipient
|
||||
{
|
||||
$completeHeader = array_merge($this->sharedHeader, $recipient['header'], $this->sharedProtectedHeader);
|
||||
$keyEncryptionAlgorithm = $recipient['key_encryption_algorithm'];
|
||||
if (! $keyEncryptionAlgorithm instanceof KeyEncryptionAlgorithm) {
|
||||
throw new InvalidArgumentException('The key encryption algorithm is not valid');
|
||||
}
|
||||
$encryptedContentEncryptionKey = $this->getEncryptedKey(
|
||||
$completeHeader,
|
||||
$cek,
|
||||
$keyEncryptionAlgorithm,
|
||||
$additionalHeader,
|
||||
$recipient['key'],
|
||||
$recipient['sender_key'] ?? $this->senderKey ?? null
|
||||
);
|
||||
$recipientHeader = $recipient['header'];
|
||||
if ((is_countable($additionalHeader) ? count($additionalHeader) : 0) !== 0 && count($this->recipients) !== 1) {
|
||||
$recipientHeader = array_merge($recipientHeader, $additionalHeader);
|
||||
$additionalHeader = [];
|
||||
}
|
||||
|
||||
return new Recipient($recipientHeader, $encryptedContentEncryptionKey);
|
||||
}
|
||||
|
||||
private function encryptJWE(string $cek, string $encodedSharedProtectedHeader): array
|
||||
{
|
||||
if (! $this->contentEncryptionAlgorithm instanceof ContentEncryptionAlgorithm) {
|
||||
throw new InvalidArgumentException('The content encryption algorithm is not valid');
|
||||
}
|
||||
$iv_size = $this->contentEncryptionAlgorithm->getIVSize();
|
||||
$iv = $this->createIV($iv_size);
|
||||
$payload = $this->preparePayload();
|
||||
$tag = null;
|
||||
$ciphertext = $this->contentEncryptionAlgorithm->encryptContent(
|
||||
$payload ?? '',
|
||||
$cek,
|
||||
$iv,
|
||||
$this->aad,
|
||||
$encodedSharedProtectedHeader,
|
||||
$tag
|
||||
);
|
||||
|
||||
return [$ciphertext, $iv, $tag];
|
||||
}
|
||||
|
||||
private function preparePayload(): ?string
|
||||
{
|
||||
$prepared = $this->payload;
|
||||
if ($this->compressionMethod === null) {
|
||||
return $prepared;
|
||||
}
|
||||
|
||||
return $this->compressionMethod->compress($prepared ?? '');
|
||||
}
|
||||
|
||||
private function getEncryptedKey(
|
||||
array $completeHeader,
|
||||
string $cek,
|
||||
KeyEncryptionAlgorithm $keyEncryptionAlgorithm,
|
||||
array &$additionalHeader,
|
||||
JWK $recipientKey,
|
||||
?JWK $senderKey
|
||||
): ?string {
|
||||
if ($keyEncryptionAlgorithm instanceof KeyEncryption) {
|
||||
return $this->getEncryptedKeyFromKeyEncryptionAlgorithm(
|
||||
$completeHeader,
|
||||
$cek,
|
||||
$keyEncryptionAlgorithm,
|
||||
$recipientKey,
|
||||
$additionalHeader
|
||||
);
|
||||
}
|
||||
if ($keyEncryptionAlgorithm instanceof KeyWrapping) {
|
||||
return $this->getEncryptedKeyFromKeyWrappingAlgorithm(
|
||||
$completeHeader,
|
||||
$cek,
|
||||
$keyEncryptionAlgorithm,
|
||||
$recipientKey,
|
||||
$additionalHeader
|
||||
);
|
||||
}
|
||||
if ($keyEncryptionAlgorithm instanceof KeyAgreementWithKeyWrapping) {
|
||||
return $this->getEncryptedKeyFromKeyAgreementAndKeyWrappingAlgorithm(
|
||||
$completeHeader,
|
||||
$cek,
|
||||
$keyEncryptionAlgorithm,
|
||||
$additionalHeader,
|
||||
$recipientKey,
|
||||
$senderKey
|
||||
);
|
||||
}
|
||||
if ($keyEncryptionAlgorithm instanceof KeyAgreement) {
|
||||
return null;
|
||||
}
|
||||
if ($keyEncryptionAlgorithm instanceof DirectEncryption) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('Unsupported key encryption algorithm.');
|
||||
}
|
||||
|
||||
private function getEncryptedKeyFromKeyAgreementAndKeyWrappingAlgorithm(
|
||||
array $completeHeader,
|
||||
string $cek,
|
||||
KeyAgreementWithKeyWrapping $keyEncryptionAlgorithm,
|
||||
array &$additionalHeader,
|
||||
JWK $recipientKey,
|
||||
?JWK $senderKey
|
||||
): string {
|
||||
if ($this->contentEncryptionAlgorithm === null) {
|
||||
throw new InvalidArgumentException('Invalid content encryption algorithm');
|
||||
}
|
||||
|
||||
return $keyEncryptionAlgorithm->wrapAgreementKey(
|
||||
$recipientKey,
|
||||
$senderKey,
|
||||
$cek,
|
||||
$this->contentEncryptionAlgorithm->getCEKSize(),
|
||||
$completeHeader,
|
||||
$additionalHeader
|
||||
);
|
||||
}
|
||||
|
||||
private function getEncryptedKeyFromKeyEncryptionAlgorithm(
|
||||
array $completeHeader,
|
||||
string $cek,
|
||||
KeyEncryption $keyEncryptionAlgorithm,
|
||||
JWK $recipientKey,
|
||||
array &$additionalHeader
|
||||
): string {
|
||||
return $keyEncryptionAlgorithm->encryptKey($recipientKey, $cek, $completeHeader, $additionalHeader);
|
||||
}
|
||||
|
||||
private function getEncryptedKeyFromKeyWrappingAlgorithm(
|
||||
array $completeHeader,
|
||||
string $cek,
|
||||
KeyWrapping $keyEncryptionAlgorithm,
|
||||
JWK $recipientKey,
|
||||
array &$additionalHeader
|
||||
): string {
|
||||
return $keyEncryptionAlgorithm->wrapKey($recipientKey, $cek, $completeHeader, $additionalHeader);
|
||||
}
|
||||
|
||||
private function checkKey(KeyEncryptionAlgorithm $keyEncryptionAlgorithm, JWK $recipientKey): void
|
||||
{
|
||||
if ($this->contentEncryptionAlgorithm === null) {
|
||||
throw new InvalidArgumentException('Invalid content encryption algorithm');
|
||||
}
|
||||
|
||||
KeyChecker::checkKeyUsage($recipientKey, 'encryption');
|
||||
if ($keyEncryptionAlgorithm->name() !== 'dir') {
|
||||
KeyChecker::checkKeyAlgorithm($recipientKey, $keyEncryptionAlgorithm->name());
|
||||
} else {
|
||||
KeyChecker::checkKeyAlgorithm($recipientKey, $this->contentEncryptionAlgorithm->name());
|
||||
}
|
||||
}
|
||||
|
||||
private function determineCEK(array &$additionalHeader): string
|
||||
{
|
||||
if ($this->contentEncryptionAlgorithm === null) {
|
||||
throw new InvalidArgumentException('Invalid content encryption algorithm');
|
||||
}
|
||||
|
||||
switch ($this->keyManagementMode) {
|
||||
case KeyEncryption::MODE_ENCRYPT:
|
||||
case KeyEncryption::MODE_WRAP:
|
||||
return $this->createCEK($this->contentEncryptionAlgorithm->getCEKSize());
|
||||
|
||||
case KeyEncryption::MODE_AGREEMENT:
|
||||
if (count($this->recipients) !== 1) {
|
||||
throw new LogicException(
|
||||
'Unable to encrypt for multiple recipients using key agreement algorithms.'
|
||||
);
|
||||
}
|
||||
$recipientKey = $this->recipients[0]['key'];
|
||||
$senderKey = $this->recipients[0]['sender_key'] ?? null;
|
||||
$algorithm = $this->recipients[0]['key_encryption_algorithm'];
|
||||
if (! $algorithm instanceof KeyAgreement) {
|
||||
throw new InvalidArgumentException('Invalid content encryption algorithm');
|
||||
}
|
||||
$completeHeader = array_merge(
|
||||
$this->sharedHeader,
|
||||
$this->recipients[0]['header'],
|
||||
$this->sharedProtectedHeader
|
||||
);
|
||||
|
||||
return $algorithm->getAgreementKey(
|
||||
$this->contentEncryptionAlgorithm->getCEKSize(),
|
||||
$this->contentEncryptionAlgorithm->name(),
|
||||
$recipientKey,
|
||||
$senderKey,
|
||||
$completeHeader,
|
||||
$additionalHeader
|
||||
);
|
||||
|
||||
case KeyEncryption::MODE_DIRECT:
|
||||
if (count($this->recipients) !== 1) {
|
||||
throw new LogicException(
|
||||
'Unable to encrypt for multiple recipients using key agreement algorithms.'
|
||||
);
|
||||
}
|
||||
/** @var JWK $key */
|
||||
$key = $this->recipients[0]['key'];
|
||||
if ($key->get('kty') !== 'oct') {
|
||||
throw new RuntimeException('Wrong key type.');
|
||||
}
|
||||
$k = $key->get('k');
|
||||
if (! is_string($k)) {
|
||||
throw new RuntimeException('Invalid key.');
|
||||
}
|
||||
|
||||
return Base64UrlSafe::decodeNoPadding($k);
|
||||
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Unsupported key management mode "%s".',
|
||||
$this->keyManagementMode
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private function getCompressionMethod(array $completeHeader): ?CompressionMethod
|
||||
{
|
||||
if ($this->compressionManager === null || ! array_key_exists('zip', $completeHeader)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->compressionManager->get($completeHeader['zip']);
|
||||
}
|
||||
|
||||
private function areKeyManagementModesCompatible(string $current, string $new): bool
|
||||
{
|
||||
$agree = KeyEncryptionAlgorithm::MODE_AGREEMENT;
|
||||
$dir = KeyEncryptionAlgorithm::MODE_DIRECT;
|
||||
$enc = KeyEncryptionAlgorithm::MODE_ENCRYPT;
|
||||
$wrap = KeyEncryptionAlgorithm::MODE_WRAP;
|
||||
$supportedKeyManagementModeCombinations = [
|
||||
$enc . $enc => true,
|
||||
$enc . $wrap => true,
|
||||
$wrap . $enc => true,
|
||||
$wrap . $wrap => true,
|
||||
$agree . $agree => false,
|
||||
$agree . $dir => false,
|
||||
$agree . $enc => false,
|
||||
$agree . $wrap => false,
|
||||
$dir . $agree => false,
|
||||
$dir . $dir => false,
|
||||
$dir . $enc => false,
|
||||
$dir . $wrap => false,
|
||||
$enc . $agree => false,
|
||||
$enc . $dir => false,
|
||||
$wrap . $agree => false,
|
||||
$wrap . $dir => false,
|
||||
];
|
||||
|
||||
if (array_key_exists($current . $new, $supportedKeyManagementModeCombinations)) {
|
||||
return $supportedKeyManagementModeCombinations[$current . $new];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function createCEK(int $size): string
|
||||
{
|
||||
return random_bytes($size / 8);
|
||||
}
|
||||
|
||||
private function createIV(int $size): string
|
||||
{
|
||||
return random_bytes($size / 8);
|
||||
}
|
||||
|
||||
private function getKeyEncryptionAlgorithm(array $completeHeader): KeyEncryptionAlgorithm
|
||||
{
|
||||
if (! isset($completeHeader['alg'])) {
|
||||
throw new InvalidArgumentException('Parameter "alg" is missing.');
|
||||
}
|
||||
$keyEncryptionAlgorithm = $this->keyEncryptionAlgorithmManager->get($completeHeader['alg']);
|
||||
if (! $keyEncryptionAlgorithm instanceof KeyEncryptionAlgorithm) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'The key encryption algorithm "%s" is not supported or not a key encryption algorithm instance.',
|
||||
$completeHeader['alg']
|
||||
));
|
||||
}
|
||||
|
||||
return $keyEncryptionAlgorithm;
|
||||
}
|
||||
|
||||
private function getContentEncryptionAlgorithm(array $completeHeader): ContentEncryptionAlgorithm
|
||||
{
|
||||
if (! isset($completeHeader['enc'])) {
|
||||
throw new InvalidArgumentException('Parameter "enc" is missing.');
|
||||
}
|
||||
$contentEncryptionAlgorithm = $this->contentEncryptionAlgorithmManager->get($completeHeader['enc']);
|
||||
if (! $contentEncryptionAlgorithm instanceof ContentEncryptionAlgorithm) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'The content encryption algorithm "%s" is not supported or not a content encryption algorithm instance.',
|
||||
$completeHeader['enc']
|
||||
));
|
||||
}
|
||||
|
||||
return $contentEncryptionAlgorithm;
|
||||
}
|
||||
|
||||
private function checkDuplicatedHeaderParameters(array $header1, array $header2): void
|
||||
{
|
||||
$inter = array_intersect_key($header1, $header2);
|
||||
if (count($inter) !== 0) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'The header contains duplicated entries: %s.',
|
||||
implode(', ', array_keys($inter))
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user