Failed Conditions
Push — v7 ( 3dace9...35cf1c )
by Florent
02:18
created

CompactSerializer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2017 Spomky-Labs
9
 *
10
 * This software may be modified and distributed under the terms
11
 * of the MIT license.  See the LICENSE file for details.
12
 */
13
14
namespace Jose\Component\Encryption\Serializer;
15
16
use Base64Url\Base64Url;
17
use Jose\Component\Core\Converter\JsonConverterInterface;
18
use Jose\Component\Encryption\JWE;
19
use Jose\Component\Encryption\Recipient;
20
21
/**
22
 * Class CompactSerializer.
23
 */
24
final class CompactSerializer implements JWESerializerInterface
25
{
26
    public const NAME = 'jwe_compact';
27
28
    /**
29
     * @var JsonConverterInterface
30
     */
31
    private $jsonConverter;
32
33
    /**
34
     * JSONFlattenedSerializer constructor.
35
     *
36
     * @param JsonConverterInterface $jsonConverter
37
     */
38
    public function __construct(JsonConverterInterface $jsonConverter)
39
    {
40
        $this->jsonConverter = $jsonConverter;
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function displayName(): string
47
    {
48
        return 'JWE Compact';
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function name(): string
55
    {
56
        return self::NAME;
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function serialize(JWE $jwe, ?int $recipientIndex = null): string
63
    {
64
        if (null === $recipientIndex) {
65
            $recipientIndex = 0;
66
        }
67
        $recipient = $jwe->getRecipient($recipientIndex);
68
69
        $this->checkHasNoAAD($jwe);
70
        $this->checkHasSharedProtectedHeaders($jwe);
71
        $this->checkRecipientHasNoHeaders($jwe, $recipientIndex);
72
73
        return sprintf(
74
            '%s.%s.%s.%s.%s',
75
            $jwe->getEncodedSharedProtectedHeaders(),
76
            Base64Url::encode(null === $recipient->getEncryptedKey() ? '' : $recipient->getEncryptedKey()),
77
            Base64Url::encode(null === $jwe->getIV() ? '' : $jwe->getIV()),
78
            Base64Url::encode($jwe->getCiphertext()),
79
            Base64Url::encode(null === $jwe->getTag() ? '' : $jwe->getTag())
80
        );
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function unserialize(string $input): JWE
87
    {
88
        $parts = explode('.', $input);
89
        if (5 !== count($parts)) {
90
            throw new \InvalidArgumentException('Unsupported input');
91
        }
92
93
        try {
94
            $encodedSharedProtectedHeader = $parts[0];
95
            $sharedProtectedHeader = $this->jsonConverter->decode(Base64Url::decode($encodedSharedProtectedHeader));
96
            $encryptedKey = empty($parts[1]) ? null : Base64Url::decode($parts[1]);
97
            $iv = Base64Url::decode($parts[2]);
98
            $ciphertext = Base64Url::decode($parts[3]);
99
            $tag = Base64Url::decode($parts[4]);
100
101
            return JWE::create(
102
                $ciphertext,
103
                $iv,
104
                $tag,
105
                null,
106
                [],
107
                $sharedProtectedHeader,
108
                $encodedSharedProtectedHeader,
109
                [Recipient::create([], $encryptedKey)]);
110
        } catch (\Exception $e) {
111
            throw new \InvalidArgumentException('Unsupported input');
112
        } catch (\Error $e) {
113
            throw new \InvalidArgumentException('Unsupported input');
114
        }
115
    }
116
117
    /**
118
     * @param JWE $jwe
119
     */
120
    private function checkHasNoAAD(JWE $jwe)
121
    {
122
        if (!empty($jwe->getAAD())) {
123
            throw new \LogicException('This JWE has AAD and cannot be converted into Compact JSON.');
124
        }
125
    }
126
127
    /**
128
     * @param JWE $jwe
129
     * @param int $id
130
     */
131
    private function checkRecipientHasNoHeaders(JWE $jwe, int $id)
132
    {
133
        if (!empty($jwe->getSharedHeaders()) || !empty($jwe->getRecipient($id)->getHeaders())) {
134
            throw new \LogicException('This JWE has shared headers or recipient headers and cannot be converted into Compact JSON.');
135
        }
136
    }
137
138
    /**
139
     * @param JWE $jwe
140
     */
141
    private function checkHasSharedProtectedHeaders(JWE $jwe)
142
    {
143
        if (empty($jwe->getSharedProtectedHeaders())) {
144
            throw new \LogicException('This JWE does not have shared protected headers and cannot be converted into Compact JSON.');
145
        }
146
    }
147
}
148