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 ( 70b15e...4c8633 )
by Joni
04:39
created

JWE::encryptionAlgorithmName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 0
crap 1
1
<?php
2
3
namespace JWX\JWE;
4
5
use JWX\JWE\CompressionAlgorithm\CompressionFactory;
6
use JWX\JWE\EncryptionAlgorithm\EncryptionAlgorithmFactory;
7
use JWX\JWE\KeyAlgorithm\KeyAlgorithmFactory;
8
use JWX\JWK\JWK;
9
use JWX\JWK\JWKSet;
10
use JWX\JWT\Header\Header;
11
use JWX\JWT\Header\JOSE;
12
use JWX\Util\Base64;
13
14
15
/**
16
 * Class to represent JWE structure.
17
 *
18
 * @link https://tools.ietf.org/html/rfc7516#section-3
19
 */
20
class JWE
21
{
22
	/**
23
	 * Protected header.
24
	 *
25
	 * @var Header $_protectedHeader
26
	 */
27
	protected $_protectedHeader;
28
	
29
	/**
30
	 * Encrypted key.
31
	 *
32
	 * @var string $_encryptedKey
33
	 */
34
	protected $_encryptedKey;
35
	
36
	/**
37
	 * Initialization vector.
38
	 *
39
	 * @var string
40
	 */
41
	protected $_iv;
42
	
43
	/**
44
	 * Additional authenticated data.
45
	 *
46
	 * @var string $_aad
47
	 */
48
	protected $_aad;
49
	
50
	/**
51
	 * Ciphertext.
52
	 *
53
	 * @var string $_ciphertext
54
	 */
55
	protected $_ciphertext;
56
	
57
	/**
58
	 * Authentication tag.
59
	 *
60
	 * @var string $_authenticationTag
61
	 */
62
	protected $_authenticationTag;
63
	
64
	/**
65
	 * Constructor
66
	 *
67
	 * @param Header $protected_header JWE Protected Header
68
	 * @param string $encrypted_key Encrypted key
69
	 * @param string $iv Initialization vector
70
	 * @param string $ciphertext Ciphertext
71
	 * @param string $auth_tag Authentication tag
72
	 * @param string|null $aad Additional authenticated data
73
	 */
74 25
	public function __construct(Header $protected_header, $encrypted_key, $iv, 
75
			$ciphertext, $auth_tag, $aad = null) {
76 25
		$this->_protectedHeader = $protected_header;
77 25
		$this->_encryptedKey = $encrypted_key;
78 25
		$this->_iv = $iv;
79 25
		$this->_aad = $aad;
80 25
		$this->_ciphertext = $ciphertext;
81 25
		$this->_authenticationTag = $auth_tag;
82 25
	}
83
	
84
	/**
85
	 * Initialize from compact serialization.
86
	 *
87
	 * @param string $data
88
	 * @return self
89
	 */
90 6
	public static function fromCompact($data) {
91 6
		return self::fromParts(explode(".", $data));
92
	}
93
	
94
	/**
95
	 * Initialize from parts of compact serialization.
96
	 *
97
	 * @param array $parts
98
	 * @throws \UnexpectedValueException
99
	 * @return self
100
	 */
101 13
	public static function fromParts(array $parts) {
102 13
		if (count($parts) != 5) {
103 1
			throw new \UnexpectedValueException(
104 2
				"Invalid JWE compact serialization.");
105
		}
106 12
		$header = Header::fromJSON(Base64::urlDecode($parts[0]));
107 12
		$encrypted_key = Base64::urlDecode($parts[1]);
108 12
		$iv = Base64::urlDecode($parts[2]);
109 12
		$ciphertext = Base64::urlDecode($parts[3]);
110 12
		$auth_tag = Base64::urlDecode($parts[4]);
111 12
		return new self($header, $encrypted_key, $iv, $ciphertext, $auth_tag);
112
	}
113
	
114
	/**
115
	 * Initialize by encrypting the given payload.
116
	 *
117
	 * @param string $payload Payload
118
	 * @param KeyManagementAlgorithm $key_algo Key management algorithm
119
	 * @param ContentEncryptionAlgorithm $enc_algo Content encryption algorithm
120
	 * @param CompressionAlgorithm|null $zip_algo Optional compression algorithm
121
	 * @param Header|null $header Optional desired header. Algorithm specific
122
	 *        parameters are automatically added.
123
	 * @param string|null $cek Optional content encryption key. Randomly
124
	 *        generated if not set.
125
	 * @param string|null $iv Optional initialization vector. Randomly generated
126
	 *        if not set.
127
	 * @throws \RuntimeException If encrypt fails
128
	 * @return self
129
	 */
130 16
	public static function encrypt($payload, KeyManagementAlgorithm $key_algo, 
131
			ContentEncryptionAlgorithm $enc_algo, 
132
			CompressionAlgorithm $zip_algo = null, Header $header = null, $cek = null, 
133
			$iv = null) {
134
		// if header was not given, initialize empty
135 16
		if (!isset($header)) {
136 6
			$header = new Header();
137 6
		}
138
		// generate random CEK
139 16
		if (!isset($cek)) {
140 8
			$cek = $key_algo->cekForEncryption($enc_algo->keySize());
141 8
		}
142
		// generate random IV
143 16
		if (!isset($iv)) {
144 7
			$iv = openssl_random_pseudo_bytes($enc_algo->ivSize());
145 7
		}
146
		// compress
147 16
		if (isset($zip_algo)) {
148 3
			$payload = $zip_algo->compress($payload);
149 3
			$header = $header->withParameters(...$zip_algo->headerParameters());
150 3
		}
151 16
		return self::_encryptContent($payload, $cek, $iv, $key_algo, $enc_algo, 
152 16
			$header);
153
	}
154
	
155
	/**
156
	 * Encrypt content with explicit parameters.
157
	 *
158
	 * @param string $plaintext Plaintext content to encrypt
159
	 * @param string $cek Content encryption key
160
	 * @param string $iv Initialization vector
161
	 * @param KeyManagementAlgorithm $key_algo Key management algorithm
162
	 * @param ContentEncryptionAlgorithm $enc_algo Content encryption algorithm
163
	 * @param Header $header Header
164
	 * @throws \UnexpectedValueException
165
	 * @return self
166
	 */
167 16
	private static function _encryptContent($plaintext, $cek, $iv, 
168
			KeyManagementAlgorithm $key_algo, 
169
			ContentEncryptionAlgorithm $enc_algo, Header $header) {
170
		// check that content encryption key has correct size
171 16
		if (strlen($cek) != $enc_algo->keySize()) {
172 1
			throw new \UnexpectedValueException("Invalid key size.");
173
		}
174
		// check that initialization vector has correct size
175 15
		if (strlen($iv) != $enc_algo->ivSize()) {
176 1
			throw new \UnexpectedValueException("Invalid IV size.");
177
		}
178
		// add key and encryption algorithm parameters to the header
179 14
		$header = $header->withParameters(...$key_algo->headerParameters())
180 14
			->withParameters(...$enc_algo->headerParameters());
181
		// encrypt the content encryption key
182 14
		$encrypted_key = $key_algo->encrypt($cek, $header);
183
		// sanity check that header wasn't unset via reference
184 14
		if (!$header instanceof Header) {
185 1
			throw new \RuntimeException("Broken key algorithm.");
186
		}
187
		// additional authenticated data
188 13
		$aad = Base64::urlEncode($header->toJSON());
189
		// encrypt
190 13
		list($ciphertext, $auth_tag) = $enc_algo->encrypt($plaintext, $cek, $iv, 
191 13
			$aad);
192 13
		return new self($header, $encrypted_key, $iv, $ciphertext, $auth_tag);
193
	}
194
	
195
	/**
196
	 * Decrypt the content using explicit algorithms.
197
	 *
198
	 * @param KeyManagementAlgorithm $key_algo
199
	 * @param ContentEncryptionAlgorithm $enc_algo
200
	 * @throws \RuntimeException If decrypt fails
201
	 * @return string Plaintext payload
202
	 */
203 15
	public function decrypt(KeyManagementAlgorithm $key_algo, 
204
			ContentEncryptionAlgorithm $enc_algo) {
205
		// check that key management algorithm matches
206 15
		if ($key_algo->algorithmParamValue() != $this->algorithmName()) {
207 1
			throw new \UnexpectedValueException(
208 1
				"Invalid key management algorithm.");
209
		}
210
		// check that encryption algorithm matches
211 14
		if ($enc_algo->encryptionAlgorithmParamValue() !=
212 14
			 $this->encryptionAlgorithmName()) {
213 1
			throw new \UnexpectedValueException("Invalid encryption algorithm.");
214
		}
215
		// decrypt content encryption key
216 13
		$cek = $key_algo->decrypt($this->_encryptedKey);
217
		// decrypt payload
218 13
		$aad = Base64::urlEncode($this->_protectedHeader->toJSON());
219 13
		$payload = $enc_algo->decrypt($this->_ciphertext, $cek, $this->_iv, 
220 13
			$aad, $this->_authenticationTag);
221 13
		$header = $this->header();
222
		// decompress
223 13
		if ($header->hasCompressionAlgorithm()) {
224 2
			$payload = CompressionFactory::algoByHeader($header)->decompress(
225 2
				$payload);
226 2
		}
227 13
		return $payload;
228
	}
229
	
230
	/**
231
	 * Decrypt content using given JWK.
232
	 *
233
	 * Key management and content encryption algorithms are determined from the
234
	 * header.
235
	 *
236
	 * @param JWK $jwk JSON Web Key
237
	 * @return string Plaintext payload
238
	 */
239 2
	public function decryptWithJWK(JWK $jwk) {
240 2
		$header = $this->header();
241 2
		$key_algo = KeyManagementAlgorithm::fromJWK($jwk, $header);
242 2
		$enc_algo = EncryptionAlgorithmFactory::algoByHeader($header);
243 2
		return $this->decrypt($key_algo, $enc_algo);
244
	}
245
	
246
	/**
247
	 * Decrypt content using a key from the given JWK set.
248
	 *
249
	 * Correct key shall be sought by the key ID indicated by the header.
250
	 *
251
	 * @param JWKSet $set Set of JSON Web Keys
252
	 * @return string Plaintext payload
253
	 */
254 4
	public function decryptWithJWKSet(JWKSet $set) {
255 4
		$header = $this->header();
256 4
		$factory = new KeyAlgorithmFactory($header);
257 4
		$key_algo = $factory->algoByKeys($set);
258 3
		$enc_algo = EncryptionAlgorithmFactory::algoByHeader($header);
259 3
		return $this->decrypt($key_algo, $enc_algo);
260
	}
261
	
262
	/**
263
	 * Get JOSE header.
264
	 *
265
	 * @return JOSE
266
	 */
267 18
	public function header() {
268 18
		return new JOSE($this->_protectedHeader);
269
	}
270
	
271
	/**
272
	 * Get the name of the key management algorithm.
273
	 *
274
	 * @return string
275
	 */
276 15
	public function algorithmName() {
277 15
		return $this->header()
278 15
			->algorithm()
279 15
			->value();
280
	}
281
	
282
	/**
283
	 * Get the name of the encryption algorithm.
284
	 *
285
	 * @return string
286
	 */
287 14
	public function encryptionAlgorithmName() {
288 14
		return $this->header()
289 14
			->encryptionAlgorithm()
290 14
			->value();
291
	}
292
	
293
	/**
294
	 * Get encrypted CEK.
295
	 *
296
	 * @return string
297
	 */
298 1
	public function encryptedKey() {
299 1
		return $this->_encryptedKey;
300
	}
301
	
302
	/**
303
	 * Get initialization vector.
304
	 *
305
	 * @return string
306
	 */
307 1
	public function initializationVector() {
308 1
		return $this->_iv;
309
	}
310
	
311
	/**
312
	 * Get ciphertext.
313
	 *
314
	 * @return string
315
	 */
316 1
	public function ciphertext() {
317 1
		return $this->_ciphertext;
318
	}
319
	
320
	/**
321
	 * Get authentication tag.
322
	 *
323
	 * @return string
324
	 */
325 1
	public function authenticationTag() {
326 1
		return $this->_authenticationTag;
327
	}
328
	
329
	/**
330
	 * Convert to compact serialization.
331
	 *
332
	 * @return string
333
	 */
334 11
	public function toCompact() {
335 11
		return Base64::urlEncode($this->_protectedHeader->toJSON()) . "." .
336 11
			 Base64::urlEncode($this->_encryptedKey) . "." .
337 11
			 Base64::urlEncode($this->_iv) . "." .
338 11
			 Base64::urlEncode($this->_ciphertext) . "." .
339 11
			 Base64::urlEncode($this->_authenticationTag);
340
	}
341
	
342
	/**
343
	 * Convert JWE to string.
344
	 *
345
	 * @return string
346
	 */
347 1
	public function __toString() {
348 1
		return $this->toCompact();
349
	}
350
}
351