4444use OCP \ICache ;
4545use OCP \ICacheFactory ;
4646use 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
0 commit comments