KeyChecker   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 1
dl 0
loc 108
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A checkKeyUsage() 0 11 3
C checkOperation() 0 35 12
C checkUsage() 0 22 7
A checkKeyAlgorithm() 0 10 3
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\Core\Util;
15
16
use Jose\Component\Core\JWK;
17
18
/**
19
 * Class KeyChecker.
20
 */
21
final class KeyChecker
22
{
23
    /**
24
     * @param JWK    $key
25
     * @param string $usage
26
     *
27
     * @throws \InvalidArgumentException
28
     *
29
     * @return bool
30
     */
31
    public static function checkKeyUsage(JWK $key, string $usage): bool
32
    {
33
        if ($key->has('use')) {
34
            return self::checkUsage($key, $usage);
35
        }
36
        if ($key->has('key_ops')) {
37
            return self::checkOperation($key, $usage);
38
        }
39
40
        return true;
41
    }
42
43
    /**
44
     * @param JWK    $key
45
     * @param string $usage
46
     *
47
     * @return bool
48
     */
49
    private static function checkOperation(JWK $key, string $usage): bool
50
    {
51
        $ops = $key->get('key_ops');
52
        if (!is_array($ops)) {
53
            $ops = [$ops];
54
        }
55
        switch ($usage) {
56
            case 'verification':
57
                if (!in_array('verify', $ops)) {
58
                    throw new \InvalidArgumentException('Key cannot be used to verify a signature');
59
                }
60
61
                return true;
62
            case 'signature':
63
                if (!in_array('sign', $ops)) {
64
                    throw new \InvalidArgumentException('Key cannot be used to sign');
65
                }
66
67
                return true;
68
            case 'encryption':
69
                if (!in_array('encrypt', $ops) && !in_array('wrapKey', $ops)) {
70
                    throw new \InvalidArgumentException('Key cannot be used to encrypt');
71
                }
72
73
                return true;
74
            case 'decryption':
75
                if (!in_array('decrypt', $ops) && !in_array('unwrapKey', $ops)) {
76
                    throw new \InvalidArgumentException('Key cannot be used to decrypt');
77
                }
78
79
                return true;
80
            default:
81
                throw new \InvalidArgumentException('Unsupported key usage.');
82
        }
83
    }
84
85
    /**
86
     * @param JWK    $key
87
     * @param string $usage
88
     *
89
     * @return bool
90
     */
91
    private static function checkUsage(JWK $key, string $usage): bool
92
    {
93
        $use = $key->get('use');
94
        switch ($usage) {
95
            case 'verification':
96
            case 'signature':
97
                if ('sig' !== $use) {
98
                    throw new \InvalidArgumentException('Key cannot be used to sign or verify a signature.');
99
                }
100
101
                return true;
102
            case 'encryption':
103
            case 'decryption':
104
                if ('enc' !== $use) {
105
                    throw new \InvalidArgumentException('Key cannot be used to encrypt or decrypt.');
106
                }
107
108
                return true;
109
            default:
110
                throw new \InvalidArgumentException('Unsupported key usage.');
111
        }
112
    }
113
114
    /**
115
     * @param JWK    $key
116
     * @param string $algorithm
117
     */
118
    public static function checkKeyAlgorithm(JWK $key, string $algorithm)
119
    {
120
        if (!$key->has('alg')) {
121
            return;
122
        }
123
124
        if ($key->get('alg') !== $algorithm) {
125
            throw new \InvalidArgumentException(sprintf('Key is only allowed for algorithm "%s".', $key->get('alg')));
126
        }
127
    }
128
}
129