Skip to content

Commit 71a87c3

Browse files
committed
🛀 cleanup
1 parent 4c98b05 commit 71a87c3

29 files changed

+1060
-677
lines changed

examples/example.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
require_once __DIR__.'/../vendor/autoload.php';
1818

19-
$algo = 'ES256';
20-
2119
// key examples from: https://datatracker.ietf.org/doc/html/rfc7515#appendix-A
2220
$privateJWK = '{
2321
"kty":"EC",
@@ -46,14 +44,11 @@
4644
// ...or PEM
4745
$jwk = new ECKey(privateKey: $privatePEM, publicKey: $publicPEM);
4846
// invoke the signature algorithm
49-
$jwa = new ECDSA(jwk: $jwk, algo: $algo);
47+
$jwa = new ECDSA(jwk: $jwk, algo: ECDSA::ALGO_ES256);
5048
// invoke the signature
5149
$jws = new JWS($jwa);
5250
// encode and sign (requires private key
5351
$jwt = $jws->encode(['foo' => 'bar']);
5452
var_dump($jwt);
5553
// decode and verify (requires public key)
5654
var_dump($jws->decode($jwt));
57-
58-
#var_dump((new ECKey)->publicKeyToPEM(Util::jsonDecode($privateJWK)));
59-
#var_dump((new ECKey)->pemToPrivateJWK($privatePEM));

src/Algorithms/Signature/ECDSA.php

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace chillerlan\JOSE\Algorithms\Signature;
1313

