Skip to content

Commit ed863a6

Browse files
committed
Ensure OpenSSL or Sodium are available before cypher operation
1 parent af20c1c commit ed863a6

File tree

10 files changed

+82
-33
lines changed

10 files changed

+82
-33
lines changed

src/Experimental/Signature/Blake2b.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
use Jose\Component\Core\JWK;
99
use Jose\Component\Signature\Algorithm\MacAlgorithm;
1010
use ParagonIE\ConstantTime\Base64UrlSafe;
11+
use RuntimeException;
12+
use function extension_loaded;
1113
use function in_array;
1214
use function is_string;
1315

@@ -18,6 +20,13 @@ final class Blake2b implements MacAlgorithm
1820
{
1921
private const MINIMUM_KEY_LENGTH = 32;
2022

23+
public function __construct()
24+
{
25+
if (! extension_loaded('sodium')) {
26+
throw new RuntimeException('Please install the Sodium extension');
27+
}
28+
}
29+
2130
public function allowedKeyTypes(): array
2231
{
2332
return ['oct'];

src/Library/Encryption/Algorithm/ContentEncryption/AESCBCHS.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,18 @@
77
use Jose\Component\Encryption\Algorithm\ContentEncryptionAlgorithm;
88
use ParagonIE\ConstantTime\Base64UrlSafe;
99
use RuntimeException;
10+
use function extension_loaded;
1011
use const OPENSSL_RAW_DATA;
1112

1213
abstract class AESCBCHS implements ContentEncryptionAlgorithm
1314
{
15+
public function __construct()
16+
{
17+
if (! extension_loaded('openssl')) {
18+
throw new RuntimeException('Please install the OpenSSL extension');
19+
}
20+
}
21+
1422
public function allowedKeyTypes(): array
1523
{
1624
return []; //Irrelevant

src/Library/Encryption/Algorithm/ContentEncryption/AESGCM.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,18 @@
77
use Jose\Component\Encryption\Algorithm\ContentEncryptionAlgorithm;
88
use ParagonIE\ConstantTime\Base64UrlSafe;
99
use RuntimeException;
10+
use function extension_loaded;
1011
use const OPENSSL_RAW_DATA;
1112

1213
abstract class AESGCM implements ContentEncryptionAlgorithm
1314
{
15+
public function __construct()
16+
{
17+
if (! extension_loaded('openssl')) {
18+
throw new RuntimeException('Please install the OpenSSL extension');
19+
}
20+
}
21+
1422
public function allowedKeyTypes(): array
1523
{
1624
return []; //Irrelevant

src/Library/Encryption/Algorithm/KeyEncryption/AESGCMKW.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,20 @@
88
use Jose\Component\Core\JWK;
99
use ParagonIE\ConstantTime\Base64UrlSafe;
1010
use RuntimeException;
11+
use function extension_loaded;
1112
use function in_array;
1213
use function is_string;
1314
use const OPENSSL_RAW_DATA;
1415

1516
abstract class AESGCMKW implements KeyWrapping
1617
{
18+
public function __construct()
19+
{
20+
if (! extension_loaded('openssl')) {
21+
throw new RuntimeException('Please install the OpenSSL extension');
22+
}
23+
}
24+
1725
public function allowedKeyTypes(): array
1826
{
1927
return ['oct'];

src/Library/Encryption/Algorithm/KeyEncryption/AbstractECDH.php

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ protected function calculateAgreementKey(JWK $private_key, JWK $public_key): str
121121
return $this->convertDecToBin(EcDH::computeSharedKey($curve, $pub_key, $priv_key));
122122

123123
case 'X25519' :
124+
$this->checkSodiumExtensionIsAvailable();
124125
$x = $public_key->get('x');
125126
if (! is_string($x)) {
126127
throw new InvalidArgumentException('Invalid key parameter "x"');
@@ -155,23 +156,11 @@ protected function getKeysFromPublicKey(
155156
if (! is_string($crv)) {
156157
throw new InvalidArgumentException('Invalid key parameter "crv"');
157158
}
158-
switch ($crv) {
159-
case 'P-256' :
160-
case 'P-384' :
161-
case 'P-521' :
162-
$private_key = $senderKey ?? ECKey::createECKey($crv);
163-
164-
break;
165-
166-
case 'X25519' :
167-
$this->checkSodiumExtensionIsAvailable();
168-
$private_key = $senderKey ?? $this->createOKPKey('X25519');
169-
170-
break;
171-
172-
default :
173-
throw new InvalidArgumentException(sprintf('The curve "%s" is not supported', $crv));
174-
}
159+
$private_key = match ($crv) {
160+
'P-256', 'P-384', 'P-521' => $senderKey ?? ECKey::createECKey($crv),
161+
'X25519' => $senderKey ?? $this->createOKPKey('X25519'),
162+
default => throw new InvalidArgumentException(sprintf('The curve "%s" is not supported', $crv)),
163+
};
175164
$epk = $private_key->toPublic()
176165
->all();
177166
$additional_header_values['epk'] = $epk;

src/Library/KeyManagement/JWKFactory.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ class JWKFactory
3434
*/
3535
public static function createRSAKey(int $size, array $values = []): JWK
3636
{
37+
if (! extension_loaded('openssl')) {
38+
throw new RuntimeException('Please install the OpenSSL extension');
39+
}
3740
if ($size % 8 !== 0) {
3841
throw new InvalidArgumentException('Invalid key size.');
3942
}
@@ -80,13 +83,8 @@ public static function createOctKey(int $size, array $values = []): JWK
8083
if ($size % 8 !== 0) {
8184
throw new InvalidArgumentException('Invalid key size.');
8285
}
83-
$values = [
84-
...$values,
85-
'kty' => 'oct',
86-
'k' => Base64UrlSafe::encodeUnpadded(random_bytes($size / 8)),
87-
];
8886

89-
return new JWK($values);
87+
return self::createFromSecret(random_bytes($size / 8), $values);
9088
}
9189

9290
/**

src/Library/KeyManagement/KeyConverter/KeyConverter.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ public static function loadFromKey(string $key, ?string $password = null): array
133133
*/
134134
public static function loadFromX5C(array $x5c): array
135135
{
136+
if (! extension_loaded('openssl')) {
137+
throw new RuntimeException('Please install the OpenSSL extension');
138+
}
136139
if (count($x5c) === 0) {
137140
throw new InvalidArgumentException('The certificate chain is empty');
138141
}
@@ -164,14 +167,14 @@ private static function loadKeyFromDER(string $der, ?string $password = null): a
164167

165168
private static function loadKeyFromPEM(string $pem, ?string $password = null): array
166169
{
167-
if (preg_match('#DEK-Info: (.+),(.+)#', $pem, $matches) === 1) {
168-
$pem = self::decodePem($pem, $matches, $password);
169-
}
170-
171170
if (! extension_loaded('openssl')) {
172171
throw new RuntimeException('Please install the OpenSSL extension');
173172
}
174173

174+
if (preg_match('#DEK-Info: (.+),(.+)#', $pem, $matches) === 1) {
175+
$pem = self::decodePem($pem, $matches, $password);
176+
}
177+
175178
if (preg_match('#BEGIN ENCRYPTED PRIVATE KEY(.+)(.+)#', $pem) === 1) {
176179
$decrypted = openssl_pkey_get_private($pem, $password);
177180
if ($decrypted === false) {
@@ -255,7 +258,10 @@ private static function tryToLoadOtherKeyTypes(string $input): array
255258
*/
256259
private static function populatePoints(PrivateKey $key, array $values): array
257260
{
258-
if (($values['crv'] === 'Ed25519' || $values['crv'] === 'X25519') && extension_loaded('sodium')) {
261+
if (($values['crv'] === 'Ed25519' || $values['crv'] === 'X25519')) {
262+
if (! extension_loaded('sodium')) {
263+
throw new RuntimeException('Please install the Sodium extension');
264+
}
259265
$x = sodium_crypto_scalarmult_base($key->privateKeyData());
260266
$values['x'] = Base64UrlSafe::encodeUnpadded($x);
261267
}

src/Library/Signature/Algorithm/ECDSA.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,19 @@
99
use Jose\Component\Core\Util\ECKey;
1010
use Jose\Component\Core\Util\ECSignature;
1111
use LogicException;
12+
use RuntimeException;
1213
use Throwable;
1314
use function defined;
15+
use function extension_loaded;
1416
use function in_array;
1517

1618
abstract class ECDSA implements SignatureAlgorithm
1719
{
1820
public function __construct()
1921
{
22+
if (! extension_loaded('openssl')) {
23+
throw new RuntimeException('Please install the OpenSSL extension');
24+
}
2025
if (! defined('OPENSSL_KEYTYPE_EC')) {
2126
throw new LogicException('Elliptic Curve key type not supported by your environment.');
2227
}

src/Library/Signature/Algorithm/RSAPKCS1.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,18 @@
88
use Jose\Component\Core\JWK;
99
use Jose\Component\Core\Util\RSAKey;
1010
use RuntimeException;
11+
use function extension_loaded;
1112
use function in_array;
1213

1314
abstract class RSAPKCS1 implements SignatureAlgorithm
1415
{
16+
public function __construct()
17+
{
18+
if (! extension_loaded('openssl')) {
19+
throw new RuntimeException('Please install the OpenSSL extension');
20+
}
21+
}
22+
1523
public function allowedKeyTypes(): array
1624
{
1725
return ['RSA'];

src/Library/Signature/Algorithm/Util/RSA.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Jose\Component\Core\Util\RSAKey;
1111
use RuntimeException;
1212
use function chr;
13+
use function extension_loaded;
1314
use function ord;
1415
use const STR_PAD_LEFT;
1516

@@ -38,6 +39,9 @@ public static function sign(RSAKey $key, string $message, string $hash, int $mod
3839
return self::signWithPSS($key, $message, $hash);
3940

4041
case self::SIGNATURE_PKCS1:
42+
if (! extension_loaded('openssl')) {
43+
throw new RuntimeException('Please install the OpenSSL extension');
44+
}
4145
$result = openssl_sign($message, $signature, $key->toPEM(), $hash);
4246
if ($result !== true) {
4347
throw new RuntimeException('Unable to sign the data');
@@ -70,11 +74,17 @@ public static function signWithPSS(RSAKey $key, string $message, string $hash):
7074

7175
public static function verify(RSAKey $key, string $message, string $signature, string $hash, int $mode): bool
7276
{
73-
return match ($mode) {
74-
self::SIGNATURE_PSS => self::verifyWithPSS($key, $message, $signature, $hash),
75-
self::SIGNATURE_PKCS1 => openssl_verify($message, $signature, $key->toPEM(), $hash) === 1,
76-
default => throw new InvalidArgumentException('Unsupported mode.'),
77-
};
77+
switch ($mode) {
78+
case self::SIGNATURE_PSS:
79+
return self::verifyWithPSS($key, $message, $signature, $hash);
80+
case self::SIGNATURE_PKCS1:
81+
if (! extension_loaded('openssl')) {
82+
throw new RuntimeException('Please install the OpenSSL extension');
83+
}
84+
return openssl_verify($message, $signature, $key->toPEM(), $hash) === 1;
85+
default:
86+
throw new InvalidArgumentException('Unsupported mode.');
87+
}
7888
}
7989

8090
/**

0 commit comments

Comments
 (0)