Completed
Push — v2.0.x ( 24925e...149802 )
by Florent
02:52
created

Loader::loadSerializedJsonJWS()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 2 Features 3
Metric Value
c 8
b 2
f 3
dl 0
loc 18
rs 9.4285
cc 2
eloc 10
nc 2
nop 1
1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2016 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
namespace Jose;
13
14
use Jose\Util\JWELoader;
15
use Jose\Util\JWSLoader;
16
17
/**
18
 * Class able to load JWS or JWE.
19
 * JWS object can also be verified.
20
 */
21
final class Loader implements LoaderInterface
22
{
23
    /**
24
     * Loader constructor.
25
     */
26
    private function __construct()
27
    {
28
    }
29
30
    /**
31
     * {@inheritdoc}
32
     */
33
    public static function load($input)
34
    {
35
        $json = self::convert($input);
36
        if (array_key_exists('signatures', $json)) {
37
            return JWSLoader::loadSerializedJsonJWS($json);
38
        }
39
        if (array_key_exists('recipients', $json)) {
40
            return JWELoader::loadSerializedJsonJWE($json);
41
        }
42
        throw new \InvalidArgumentException('Unable to load the input');
43
    }
44
45
    /**
46
     * @param string $input
47
     *
48
     * @return array
49
     */
50
    private static function convert($input)
51
    {
52
        if (is_array($data = json_decode($input, true))) {
53
            if (array_key_exists('signatures', $data) || array_key_exists('recipients', $data)) {
54
                return $data;
55
            } elseif (array_key_exists('signature', $data)) {
56
                return self::fromFlattenedSerializationSignatureToSerialization($data);
57
            } elseif (array_key_exists('ciphertext', $data)) {
58
                return self::fromFlattenedSerializationRecipientToSerialization($data);
59
            }
60
        } elseif (is_string($input)) {
61
            return self::fromCompactSerializationToSerialization($input);
62
        }
63
        throw new \InvalidArgumentException('Unsupported input');
64
    }
65
66
    /**
67
     * @param $input
68
     *
69
     * @return array
70
     */
71
    private static function fromFlattenedSerializationRecipientToSerialization($input)
72
    {
73
        $recipient = [];
74
        foreach (['header', 'encrypted_key'] as $key) {
75
            if (array_key_exists($key, $input)) {
76
                $recipient[$key] = $input[$key];
77
            }
78
        }
79
        $recipients = [
80
            'ciphertext' => $input['ciphertext'],
81
            'recipients' => [$recipient],
82
        ];
83
        foreach (['ciphertext', 'protected', 'unprotected', 'iv', 'aad', 'tag'] as $key) {
84
            if (array_key_exists($key, $input)) {
85
                $recipients[$key] = $input[$key];
86
            }
87
        }
88
89
        return $recipients;
90
    }
91
92
    /**
93
     * @param $input
94
     *
95
     * @return array
96
     */
97
    private static function fromFlattenedSerializationSignatureToSerialization($input)
98
    {
99
        $signature = [
100
            'signature' => $input['signature'],
101
        ];
102
        foreach (['protected', 'header'] as $key) {
103
            if (array_key_exists($key, $input)) {
104
                $signature[$key] = $input[$key];
105
            }
106
        }
107
108
        $temp = [];
109
        if (!empty($input['payload'])) {
110
            $temp['payload'] = $input['payload'];
111
        }
112
        $temp['signatures'] = [$signature];
113
114
        return $temp;
115
    }
116
117
    /**
118
     * @param string $input
119
     *
120
     * @return array
121
     */
122
    private static function fromCompactSerializationToSerialization($input)
123
    {
124
        $parts = explode('.', $input);
125
        switch (count($parts)) {
126
            case 3:
127
                return self::fromCompactSerializationSignatureToSerialization($parts);
128
            case 5:
129
                return self::fromCompactSerializationRecipientToSerialization($parts);
130
            default:
131
                throw new \InvalidArgumentException('Unsupported input');
132
        }
133
    }
134
135
    /**
136
     * @param array $parts
137
     *
138
     * @return array
139
     */
140
    private static function fromCompactSerializationRecipientToSerialization(array $parts)
141
    {
142
        $recipient = [];
143
        if (!empty($parts[1])) {
144
            $recipient['encrypted_key'] = $parts[1];
145
        }
146
147
        $recipients = [
148
            'recipients' => [$recipient],
149
        ];
150
        foreach ([3 => 'ciphertext', 0 => 'protected', 2 => 'iv', 4 => 'tag'] as $part => $key) {
151
            if (!empty($parts[$part])) {
152
                $recipients[$key] = $parts[$part];
153
            }
154
        }
155
156
        return $recipients;
157
    }
158
159
    /**
160
     * @param array $parts
161
     *
162
     * @return array
163
     */
164
    private static function fromCompactSerializationSignatureToSerialization(array $parts)
165
    {
166
        $temp = [];
167
168
        if (!empty($parts[1])) {
169
            $temp['payload'] = $parts[1];
170
        }
171
        $temp['signatures'] = [[
172
            'protected' => $parts[0],
173
            'signature' => $parts[2],
174
        ]];
175
176
        return $temp;
177
    }
178
}
179