84 lines
3.2 KiB
PHP
84 lines
3.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Jose\Component\NestedToken;
|
|
|
|
use InvalidArgumentException;
|
|
use Jose\Component\Core\JWK;
|
|
use Jose\Component\Encryption\JWEBuilder;
|
|
use Jose\Component\Encryption\Serializer\JWESerializerManager;
|
|
use Jose\Component\Signature\JWSBuilder;
|
|
use Jose\Component\Signature\Serializer\JWSSerializerManager;
|
|
use function array_key_exists;
|
|
use function is_array;
|
|
|
|
class NestedTokenBuilder
|
|
{
|
|
public function __construct(
|
|
private readonly JWEBuilder $jweBuilder,
|
|
private readonly JWESerializerManager $jweSerializerManager,
|
|
private readonly JWSBuilder $jwsBuilder,
|
|
private readonly JWSSerializerManager $jwsSerializerManager
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Creates a nested token.
|
|
*
|
|
* @param array{array{key: JWK, protected_header?: array<string, mixed>, header?: array<string, mixed>}} $signatures
|
|
* @param array{alg?: string, string?: mixed} $jweSharedProtectedHeader
|
|
* @param array{alg?: string, string?: mixed} $jweSharedHeader
|
|
* @param array{array{key: JWK, header?: array<string, mixed>}} $recipients
|
|
*/
|
|
public function create(
|
|
string $payload,
|
|
array $signatures,
|
|
string $jws_serialization_mode,
|
|
array $jweSharedProtectedHeader,
|
|
array $jweSharedHeader,
|
|
array $recipients,
|
|
string $jwe_serialization_mode,
|
|
?string $aad = null
|
|
): string {
|
|
$jws = $this->jwsBuilder->create()
|
|
->withPayload($payload);
|
|
foreach ($signatures as $signature) {
|
|
if (! is_array($signature) || ! array_key_exists('key', $signature)) {
|
|
throw new InvalidArgumentException(
|
|
'The signatures must be an array of arrays containing a key, a protected header and a header'
|
|
);
|
|
}
|
|
$signature['protected_header'] = array_key_exists(
|
|
'protected_header',
|
|
$signature
|
|
) ? $signature['protected_header'] : [];
|
|
$signature['header'] = array_key_exists('header', $signature) ? $signature['header'] : [];
|
|
$jws = $jws->addSignature($signature['key'], $signature['protected_header'], $signature['header']);
|
|
}
|
|
$jws = $jws->build();
|
|
$token = $this->jwsSerializerManager->serialize($jws_serialization_mode, $jws);
|
|
|
|
$jweSharedProtectedHeader['cty'] = 'JWT';
|
|
|
|
$jwe = $this->jweBuilder
|
|
->create()
|
|
->withPayload($token)
|
|
->withSharedProtectedHeader($jweSharedProtectedHeader)
|
|
->withSharedHeader($jweSharedHeader)
|
|
->withAAD($aad);
|
|
foreach ($recipients as $recipient) {
|
|
if (! is_array($recipient) || ! array_key_exists('key', $recipient)) {
|
|
throw new InvalidArgumentException(
|
|
'The recipients must be an array of arrays containing a key and a header'
|
|
);
|
|
}
|
|
$recipient['header'] = array_key_exists('header', $recipient) ? $recipient['header'] : [];
|
|
$jwe = $jwe->addRecipient($recipient['key'], $recipient['header']);
|
|
}
|
|
$jwe = $jwe->build();
|
|
|
|
return $this->jweSerializerManager->serialize($jwe_serialization_mode, $jwe);
|
|
}
|
|
}
|