73b3d5372e5a6dbb6435016aaf0e29da2772c6a4
[friendica.git/.git] / tests / src / Util / CryptoTest.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2020, Friendica
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  * This is in the same namespace as Crypto for mocking 'rand' and 'random_init'
21  */
22 namespace Friendica\Util;
23
24 use phpseclib\Crypt\RSA;
25 use phpseclib\Math\BigInteger;
26 use PHPUnit\Framework\TestCase;
27
28 class CryptoTest extends TestCase
29 {
30         /**
31          * Replaces random_int results with given mocks
32          *
33          */
34         private function assertRandomInt($min, $max)
35         {
36                 global $phpMock;
37                 $phpMock['random_int'] = function ($mMin, $mMax) use ($min, $max) {
38                         $this->assertEquals($min, $mMin);
39                         $this->assertEquals($max, $mMax);
40                         return 1;
41                 };
42         }
43
44         public function testRandomDigitsRandomInt()
45         {
46                 $this->assertRandomInt(0, 9);
47
48                 $test = Crypto::randomDigits(1);
49                 $this->assertEquals(1, strlen($test));
50                 $this->assertEquals(1, $test);
51
52                 $test = Crypto::randomDigits(8);
53                 $this->assertEquals(8, strlen($test));
54                 $this->assertEquals(11111111, $test);
55         }
56
57         public function dataRsa()
58         {
59                 return [
60                         'diaspora' => [
61                                 'key' => file_get_contents(__DIR__ . '/../../datasets/crypto/rsa/diaspora-public-rsa-base64'),
62                                 'expected' => file_get_contents(__DIR__ . '/../../datasets/crypto/rsa/diaspora-public-pem'),
63                         ],
64                 ];
65         }
66
67         /**
68          * @dataProvider dataRsa
69          */
70         public function testPubRsaToMe(string $key, string $expected)
71         {
72                 $this->assertEquals($expected, Crypto::rsaToPem(base64_decode($key)));
73         }
74
75
76         public function dataPEM()
77         {
78                 return [
79                         'diaspora' => [
80                                 'key' => file_get_contents(__DIR__ . '/../../datasets/crypto/rsa/diaspora-public-pem'),
81                         ],
82                 ];
83         }
84
85         /**
86          * @dataProvider dataPEM
87          */
88         public function testPemToMe(string $key)
89         {
90                 Crypto::pemToMe($key, $m, $e);
91
92                 $expectedRSA = new RSA();
93                 $expectedRSA->loadKey([
94                                                                   'e' => new BigInteger($e, 256),
95                                                                   'n' => new BigInteger($m, 256)
96                                                           ]);
97
98                 $this->assertEquals($expectedRSA->getPublicKey(), $key);
99         }
100
101         /**
102          * @dataProvider dataPEM
103          */
104         public function testMeToPem(string $key)
105         {
106                 Crypto::pemToMe($key, $m, $e);
107
108                 $checkKey = Crypto::meToPem($m, $e);
109
110                 $this->assertEquals($key, $checkKey);
111         }
112 }
113
114 /**
115  * A workaround to replace the PHP native random_int() (>= 7.0) with a mocked function
116  *
117  * @return int
118  */
119 function random_int($min, $max)
120 {
121         global $phpMock;
122         if (isset($phpMock['random_int'])) {
123                 $result = call_user_func_array($phpMock['random_int'], func_get_args());
124                 return $result;
125         }
126 }