Failed Conditions
Push — v7 ( e9e51b...d9c0af )
by Florent
03:20
created

KeyChecker::checkUsage()   C

Complexity

Conditions 7
Paths 9

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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