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

RSAESKeyAlgorithm::fromJWK()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
ccs 8
cts 8
cp 1
rs 9.4285
cc 3
eloc 8
nc 3
nop 2
crap 3
1
<?php
2
3
namespace JWX\JWE\KeyAlgorithm;
4
5
use JWX\JWA\JWA;
6
use JWX\JWE\KeyAlgorithm\Feature\RandomCEK;
7
use JWX\JWE\KeyManagementAlgorithm;
8
use JWX\JWK\JWK;
9
use JWX\JWK\RSA\RSAPrivateKeyJWK;
10
use JWX\JWK\RSA\RSAPublicKeyJWK;
11
use JWX\JWT\Header\Header;
12
use JWX\JWT\Parameter\AlgorithmParameter;
13
14
15
/**
16
 * Base class for algorithms implementing RSA based key encryption.
17
 *
18
 * @link https://tools.ietf.org/html/rfc7518#section-4.2
19
 * @link https://tools.ietf.org/html/rfc7518#section-4.3
20
 */
21
abstract class RSAESKeyAlgorithm extends KeyManagementAlgorithm
22
{
23
	use RandomCEK;
24
	
25
	/**
26
	 * Public key.
27
	 *
28
	 * @var RSAPublicKeyJWK $_publicKey
29
	 */
30
	protected $_publicKey;
31
	
32
	/**
33
	 * Private key.
34
	 *
35
	 * @var RSAPrivateKeyJWK|null $_privateKey
36
	 */
37
	protected $_privateKey;
38
	
39
	/**
40
	 * Mapping from algorithm name to class name.
41
	 *
42
	 * @internal
43
	 *
44
	 * @var array
45
	 */
46
	const MAP_ALGO_TO_CLASS = array(
47
		/* @formatter:off */
48
		JWA::ALGO_RSA1_5 => RSAESPKCS1Algorithm::class,
49
		JWA::ALGO_RSA_OAEP => RSAESOAEPAlgorithm::class
50
		/* @formatter:on */
51
	);
52
	
53
	/**
54
	 * Get the padding scheme.
55
	 *
56
	 * @return int
57
	 */
58
	abstract protected function _paddingScheme();
59
	
60
	/**
61
	 * Constructor.
62
	 *
63
	 * Use <code>fromPublicKey</code> or <code>fromPrivateKey</code> instead!
64
	 *
65
	 * @param RSAPublicKeyJWK $pub_key RSA public key
66
	 * @param RSAPrivateKeyJWK $priv_key Optional RSA private key
67
	 */
68 18
	protected function __construct(RSAPublicKeyJWK $pub_key, 
69
			RSAPrivateKeyJWK $priv_key = null) {
70 18
		$this->_publicKey = $pub_key;
71 18
		$this->_privateKey = $priv_key;
72 18
	}
73
	
74
	/**
75
	 *
76
	 * @param JWK $jwk
77
	 * @param Header $header
78
	 * @throws \UnexpectedValueException
79
	 * @return RSAESKeyAlgorithm
80
	 */
81 3
	public static function fromJWK(JWK $jwk, Header $header) {
82 3
		$alg = JWA::deriveAlgorithmName($header, $jwk);
83 3
		if (!array_key_exists($alg, self::MAP_ALGO_TO_CLASS)) {
84 1
			throw new \UnexpectedValueException("Unsupported algorithm '$alg'.");
85
		}
86 2
		$cls = self::MAP_ALGO_TO_CLASS[$alg];
87 2
		if ($jwk->has(...RSAPrivateKeyJWK::MANAGED_PARAMS)) {
88 1
			return $cls::fromPrivateKey(RSAPrivateKeyJWK::fromJWK($jwk));
89
		}
90 1
		return $cls::fromPublicKey(RSAPublicKeyJWK::fromJWK($jwk));
91
	}
92
	
93
	/**
94
	 * Initialize from a public key.
95
	 *
96
	 * @param RSAPublicKeyJWK $jwk
97
	 * @return self
98
	 */
99 3
	public static function fromPublicKey(RSAPublicKeyJWK $jwk) {
100 3
		return new static($jwk);
101
	}
102
	
103
	/**
104
	 * Initialize from a private key.
105
	 *
106
	 * @param RSAPrivateKeyJWK $jwk
107
	 * @return self
108
	 */
109 15
	public static function fromPrivateKey(RSAPrivateKeyJWK $jwk) {
110 15
		return new static($jwk->publicKey(), $jwk);
111
	}
112
	
113
	/**
114
	 * Get the public key.
115
	 *
116
	 * @return RSAPublicKeyJWK
117
	 */
118 11
	public function publicKey() {
119 11
		return $this->_publicKey;
120
	}
121
	
122
	/**
123
	 * Check whether the private key is present.
124
	 *
125
	 * @return bool
126
	 */
127 13
	public function hasPrivateKey() {
128 13
		return isset($this->_privateKey);
129
	}
130
	
131
	/**
132
	 * Get the private key.
133
	 *
134
	 * @throws \LogicException
135
	 * @return RSAPrivateKeyJWK
136
	 */
137 12
	public function privateKey() {
138 12
		if (!$this->hasPrivateKey()) {
139 1
			throw new \LogicException("Private key not set.");
140
		}
141 11
		return $this->_privateKey;
142
	}
143
	
144 10 View Code Duplication
	protected function _encryptKey($key, Header &$header) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
145 10
		$pubkey = openssl_pkey_get_public(
146 10
			$this->publicKey()
147 10
				->toPEM()
148 10
				->string());
149 10
		if (false === $pubkey) {
150 1
			throw new \RuntimeException(
151
				"openssl_pkey_get_public() failed: " .
152 1
					 $this->_getLastOpenSSLError());
153
		}
154 9
		$result = openssl_public_encrypt($key, $crypted, $pubkey, 
155 9
			$this->_paddingScheme());
156 9
		if (!$result) {
157 1
			throw new \RuntimeException(
158
				"openssl_public_encrypt() failed: " .
159 1
					 $this->_getLastOpenSSLError());
160
		}
161 8
		return $crypted;
162
	}
163
	
164 10 View Code Duplication
	protected function _decryptKey($ciphertext, Header $header) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
165 10
		$privkey = openssl_pkey_get_private(
166 10
			$this->privateKey()
167 10
				->toPEM()
168 10
				->string());
169 10
		if (!$privkey) {
170 1
			throw new \RuntimeException(
171
				"openssl_pkey_get_private() failed: " .
172 1
					 $this->_getLastOpenSSLError());
173
		}
174 9
		$result = openssl_private_decrypt($ciphertext, $cek, $privkey, 
175 9
			$this->_paddingScheme());
176 9
		if (!$result) {
177 1
			throw new \RuntimeException(
178
				"openssl_private_decrypt() failed: " .
179 1
					 $this->_getLastOpenSSLError());
180
		}
181 8
		return $cek;
182
	}
183
	
184
	/**
185
	 * Get last OpenSSL error message.
186
	 *
187
	 * @return string|null
188
	 */
189 4 View Code Duplication
	protected function _getLastOpenSSLError() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
190 4
		$msg = null;
191 4
		while (false !== ($err = openssl_error_string())) {
192 4
			$msg = $err;
193 4
		}
194 4
		return $msg;
195
	}
196
	
197 3
	public function headerParameters() {
198 3
		return array(AlgorithmParameter::fromAlgorithm($this));
199
	}
200
}
201