GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( e7c776...4b2105 )
by Joni
05:35
created

PBES2Algorithm::fromJWK()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 17
ccs 13
cts 13
cp 1
rs 9.2
cc 4
eloc 13
nc 4
nop 2
crap 4
1
<?php
2
3
namespace JWX\JWE\KeyAlgorithm;
4
5
use AESKW\AESKeyWrapAlgorithm;
6
use JWX\JWA\JWA;
7
use JWX\JWE\KeyAlgorithm\Feature\RandomCEK;
8
use JWX\JWE\KeyManagementAlgorithm;
9
use JWX\JWK\JWK;
10
use JWX\JWK\Symmetric\SymmetricKeyJWK;
11
use JWX\JWT\Header\Header;
12
use JWX\JWT\Parameter\AlgorithmParameter;
13
use JWX\JWT\Parameter\PBES2CountParameter;
14
use JWX\JWT\Parameter\PBES2SaltInputParameter;
15
16
17
/**
18
 * Base class for algorithms implementing PBES2 key encryption.
19
 *
20
 * @link https://tools.ietf.org/html/rfc7518#section-4.8
21
 */
22
abstract class PBES2Algorithm extends KeyManagementAlgorithm
23
{
24
	use RandomCEK;
25
	
26
	/**
27
	 * Password.
28
	 *
29
	 * @var string $_password
30
	 */
31
	protected $_password;
32
	
33
	/**
34
	 * Salt input.
35
	 *
36
	 * @var string $_salt
37
	 */
38
	protected $_saltInput;
39
	
40
	/**
41
	 * Iteration count.
42
	 *
43
	 * @var int $_count
44
	 */
45
	protected $_count;
46
	
47
	/**
48
	 * Derived key.
49
	 *
50
	 * @var string
51
	 */
52
	private $_derivedKey;
53
	
54
	/**
55
	 * Mapping from algorithm name to class name.
56
	 *
57
	 * @internal
58
	 *
59
	 * @var array
60
	 */
61
	const MAP_ALGO_TO_CLASS = array(
62
		/* @formatter:off */
63
		JWA::ALGO_PBES2_HS256_A128KW => PBES2HS256A128KWAlgorithm::class, 
64
		JWA::ALGO_PBES2_HS384_A192KW => PBES2HS384A192KWAlgorithm::class, 
65
		JWA::ALGO_PBES2_HS512_A256KW => PBES2HS512A256KWAlgorithm::class
66
		/* @formatter:on */
67
	);
68
	
69
	/**
70
	 * Get hash algorithm for hash_pbkdf2.
71
	 *
72
	 * @return string
73
	 */
74
	abstract protected function _hashAlgo();
75
	
76
	/**
77
	 * Get derived key length.
78
	 *
79
	 * @return int
80
	 */
81
	abstract protected function _keyLength();
82
	
83
	/**
84
	 * Get key wrapping algoritym.
85
	 *
86
	 * @return AESKeyWrapAlgorithm
87
	 */
88
	abstract protected function _kwAlgo();
89
	
90
	/**
91
	 * Constructor
92
	 *
93
	 * @param string $password Password
94
	 * @param string $salt_input Salt input
95
	 * @param int $count Iteration count
96
	 */
97 10
	public function __construct($password, $salt_input, $count) {
98 10
		$this->_password = $password;
99 10
		$this->_saltInput = $salt_input;
100 10
		$this->_count = $count;
101 10
	}
102
	
103
	/**
104
	 *
105
	 * @param JWK $jwk
106
	 * @param Header $header
107
	 * @throws \UnexpectedValueException
108
	 * @return PBES2Algorithm
109
	 */
110 7
	public static function fromJWK(JWK $jwk, Header $header) {
111 7
		$jwk = SymmetricKeyJWK::fromJWK($jwk);
112 7
		if (!$header->hasPBES2SaltInput()) {
113 1
			throw new \UnexpectedValueException("No salt input.");
114
		}
115 6
		$salt_input = $header->PBES2SaltInput()->saltInput();
116 6
		if (!$header->hasPBES2Count()) {
117 1
			throw new \UnexpectedValueException("No iteration count.");
118
		}
119 5
		$count = $header->PBES2Count()->value();
120 5
		$alg = JWA::deriveAlgorithmName($header, $jwk);
121 5
		if (!array_key_exists($alg, self::MAP_ALGO_TO_CLASS)) {
122 1
			throw new \UnexpectedValueException("Unsupported algorithm '$alg'.");
123
		}
124 4
		$cls = self::MAP_ALGO_TO_CLASS[$alg];
125 4
		return new $cls($jwk->key(), $salt_input, $count);
126
	}
127
	
128
	/**
129
	 * Initialize from a password with random salt and default iteration count.
130
	 *
131
	 * @param string $password Password
132
	 * @param int $count Optional user defined iteration count
133
	 * @param int $salt_bytes Optional user defined salt length
134
	 * @return self
135
	 */
136 1
	public static function fromPassword($password, $count = 64000, $salt_bytes = 8) {
137 1
		$salt_input = openssl_random_pseudo_bytes($salt_bytes);
138 1
		return new static($password, $salt_input, $count);
139
	}
140
	
141
	/**
142
	 * Get salt input.
143
	 *
144
	 * @return string
145
	 */
146 1
	public function saltInput() {
147 1
		return $this->_saltInput;
148
	}
149
	
150
	/**
151
	 * Get computed salt.
152
	 *
153
	 * @return string
154
	 */
155 9
	public function salt() {
156 9
		return PBES2SaltInputParameter::fromString($this->_saltInput)->salt(
157 9
			AlgorithmParameter::fromAlgorithm($this));
158
	}
159
	
160
	/**
161
	 * Get iteration count.
162
	 *
163
	 * @return int
164
	 */
165 1
	public function iterationCount() {
166 1
		return $this->_count;
167
	}
168
	
169
	/**
170
	 * Get derived key.
171
	 *
172
	 * @return string
173
	 */
174 12
	protected function _derivedKey() {
175 12
		if (!isset($this->_derivedKey)) {
176 8
			$this->_derivedKey = hash_pbkdf2($this->_hashAlgo(), 
177 8
				$this->_password, $this->salt(), $this->_count, 
178 8
				$this->_keyLength(), true);
179 8
		}
180 12
		return $this->_derivedKey;
181
	}
182
	
183 7
	protected function _encryptKey($key, Header &$header) {
184 7
		return $this->_kwAlgo()->wrap($key, $this->_derivedKey());
185
	}
186
	
187 5
	protected function _decryptKey($ciphertext, Header $header) {
188 5
		return $this->_kwAlgo()->unwrap($ciphertext, $this->_derivedKey());
189
	}
190
	
191 3
	public function headerParameters() {
192 3
		return array(AlgorithmParameter::fromAlgorithm($this), 
193 3
			PBES2SaltInputParameter::fromString($this->_saltInput), 
194 3
			new PBES2CountParameter($this->_count));
195
	}
196
}
197