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 ( cdd200...ea8f01 )
by Joni
04:14
created

JWE::_encryptContent()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4

Importance

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