Failed Conditions
Push — master ( 71e756...c4ef0e )
by Florent
08:21 queued 10s
created

Decrypt::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 32
rs 9.408
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2019 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\Easy;
15
16
use InvalidArgumentException;
17
use Jose\Component\Checker;
18
use Jose\Component\Core\Algorithm;
19
use Jose\Component\Core\AlgorithmManager;
20
use Jose\Component\Core\Util\JsonConverter;
21
use Jose\Component\Encryption\Algorithm\ContentEncryption;
22
use Jose\Component\Encryption\Algorithm\KeyEncryption;
23
use Jose\Component\Encryption\Compression\CompressionMethod;
24
use Jose\Component\Encryption\Compression\CompressionMethodManager;
25
use Jose\Component\Encryption\Compression\Deflate;
26
use Jose\Component\Encryption\JWEDecrypter;
27
use Jose\Component\Encryption\JWETokenSupport;
28
use Jose\Component\Encryption\Serializer\CompactSerializer;
29
30
class Decrypt extends AbstractLoader
31
{
32
    /**
33
     * @var string[]
34
     */
35
    protected $allowedContentEncryptionAlgorithms = [];
36
    /**
37
     * @var CompressionMethod[]
38
     */
39
    private $compressionMethods;
40
41
    private function __construct(string $token)
42
    {
43
        parent::__construct($token);
44
        $this->algorithms = [
45
            new KeyEncryption\A128GCMKW(),
46
            new KeyEncryption\A192GCMKW(),
47
            new KeyEncryption\A256GCMKW(),
48
            new KeyEncryption\A128KW(),
49
            new KeyEncryption\A192KW(),
50
            new KeyEncryption\A256KW(),
51
            new KeyEncryption\Dir(),
52
            new KeyEncryption\ECDHES(),
53
            new KeyEncryption\ECDHESA128KW(),
54
            new KeyEncryption\ECDHESA192KW(),
55
            new KeyEncryption\ECDHESA256KW(),
56
            new KeyEncryption\PBES2HS256A128KW(),
57
            new KeyEncryption\PBES2HS384A192KW(),
58
            new KeyEncryption\PBES2HS512A256KW(),
59
            new KeyEncryption\RSA15(),
60
            new KeyEncryption\RSAOAEP(),
61
            new KeyEncryption\RSAOAEP256(),
62
            new ContentEncryption\A128GCM(),
63
            new ContentEncryption\A192GCM(),
64
            new ContentEncryption\A256GCM(),
65
            new ContentEncryption\A128CBCHS256(),
66
            new ContentEncryption\A192CBCHS384(),
67
            new ContentEncryption\A256CBCHS512(),
68
        ];
69
        $this->compressionMethods = [
70
            new Deflate(),
71
        ];
72
    }
73
74
    public static function token(string $token): self
75
    {
76
        return new self($token);
77
    }
78
79
    /**
80
     * @param Algorithm|string $enc
81
     *
82
     * @throws InvalidArgumentException if the encryption algorithm is invalid
83
     */
84
    public function enc($enc): self
85
    {
86
        $clone = clone $this;
87
        switch (true) {
88
            case \is_string($enc):
89
                $clone->allowedContentEncryptionAlgorithms[] = $enc;
90
91
                return $clone;
92
            case $enc instanceof Algorithm:
93
                $clone->algorithms[$enc->name()] = $enc;
94
                $clone->allowedContentEncryptionAlgorithms[] = $enc->name();
95
96
                return $clone;
97
            default:
98
                throw new InvalidArgumentException('Invalid parameter "enc". Shall be a string or an algorithm instance.');
99
        }
100
    }
101
102
    /**
103
     * @param Algorithm[]|string[] $encs
104
     */
105
    public function encs($encs): self
106
    {
107
        $clone = clone $this;
108
        foreach ($encs as $enc) {
109
            $clone = $clone->enc($enc);
110
        }
111
112
        return $clone;
113
    }
114
115
    public function run(): JWT
116
    {
117
        if (0 !== \count($this->allowedAlgorithms)) {
118
            $this->headerCheckers[] = new Checker\AlgorithmChecker($this->allowedAlgorithms, true);
119
        }
120
        if (0 !== \count($this->allowedContentEncryptionAlgorithms)) {
121
            $this->headerCheckers[] = new ContentEncryptionAlgorithmChecker($this->allowedContentEncryptionAlgorithms, true);
122
        }
123
        $jwe = (new CompactSerializer())->unserialize($this->token);
124
        $headerChecker = new Checker\HeaderCheckerManager($this->headerCheckers, [new JWETokenSupport()]);
125
        $headerChecker->check($jwe, 0);
126
127
        $verifier = new JWEDecrypter(
128
            new AlgorithmManager($this->algorithms),
129
            new AlgorithmManager($this->algorithms),
130
            new CompressionMethodManager($this->compressionMethods)
131
        );
132
        $verifier->decryptUsingKeySet($jwe, $this->jwkset, 0);
133
134
        $jwt = new JWT();
135
        $jwt->header->replace($jwe->getSharedProtectedHeader());
136
        $jwt->claims->replace(JsonConverter::decode($jwe->getPayload()));
137
138
        $claimChecker = new Checker\ClaimCheckerManager($this->claimCheckers);
139
        $claimChecker->check($jwt->claims->all());
140
141
        return $jwt;
142
    }
143
}
144