1414
use chillerlan\JOSE\Algorithms\OpenSSLAbstract;
15-
use chillerlan\JOSE\Key\JWK;
1615
use InvalidArgumentException;
1716
use function dechex;
1817
use function hexdec;
@@ -36,21 +35,33 @@
3635
*/
3736
final class ECDSA extends OpenSSLAbstract implements SignatureAlgorithm{
3837

38+
public const ALGO_ES256 = 'ES256';
39+
public const ALGO_ES256K = 'ES256K';
40+
public const ALGO_ES384 = 'ES384';
41+
public const ALGO_ES512 = 'ES512';
42+
3943
public const SUPPORTED_ALGOS = [
40-
'ES256' => OPENSSL_ALGO_SHA256,
41-
'ES256K' => OPENSSL_ALGO_SHA256,
42-
'ES384' => OPENSSL_ALGO_SHA384,
43-
'ES512' => OPENSSL_ALGO_SHA512,
44+
self::ALGO_ES256 => OPENSSL_ALGO_SHA256,
45+
self::ALGO_ES256K => OPENSSL_ALGO_SHA256,
46+
self::ALGO_ES384 => OPENSSL_ALGO_SHA384,
47+
self::ALGO_ES512 => OPENSSL_ALGO_SHA512,
4448
];
4549

46-
private const META = [
47-
'ES256' => [256, 64, 'P-256'],
48-
'ES256K' => [256, 64, 'P-256K'],
49-
'ES384' => [384, 96, 'P-384'],
50-
'ES512' => [521, 132, 'P-521'],
50+
protected const KEYTYPE = OPENSSL_KEYTYPE_EC;
51+
52+
private const KEY_LENGTH = [
53+
self::ALGO_ES256 => 256,
54+
self::ALGO_ES256K => 256,
55+
self::ALGO_ES384 => 384,
56+
self::ALGO_ES512 => 521,
5157
];
5258

53-
protected const KEYTYPE = OPENSSL_KEYTYPE_EC;
59+
private const OCTET_LENGTH = [
60+
self::ALGO_ES256 => 64,
61+
self::ALGO_ES256K => 64,
62+
self::ALGO_ES384 => 96,
63+
self::ALGO_ES512 => 132,
64+
];
5465

5566
private const BYTE_SIZE = 2;
5667

@@ -60,16 +71,6 @@ final class ECDSA extends OpenSSLAbstract implements SignatureAlgorithm{
6071
private const ASN1_BIG_INTEGER_LIMIT = '7f';
6172
private const ASN1_NEGATIVE_INTEGER = '00';
6273

63-
private int $keyLength;
64-
private int $signaturePartLength;
65-
# private string $crv;
66-
67-
public function __construct(JWK $jwk, string $algo, string|null $passphrase = null){
68-
parent::__construct($jwk, $algo, $passphrase);
69-
70-
[$this->keyLength, $this->signaturePartLength, /* $this->crv */] = self::META[$this->algo];
71-
}
72-
7374
public function sign(string $message):string{
7475
return $this->fromAsn1($this->signMessage($message));
7576
}
@@ -79,18 +80,18 @@ public function verify(string $message, string $signature):bool{
7980
}
8081

8182
protected function checkKeyLength(int $bits):bool{
82-
return $bits === $this->keyLength;
83+
return $bits === self::KEY_LENGTH[$this->algo];
8384
}
8485

8586
private function toAsn1(string $signature):string{
8687
$signature = sodium_bin2hex($signature);
8788

88-
if($this->octetLength($signature) !== $this->signaturePartLength){
89+
if($this->octetLength($signature) !== self::OCTET_LENGTH[$this->algo]){
8990
throw new InvalidArgumentException('Invalid signature length.');
9091
}
9192

92-
$pointR = $this->preparePositiveInteger(substr($signature, 0, $this->signaturePartLength));
93-
$pointS = $this->preparePositiveInteger(substr($signature, $this->signaturePartLength));
93+
$pointR = $this->preparePositiveInteger(substr($signature, 0, self::OCTET_LENGTH[$this->algo]));
94+
$pointS = $this->preparePositiveInteger(substr($signature, self::OCTET_LENGTH[$this->algo]));
9495
$lengthR = $this->octetLength($pointR);
9596
$lengthS = $this->octetLength($pointS);
9697

@@ -114,26 +115,6 @@ private function toAsn1(string $signature):string{
114115
);
115116
}
116117

117-
private function octetLength(string $data):int{
118-
return intdiv(strlen($data), self::BYTE_SIZE);
119-
}
120-
121-
private function preparePositiveInteger(string $data):string{
122-
123-
if(substr($data, 0, self::BYTE_SIZE) > self::ASN1_BIG_INTEGER_LIMIT){
124-
return self::ASN1_NEGATIVE_INTEGER.$data;
125-
}
126-
127-
while(
128-
str_starts_with($data, self::ASN1_NEGATIVE_INTEGER)
129-
&& substr($data, 2, self::BYTE_SIZE) <= self::ASN1_BIG_INTEGER_LIMIT
130-
){
131-
$data = substr($data, 2);
132-
}
133-
134-
return $data;
135-
}
136-
137118
private function fromAsn1(string $signature):string{
138119
$message = sodium_bin2hex($signature);
139120
$position = 0;
@@ -150,8 +131,8 @@ private function fromAsn1(string $signature):string{
150131
$pointS = $this->retrievePositiveInteger($message, $position);
151132

152133
return sodium_hex2bin(
153-
str_pad($pointR, $this->signaturePartLength, '0', STR_PAD_LEFT).
154-
str_pad($pointS, $this->signaturePartLength, '0', STR_PAD_LEFT),
134+
str_pad($pointR, self::OCTET_LENGTH[$this->algo], '0', STR_PAD_LEFT).
135+
str_pad($pointS, self::OCTET_LENGTH[$this->algo], '0', STR_PAD_LEFT),
155136
);
156137
}
157138

@@ -162,6 +143,26 @@ private function readAsn1Content(string $message, int &$position, int $length):s
162143
return $content;
163144
}
164145

146+
private function octetLength(string $data):int{
147+
return intdiv(strlen($data), self::BYTE_SIZE);
148+
}
149+
150+
private function preparePositiveInteger(string $data):string{
151+
152+
if(substr($data, 0, self::BYTE_SIZE) > self::ASN1_BIG_INTEGER_LIMIT){
153+
return self::ASN1_NEGATIVE_INTEGER.$data;
154+
}
155+
156+
while(
157+
str_starts_with($data, self::ASN1_NEGATIVE_INTEGER)
158+
&& substr($data, 2, self::BYTE_SIZE) <= self::ASN1_BIG_INTEGER_LIMIT
159+
){
160+
$data = substr($data, 2);
161+
}
162+
163+
return $data;
164+
}
165+
165166
private function retrievePositiveInteger(string $message, int &$position):string{
166167

167168
if($this->readAsn1Content($message, $position, self::BYTE_SIZE) !== self::ASN1_INTEGER){

src/Algorithms/Signature/EdDSA.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@
2222
*/
2323
final class EdDSA extends JWAAbstract implements SignatureAlgorithm{
2424

25-
public const SUPPORTED_ALGOS = ['EdDSA' => 'Ed25519'];
25+
public const ALGO_EDDSA = 'EdDSA';
26+
27+
public const SUPPORTED_ALGOS = [
28+
self::ALGO_EDDSA => 'Ed25519',
29+
];
2630

2731
public function sign(string $message):string{
2832
return sodium_crypto_sign_detached($message, $this->jwk->getPrivateKey());

src/Algorithms/Signature/HMAC.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,20 @@
2626
*/
2727
final class HMAC extends JWAAbstract implements SignatureAlgorithm{
2828

29+
public const ALGO_HS256 = 'HS256';
30+
public const ALGO_HS384 = 'HS384';
31+
public const ALGO_HS512 = 'HS512';
32+
2933
public const SUPPORTED_ALGOS = [
30-
'HS256' => 'SHA256', // required
31-
'HS384' => 'SHA384',
32-
'HS512' => 'SHA512',
34+
self::ALGO_HS256 => 'SHA256', // required
35+
self::ALGO_HS384 => 'SHA384',
36+
self::ALGO_HS512 => 'SHA512',
3337
];
3438

3539
private const MIN_KEYLENGTH = [
36-
'HS256' => 256,
37-
'HS384' => 384,
38-
'HS512' => 512,
40+
self::ALGO_HS256 => 256,
41+
self::ALGO_HS384 => 384,
42+
self::ALGO_HS512 => 512,
3943
];
4044

4145
public function sign(string $message):string{
@@ -57,11 +61,11 @@ private function getHmacKey():string{
5761
$key = $this->jwk->getPrivateKey();
5862
}
5963
catch(Throwable){
60-
$key = $this->jwk->getPublicKey();
64+
$key = $this->jwk->getPublicKey(); // @codeCoverageIgnore
6165
}
6266

6367
if((strlen($key) * 8) < $this::MIN_KEYLENGTH[$this->algo]){
64-
throw new RuntimeException('the given key is too short');
68+
throw new RuntimeException('the given key is too short'); // @codeCoverageIgnore
6569
}
6670

6771
return $key;

src/Algorithms/Signature/RSA.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,14 @@
2525
*/
2626
final class RSA extends OpenSSLAbstract implements SignatureAlgorithm{
2727

28+
public const ALGO_RS256 = 'RS256';
29+
public const ALGO_RS384 = 'RS384';
30+
public const ALGO_RS512 = 'RS512';
31+
2832
public const SUPPORTED_ALGOS = [
29-
'RS256' => OPENSSL_ALGO_SHA256,
30-
'RS384' => OPENSSL_ALGO_SHA384,
31-
'RS512' => OPENSSL_ALGO_SHA512,
33+
self::ALGO_RS256 => OPENSSL_ALGO_SHA256,
34+
self::ALGO_RS384 => OPENSSL_ALGO_SHA384,
35+
self::ALGO_RS512 => OPENSSL_ALGO_SHA512,
3236
];
3337

3438
protected const KEYTYPE = OPENSSL_KEYTYPE_RSA;

0 commit comments

Comments
 (0)