Skip to content

JWEBuilder: fatal error when a shared header is set after a recipient has been added #678

Description

@Spomky

Version(s) affected

4.2.0 (and every previous 4.x)

Description

JWEBuilder::withSharedProtectedHeader() and JWEBuilder::withSharedHeader() iterate over the
already registered recipients and call $recipient->getHeader():

But addRecipient() stores plain arrays (['key' => ..., 'header' => ..., 'key_encryption_algorithm' => ...]),
not Recipient objects. Any call to one of those two methods after addRecipient() therefore raises a
fatal Error, instead of performing the duplicated-header-parameter check it is supposed to perform.

The duplicate check between the shared headers and the per-recipient headers is consequently never
executed in that direction: it only runs when the recipient is added last.

How to reproduce

use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A128CBCHS256;
use Jose\Component\Encryption\Algorithm\KeyEncryption\A128KW;
use Jose\Component\Encryption\JWEBuilder;
use Jose\Component\KeyManagement\JWKFactory;

$key = JWKFactory::createOctKey(128, ['alg' => 'A128KW']);
$builder = new JWEBuilder(new AlgorithmManager([new A128KW(), new A128CBCHS256()]));

$builder->withPayload('hello')
    ->withSharedProtectedHeader(['alg' => 'A128KW', 'enc' => 'A128CBC-HS256'])
    ->addRecipient($key)
    ->withSharedHeader(['cty' => 'text/plain'])   // <-- here
    ->build();
PHP Fatal error: Uncaught Error: Call to a member function getHeader() on array

Possible Solution

Read the header from the array entry ($recipient['header']) in both methods, and add a test that
covers a shared header set after a recipient.

The underlying cause is that the builder state is stored as untyped arrays; replacing those entries by
readonly value objects is part of the builder redesign planned for 4.3/5.0.

Additional Context

Related: the builder is also order-sensitive in the other direction — addRecipient() requires alg
and enc to be present in a shared header already, otherwise it throws
Parameter "enc" is missing.. That part is a design issue, addressed separately in the 4.3.0 builder
redesign issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions