Skip to content

Commit f25ae54

Browse files
committed
feat(deps): Upgrade phpseclib to v3
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent a4de988 commit f25ae54

File tree

10 files changed

+78
-84
lines changed

10 files changed

+78
-84
lines changed

3rdparty

Submodule 3rdparty updated 362 files

apps/encryption/lib/Crypto/Crypt.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
use OCP\IConfig;
4242
use OCP\IL10N;
4343
use OCP\IUserSession;
44-
use phpseclib\Crypt\RC4;
44+
use phpseclib3\Crypt\RC4;
4545
use Psr\Log\LoggerInterface;
4646

4747
/**
@@ -749,7 +749,6 @@ public function useLegacyBase64Encoding(): bool {
749749
*/
750750
private function rc4Decrypt(string $data, string $secret): string {
751751
$rc4 = new RC4();
752-
/** @psalm-suppress InternalMethod */
753752
$rc4->setKey($secret);
754753

755754
return $rc4->decrypt($data);
@@ -760,7 +759,6 @@ private function rc4Decrypt(string $data, string $secret): string {
760759
*/
761760
private function rc4Encrypt(string $data, string $secret): string {
762761
$rc4 = new RC4();
763-
/** @psalm-suppress InternalMethod */
764762
$rc4->setKey($secret);
765763

766764
return $rc4->encrypt($data);

apps/files_external/lib/Controller/AjaxController.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,15 @@ public function __construct($appName,
7373
*/
7474
private function generateSshKeys($keyLength) {
7575
$key = $this->rsaMechanism->createKey($keyLength);
76-
// Replace the placeholder label with a more meaningful one
77-
$key['publickey'] = str_replace('phpseclib-generated-key', gethostname(), $key['publickey']);
78-
79-
return $key;
76+
return [
77+
'private_key' => $key->toString('PKCS1'),
78+
// Replace the placeholder label with a more meaningful one
79+
'public_key' => str_replace(
80+
'phpseclib-generated-key',
81+
gethostname(),
82+
$key->getPublicKey()->toString('OpenSSH'),
83+
),
84+
];
8085
}
8186

8287
/**
@@ -88,10 +93,7 @@ private function generateSshKeys($keyLength) {
8893
public function getSshKeys($keyLength = 1024) {
8994
$key = $this->generateSshKeys($keyLength);
9095
return new JSONResponse(
91-
['data' => [
92-
'private_key' => $key['privatekey'],
93-
'public_key' => $key['publickey']
94-
],
96+
['data' => $key,
9597
'status' => 'success'
9698
]);
9799
}

apps/files_external/lib/Lib/Auth/PublicKey/RSA.php

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
use OCP\IConfig;
3030
use OCP\IL10N;
3131
use OCP\IUser;
32-
use phpseclib\Crypt\RSA as RSACrypt;
32+
use phpseclib3\Crypt\RSA as RSACrypt;
3333

3434
/**
3535
* RSA public key authentication
@@ -60,33 +60,32 @@ public function __construct(IL10N $l, IConfig $config) {
6060
* @return void
6161
*/
6262
public function manipulateStorageConfig(StorageConfig &$storage, ?IUser $user = null) {
63-
$auth = new RSACrypt();
64-
$auth->setPassword($this->config->getSystemValue('secret', ''));
65-
if (!$auth->loadKey($storage->getBackendOption('private_key'))) {
63+
try {
64+
$auth = RSACrypt::loadPrivateKey(
65+
$storage->getBackendOption('private_key'),
66+
$this->config->getSystemValue('secret', '')
67+
);
68+
} catch (\Throwable) {
6669
// Add fallback routine for a time where secret was not enforced to be exists
67-
$auth->setPassword('');
68-
if (!$auth->loadKey($storage->getBackendOption('private_key'))) {
69-
throw new \RuntimeException('unable to load private key');
70-
}
70+
$auth = RSACrypt::loadPrivateKey($storage->getBackendOption('private_key'));
7171
}
72+
7273
$storage->setBackendOption('public_key_auth', $auth);
7374
}
7475

7576
/**
7677
* Generate a keypair
7778
*
7879
* @param int $keyLenth
79-
* @return array ['privatekey' => $privateKey, 'publickey' => $publicKey]
8080
*/
81-
public function createKey($keyLength) {
81+
public function createKey($keyLength): RSACrypt\PrivateKey {
8282
$rsa = new RSACrypt();
83-
$rsa->setPublicKeyFormat(RSACrypt::PUBLIC_FORMAT_OPENSSH);
84-
$rsa->setPassword($this->config->getSystemValue('secret', ''));
85-
83+
8684
if ($keyLength !== 1024 && $keyLength !== 2048 && $keyLength !== 4096) {
8785
$keyLength = 1024;
8886
}
8987

90-
return $rsa->createKey($keyLength);
88+
return $rsa->createKey($keyLength)
89+
->withPassword($this->config->getSystemValue('secret', ''));
9190
}
9291
}

core/Command/Integrity/SignApp.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
use OC\IntegrityCheck\Checker;
2828
use OC\IntegrityCheck\Helpers\FileAccessHelper;
2929
use OCP\IURLGenerator;
30-
use phpseclib\Crypt\RSA;
31-
use phpseclib\File\X509;
30+
use phpseclib3\Crypt\RSA;
31+
use phpseclib3\File\X509;
3232
use Symfony\Component\Console\Command\Command;
3333
use Symfony\Component\Console\Input\InputInterface;
3434
use Symfony\Component\Console\Input\InputOption;
@@ -85,8 +85,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8585
return 1;
8686
}
8787

88-
$rsa = new RSA();
89-
$rsa->loadKey($privateKey);
88+
$rsa = RSA::loadPrivateKey($privateKey);
9089
$x509 = new X509();
9190
$x509->loadX509($keyBundle);
9291
$x509->setPrivateKey($rsa);

core/Command/Integrity/SignCore.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626

2727
use OC\IntegrityCheck\Checker;
2828
use OC\IntegrityCheck\Helpers\FileAccessHelper;
29-
use phpseclib\Crypt\RSA;
30-
use phpseclib\File\X509;
29+
use phpseclib3\Crypt\RSA;
30+
use phpseclib3\File\X509;
3131
use Symfony\Component\Console\Command\Command;
3232
use Symfony\Component\Console\Input\InputInterface;
3333
use Symfony\Component\Console\Input\InputOption;
@@ -80,8 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8080
return 1;
8181
}
8282

83-
$rsa = new RSA();
84-
$rsa->loadKey($privateKey);
83+
$rsa = RSA::loadPrivateKey($privateKey);
8584
$x509 = new X509();
8685
$x509->loadX509($keyBundle);
8786
$x509->setPrivateKey($rsa);

lib/private/Installer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
use OCP\IConfig;
5858
use OCP\ITempManager;
5959
use OCP\Migration\IOutput;
60-
use phpseclib\File\X509;
60+
use phpseclib3\File\X509;
6161
use Psr\Log\LoggerInterface;
6262

6363
/**

lib/private/IntegrityCheck/Checker.php

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444
use OCP\ICache;
4545
use OCP\ICacheFactory;
4646
use OCP\IConfig;
47-
use phpseclib\Crypt\RSA;
48-
use phpseclib\File\X509;
47+
use phpseclib3\Crypt\RSA;
48+
use phpseclib3\File\X509;
4949

5050
/**
5151
* Class Checker handles the code signing using X.509 and RSA. ownCloud ships with
@@ -188,24 +188,26 @@ private function generateHashes(\RecursiveIteratorIterator $iterator,
188188
*
189189
* @param array $hashes
190190
* @param X509 $certificate
191-
* @param RSA $privateKey
191+
* @param RSA\PrivateKey $privateKey
192192
* @return array
193193
*/
194-
private function createSignatureData(array $hashes,
194+
private function createSignatureData(
195+
array $hashes,
195196
X509 $certificate,
196-
RSA $privateKey): array {
197+
RSA\PrivateKey $privateKey,
198+
): array {
197199
ksort($hashes);
198200

199-
$privateKey->setSignatureMode(RSA::SIGNATURE_PSS);
200-
$privateKey->setMGFHash('sha512');
201-
// See https://tools.ietf.org/html/rfc3447#page-38
202-
$privateKey->setSaltLength(0);
203-
$signature = $privateKey->sign(json_encode($hashes));
201+
$signature = $privateKey
202+
->withPadding(RSA::SIGNATURE_PSS)
203+
->withMGFHash('sha512')
204+
->withSaltLength(0)
205+
->sign(json_encode($hashes));
204206

205207
return [
206208
'hashes' => $hashes,
207209
'signature' => base64_encode($signature),
208-
'certificate' => $certificate->saveX509($certificate->currentCert),
210+
'certificate' => $certificate->saveX509($certificate->getCurrentCert()),
209211
];
210212
}
211213

@@ -214,12 +216,12 @@ private function createSignatureData(array $hashes,
214216
*
215217
* @param string $path
216218
* @param X509 $certificate
217-
* @param RSA $privateKey
219+
* @param RSA\PrivateKey $privateKey
218220
* @throws \Exception
219221
*/
220222
public function writeAppSignature($path,
221223
X509 $certificate,
222-
RSA $privateKey) {
224+
RSA\PrivateKey $privateKey) {
223225
$appInfoDir = $path . '/appinfo';
224226
try {
225227
$this->fileAccessHelper->assertDirectoryExists($appInfoDir);
@@ -243,12 +245,12 @@ public function writeAppSignature($path,
243245
* Write the signature of core
244246
*
245247
* @param X509 $certificate
246-
* @param RSA $rsa
248+
* @param RSA\PrivateKey $rsa
247249
* @param string $path
248250
* @throws \Exception
249251
*/
250252
public function writeCoreSignature(X509 $certificate,
251-
RSA $rsa,
253+
RSA\PrivateKey $rsa,
252254
$path) {
253255
$coreDir = $path . '/core';
254256
try {
@@ -312,15 +314,14 @@ private function verify(string $signaturePath, string $basePath, string $certifi
312314
$certificate = $signatureData['certificate'];
313315

314316
// Check if certificate is signed by Nextcloud Root Authority
315-
$x509 = new \phpseclib\File\X509();
317+
$x509 = new X509();
316318
$rootCertificatePublicKey = $this->fileAccessHelper->file_get_contents($this->environmentHelper->getServerRoot().'/resources/codesigning/root.crt');
317319

318320
$rootCerts = $this->splitCerts($rootCertificatePublicKey);
319321
foreach ($rootCerts as $rootCert) {
320322
$x509->loadCA($rootCert);
321323
}
322-
$x509->loadX509($certificate);
323-
if (!$x509->validateSignature()) {
324+
if ($x509->loadX509($certificate) === false || !$x509->validateSignature()) {
324325
throw new InvalidSignatureException('Certificate is not valid.');
325326
}
326327
// Verify if certificate has proper CN. "core" CN is always trusted.
@@ -331,13 +332,18 @@ private function verify(string $signaturePath, string $basePath, string $certifi
331332
}
332333

333334
// Check if the signature of the files is valid
334-
$rsa = new \phpseclib\Crypt\RSA();
335-
$rsa->loadKey($x509->currentCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']);
336-
$rsa->setSignatureMode(RSA::SIGNATURE_PSS);
337-
$rsa->setMGFHash('sha512');
338-
// See https://tools.ietf.org/html/rfc3447#page-38
339-
$rsa->setSaltLength(0);
340-
if (!$rsa->verify(json_encode($expectedHashes), $signature)) {
335+
/** @var RSA\PublicKey|false */
336+
$rsa = $x509->getPublicKey();
337+
if ($rsa === false) {
338+
throw new InvalidSignatureException('Certificate does not provide valid public RSA key.');
339+
}
340+
341+
$rsa = $rsa
342+
->withPadding(RSA::SIGNATURE_PSS)
343+
->withMGFHash('sha512')
344+
->withSaltLength(0);
345+
346+
if (!$rsa->verify(json_encode($expectedHashes), (string)$signature)) {
341347
throw new InvalidSignatureException('Signature could not get verified.');
342348
}
343349

lib/private/Security/Crypto.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
use Exception;
3333
use OCP\IConfig;
3434
use OCP\Security\ICrypto;
35-
use phpseclib\Crypt\AES;
36-
use phpseclib\Crypt\Hash;
35+
use phpseclib3\Crypt\AES;
36+
use phpseclib3\Crypt\Hash;
3737

3838
/**
3939
* Class Crypto provides a high-level encryption layer using AES-CBC. If no key has been provided
@@ -52,7 +52,7 @@ class Crypto implements ICrypto {
5252
public function __construct(
5353
private IConfig $config,
5454
) {
55-
$this->cipher = new AES();
55+
$this->cipher = new AES('cbc');
5656
}
5757

5858
/**

0 commit comments

Comments
 (0)