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 ( 74ce6a...af33f1 )
by Joni
05:36
created

ECDSAAlgorithm   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 148
Duplicated Lines 16.22 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 14
c 0
b 0
f 0
lcom 1
cbo 9
dl 24
loc 148
ccs 51
cts 51
cp 1
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
_curveName() 0 1 ?
A __construct() 0 13 2
A fromPublicKey() 0 3 1
A fromPrivateKey() 0 3 1
B fromJWK() 24 24 6
A computeSignature() 0 9 1
A validateSignature() 0 12 2
A headerParameters() 0 3 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace JWX\JWS\Algorithm;
4
5
use CryptoUtil\ASN1\EC\ECDSASigValue;
6
use CryptoUtil\Conversion\ECConversion;
7
use JWX\JWA\JWA;
8
use JWX\JWK\EC\ECPrivateKeyJWK;
9
use JWX\JWK\EC\ECPublicKeyJWK;
10
use JWX\JWK\JWK;
11
use JWX\JWK\Parameter\CurveParameter;
12
use JWX\JWT\Parameter\AlgorithmParameter;
13
use JWX\JWT\Parameter\JWTParameter;
14
15
16
/**
17
 * Base class for algorithms implementing elliptic curve signature computation.
18
 *
19
 * @link https://tools.ietf.org/html/rfc7518#section-3.4
20
 */
21
abstract class ECDSAAlgorithm extends OpenSSLSignatureAlgorithm
22
{
23
	/**
24
	 * Mapping from algorithm name to class name.
25
	 *
26
	 * @internal
27
	 *
28
	 * @var array
29
	 */
30
	const MAP_NAME_TO_CLASS = array(
31
		/* @formatter:off */
32
		JWA::ALGO_ES256 => ES256Algorithm::class,
33
		JWA::ALGO_ES384 => ES384Algorithm::class,
34
		JWA::ALGO_ES512 => ES512Algorithm::class
35
		/* @formatter:on */
36
	);
37
	
38
	/**
39
	 * Signature size in bytes.
40
	 *
41
	 * @var int
42
	 */
43
	private $_signatureSize;
44
	
45
	/**
46
	 * Get the name of the curve used by this algorithm.
47
	 *
48
	 * @return string
49
	 */
50
	abstract protected function _curveName();
51
	
52
	/**
53
	 * Constructor
54
	 *
55
	 * @param ECPublicKeyJWK $pub_key
56
	 * @param ECPrivateKeyJWK $priv_key
57
	 */
58 11
	protected function __construct(ECPublicKeyJWK $pub_key, 
59
			ECPrivateKeyJWK $priv_key = null) {
60 11
		$curve = $pub_key->curveParameter()->value();
61 11
		if ($this->_curveName() != $curve) {
62 1
			throw new \InvalidArgumentException(
63 1
				"Key with " . $this->_curveName() .
64 1
					 " curve expected, got $curve.");
65
		}
66 10
		$this->_publicKey = $pub_key;
67 10
		$this->_privateKey = $priv_key;
68 10
		$key_size = $pub_key->curveParameter()->keySizeBits();
69 10
		$this->_signatureSize = ceil($key_size / 8) * 2;
0 ignored issues
show
Documentation Bug introduced by
The property $_signatureSize was declared of type integer, but ceil($key_size / 8) * 2 is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
70 10
	}
71
	
72
	/**
73
	 * Initialize from a public key.
74
	 *
75
	 * @param ECPublicKeyJWK $jwk
76
	 * @return self
77
	 */
78 5
	public static function fromPublicKey(ECPublicKeyJWK $jwk) {
79 5
		return new static($jwk);
80
	}
81
	
82
	/**
83
	 * Initialize from a private key.
84
	 *
85
	 * @param ECPrivateKeyJWK $jwk
86
	 * @return self
87
	 */
88 6
	public static function fromPrivateKey(ECPrivateKeyJWK $jwk) {
89 6
		return new static($jwk->publicKey(), $jwk);
90
	}
91
	
92
	/**
93
	 * Initialize from a JWK.
94
	 *
95
	 * If algorithm is not specified, look from JWK.
96
	 *
97
	 * @param JWK $jwk
98
	 * @param string|null $alg Optional algorithm name
99
	 * @throws \UnexpectedValueException
100
	 * @return self
101
	 */
102 8 View Code Duplication
	public static function fromJWK(JWK $jwk, $alg = null) {
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...
103
		// if algorithm is not explicitly given, consult JWK
104 8
		if (!isset($alg)) {
105 3
			if (!$jwk->hasAlgorithmParameter()) {
106 1
				throw new \UnexpectedValueException(
107 1
					"Missing algorithm parameter.");
108
			}
109 2
			$alg = $jwk->algorithmParameter()->value();
110 2
		}
111 7
		if (!array_key_exists($alg, self::MAP_NAME_TO_CLASS)) {
112 1
			throw new \UnexpectedValueException(
113 1
				"Algorithm '$alg' not supported.");
114
		}
115 6
		$cls = self::MAP_NAME_TO_CLASS[$alg];
116 6
		$params = ECPrivateKeyJWK::MANAGED_PARAMS;
117 6
		if ($jwk->has(...$params)) {
118 3
			return $cls::fromPrivateKey(ECPrivateKeyJWK::fromJWK($jwk));
119
		}
120 3
		$params = ECPublicKeyJWK::MANAGED_PARAMS;
121 3
		if ($jwk->has(...$params)) {
122 2
			return $cls::fromPublicKey(ECPublicKeyJWK::fromJWK($jwk));
123
		}
124 1
		throw new \UnexpectedValueException("Not an EC key.");
125
	}
126
	
127
	/**
128
	 *
129
	 * @see \JWX\JWS\Algorithm\OpenSSLSignatureAlgorithm::computeSignature()
130
	 * @return string
131
	 */
132 4
	public function computeSignature($data) {
133
		// OpenSSL returns ECDSA signature as a DER encoded ECDSA-Sig-Value
134 4
		$der = parent::computeSignature($data);
135 4
		$sig = ECDSASigValue::fromDER($der);
136 4
		$mlen = floor($this->_signatureSize / 2);
137 4
		$signature = ECConversion::numberToOctets($sig->r(), $mlen) .
138 4
			 ECConversion::numberToOctets($sig->s(), $mlen);
139 4
		return $signature;
140
	}
141
	
142
	/**
143
	 *
144
	 * @see \JWX\JWS\Algorithm\OpenSSLSignatureAlgorithm::validateSignature()
145
	 * @return bool
146
	 */
147 5
	public function validateSignature($data, $signature) {
148 5
		if (strlen($signature) != $this->_signatureSize) {
149 1
			throw new \UnexpectedValueException("Invalid signature length.");
150
		}
151 4
		list($r_octets, $s_octets) = str_split($signature, 
152 4
			floor($this->_signatureSize / 2));
153
		// convert signature to DER sequence for OpenSSL
154 4
		$r = ECConversion::octetsToNumber($r_octets);
155 4
		$s = ECConversion::octetsToNumber($s_octets);
156 4
		$sig = new ECDSASigValue($r, $s);
157 4
		return parent::validateSignature($data, $sig->toDER());
158
	}
159
	
160
	/**
161
	 *
162
	 * @see \JWX\JWT\Header\HeaderParameters::headerParameters()
163
	 * @return JWTParameter[]
164
	 */
165 2
	public function headerParameters() {
166 2
		return array(AlgorithmParameter::fromAlgorithm($this));
167
	}
168
}
169