Completed
Push — master ( d0ace3...8281d7 )
by Florent
02:33
created

Loader::loadSerializedJsonJWS()   C

Complexity

Conditions 7
Paths 40

Size

Total Lines 34
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 3
Metric Value
c 4
b 0
f 3
dl 0
loc 34
rs 6.7273
cc 7
eloc 24
nc 40
nop 2
1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2015 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 Base64Url\Base64Url;
15
use Jose\Algorithm\JWAManagerInterface;
16
use Jose\Behaviour\HasCheckerManager;
17
use Jose\Behaviour\HasCompressionManager;
18
use Jose\Behaviour\HasJWAManager;
19
use Jose\Behaviour\HasKeyChecker;
20
use Jose\Behaviour\HasPayloadConverter;
21
use Jose\Checker\CheckerManagerInterface;
22
use Jose\Compression\CompressionManagerInterface;
23
use Jose\Object\JWE;
24
use Jose\Object\JWS;
25
use Jose\Payload\PayloadConverterManagerInterface;
26
use Jose\Util\Converter;
27
28
/**
29
 * Class able to load JWS or JWE.
30
 * JWS object can also be verified.
31
 */
32
final class Loader implements LoaderInterface
33
{
34
    use HasKeyChecker;
35
    use HasJWAManager;
36
    use HasCheckerManager;
37
    use HasPayloadConverter;
38
    use HasCompressionManager;
39
40
    /**
41
     * Loader constructor.
42
     *
43
     * @param \Jose\Algorithm\JWAManagerInterface            $jwa_manager
44
     * @param \Jose\Payload\PayloadConverterManagerInterface $payload_converter_manager
45
     * @param \Jose\Compression\CompressionManagerInterface  $compression_manager
46
     * @param \Jose\Checker\CheckerManagerInterface          $checker_manager
47
     */
48
    public function __construct(
49
        JWAManagerInterface $jwa_manager,
50
        PayloadConverterManagerInterface $payload_converter_manager,
51
        CompressionManagerInterface $compression_manager,
52
        CheckerManagerInterface $checker_manager)
53
    {
54
        $this->setJWAManager($jwa_manager);
55
        $this->setPayloadConverter($payload_converter_manager);
56
        $this->setCompressionManager($compression_manager);
57
        $this->setCheckerManager($checker_manager);
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function load($input)
64
    {
65
        $json = Converter::convert($input, JSONSerializationModes::JSON_SERIALIZATION, false);
66
        if (is_array($json)) {
67
            if (array_key_exists('signatures', $json)) {
68
                return $this->loadSerializedJsonJWS($json, $input);
69
            }
70
            if (array_key_exists('recipients', $json)) {
71
                return $this->loadSerializedJsonJWE($json, $input);
72
            }
73
        }
74
        throw new \InvalidArgumentException('Unable to load the input');
75
    }
76
77
    /**
78
     * @param array  $data
79
     * @param string $input
80
     *
81
     * @return \Jose\Object\JWSInterface|\Jose\Object\JWSInterface[]
82
     */
83
    private function loadSerializedJsonJWS(array $data, $input)
84
    {
85
        $encoded_payload = array_key_exists('payload', $data) ? $data['payload'] : null;
86
        $payload = null === $encoded_payload?null:Base64Url::decode($encoded_payload);
87
88
        $jws = [];
89
        foreach ($data['signatures'] as $signature) {
90
            if (array_key_exists('protected', $signature)) {
91
                $encoded_protected_header = $signature['protected'];
92
                $protected_header = json_decode(Base64Url::decode($encoded_protected_header), true);
93
            } else {
94
                $encoded_protected_header = null;
95
                $protected_header = [];
96
            }
97
            $unprotected_header = isset($signature['header']) ? $signature['header'] : [];
98
            $tmp = $this->getPayloadConverter()->convertStringToPayload(
99
                array_merge($protected_header, $unprotected_header),
100
                $payload
101
            );
102
103
            $result = new JWS(
104
                $input,
105
                Base64Url::decode($signature['signature']),
106
                $encoded_payload,
107
                $tmp,
108
                $encoded_protected_header,
109
                $unprotected_header
110
            );
111
            //$result = $this->createJWS($input, $encoded_protected_header, $encoded_payload, $protected_header, $unprotected_header, $payload, Base64Url::decode($signature['signature']));
112
            $jws[] = $result;
113
        }
114
115
        return count($jws) > 1 ? $jws : current($jws);
116
    }
117
118
    /**
119
     * @param array  $data
120
     * @param string $input
121
     *
122
     * @return \Jose\Object\JWEInterface|\Jose\Object\JWEInterface[]
123
     */
124
    private function loadSerializedJsonJWE(array $data, $input)
125
    {
126
        $result = [];
127
        foreach ($data['recipients'] as $recipient) {
128
            $encoded_protected_header = array_key_exists('protected', $data) ? $data['protected'] : null;
129
            $unprotected_header = array_key_exists('unprotected', $data) ? $data['unprotected'] : [];
130
            $header = array_key_exists('header', $recipient) ? $recipient['header'] : [];
131
132
            $jwe = new JWE(
133
                $input,
134
                Base64Url::decode($data['ciphertext']),
135
                array_key_exists('encrypted_key', $recipient) ? Base64Url::decode($recipient['encrypted_key']) : null,
0 ignored issues
show
Bug introduced by
It seems like array_key_exists('encryp...encrypted_key']) : null can also be of type string; however, Jose\Object\JWE::__construct() does only seem to accept null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
136
                array_key_exists('iv', $data) ? Base64Url::decode($data['iv']) : null,
0 ignored issues
show
Bug introduced by
It seems like array_key_exists('iv', $...ode($data['iv']) : null can also be of type string; however, Jose\Object\JWE::__construct() does only seem to accept null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
137
                array_key_exists('aad', $data) ? Base64Url::decode($data['aad']) : null,
0 ignored issues
show
Bug introduced by
It seems like array_key_exists('aad', ...de($data['aad']) : null can also be of type string; however, Jose\Object\JWE::__construct() does only seem to accept null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
138
                array_key_exists('tag', $data) ? Base64Url::decode($data['tag']) : null,
0 ignored issues
show
Bug introduced by
It seems like array_key_exists('tag', ...de($data['tag']) : null can also be of type string; however, Jose\Object\JWE::__construct() does only seem to accept null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
139
                $encoded_protected_header,
140
                array_merge($unprotected_header, $header)
141
            );
142
            $result[] = $jwe;
143
        }
144
145
        return count($result) > 1 ? $result : current($result);
146
    }
147
}
148