]> git.mxchange.org Git - friendica.git/commitdiff
Move random Digits to Crypto class
authorPhilipp Holzer <admin@philipp.info>
Mon, 5 Nov 2018 08:37:03 +0000 (09:37 +0100)
committerPhilipp Holzer <admin@philipp.info>
Mon, 5 Nov 2018 20:02:54 +0000 (21:02 +0100)
boot.php
include/conversation.php
mod/editpost.php
mod/photos.php
src/Core/System.php
src/Object/Post.php
src/Util/Crypto.php
tests/src/Util/CryptoTest.php [new file with mode: 0644]

index a94b380387bcb262e50a0826e7ab1fd0821c2731..6373b2c64b4c525753897d9f95e859280492f112 100644 (file)
--- a/boot.php
+++ b/boot.php
@@ -673,16 +673,6 @@ function curPageURL()
        return $pageURL;
 }
 
-function random_digits($digits)
-{
-       $rn = '';
-       for ($i = 0; $i < $digits; $i++) {
-               /// @TODO Avoid rand/mt_rand, when it comes to cryptography, they are generating predictable (seedable) numbers.
-               $rn .= rand(0, 9);
-       }
-       return $rn;
-}
-
 function get_server()
 {
        $server = Config::get("system", "directory");
index c10a7bec739a0698b8ae918e359327ba059a4d2d..cd635521e51516545e43e937c4e294a252a4b3e6 100644 (file)
@@ -27,6 +27,7 @@ use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Proxy as ProxyUtils;
 use Friendica\Util\Temporal;
 use Friendica\Util\XML;
+use Friendica\Util\Crypto;
 
 function item_extract_images($body) {
 
@@ -1166,7 +1167,7 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
                '$notes_cid'    => $notes_cid,
                '$sourceapp'    => L10n::t($a->sourcename),
                '$cancel'       => L10n::t('Cancel'),
-               '$rand_num'     => random_digits(12),
+               '$rand_num'     => Crypto::randomDigits(12),
 
                // ACL permissions box
                '$acl'           => $x['acl'],
index 0023e35edd963dd069f0c934cff44512a0f183e9..b518588a591a46042cef3b7978295a42d9f58227 100644 (file)
@@ -12,6 +12,7 @@ use Friendica\Core\System;
 use Friendica\Model\FileTag;
 use Friendica\Model\Item;
 use Friendica\Database\DBA;
+use Friendica\Util\Crypto;
 
 function editpost_content(App $a)
 {
@@ -131,7 +132,7 @@ function editpost_content(App $a)
                '$jotplugins' => $jotplugins,
                '$sourceapp' => L10n::t($a->sourcename),
                '$cancel' => L10n::t('Cancel'),
-               '$rand_num' => random_digits(12),
+               '$rand_num' => Crypto::randomDigits(12),
 
                //jot nav tab (used in some themes)
                '$message' => L10n::t('Message'),
index 69b1972d4cdbcc25bb562a96753e3b6a587bda9c..7a49f061a752c9addeb79c4928fc054881d8c405 100644 (file)
@@ -26,6 +26,7 @@ use Friendica\Model\User;
 use Friendica\Network\Probe;
 use Friendica\Object\Image;
 use Friendica\Protocol\DFRN;
+use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Map;
 use Friendica\Util\Security;
@@ -1500,7 +1501,7 @@ function photos_content(App $a)
                                                '$preview' => L10n::t('Preview'),
                                                '$sourceapp' => L10n::t($a->sourcename),
                                                '$ww' => '',
-                                               '$rand_num' => random_digits(12)
+                                               '$rand_num' => Crypto::randomDigits(12)
                                        ]);
                                }
                        }
@@ -1539,7 +1540,7 @@ function photos_content(App $a)
                                                '$preview' => L10n::t('Preview'),
                                                '$sourceapp' => L10n::t($a->sourcename),
                                                '$ww' => '',
-                                               '$rand_num' => random_digits(12)
+                                               '$rand_num' => Crypto::randomDigits(12)
                                        ]);
                                }
 
@@ -1599,7 +1600,7 @@ function photos_content(App $a)
                                                        '$preview' => L10n::t('Preview'),
                                                        '$sourceapp' => L10n::t($a->sourcename),
                                                        '$ww' => '',
-                                                       '$rand_num' => random_digits(12)
+                                                       '$rand_num' => Crypto::randomDigits(12)
                                                ]);
                                        }
                                }
index 0f9a611ab92b084d2d5d758b0c435a7efcfc56f5..d24581e996202a6b54be24bfc626abcfb4fec305 100644 (file)
@@ -265,7 +265,6 @@ class System extends BaseObject
        function notice($s)
        function info($s)
        function is_site_admin()
-       function random_digits($digits)
        function get_server()
        function get_temppath()
        function get_cachefile($file, $writemode = true)
index e2c1ea03c3f7186af863d9dd7efe10c9ed471c3f..644d53e25d8207f8f9d2d16180ba5ec9903ac98e 100644 (file)
@@ -18,6 +18,7 @@ use Friendica\Database\DBA;
 use Friendica\Model\Contact;
 use Friendica\Model\Item;
 use Friendica\Model\Term;
+use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Proxy as ProxyUtils;
 use Friendica\Util\Temporal;
@@ -815,7 +816,7 @@ class Post extends BaseObject
                                '$indent'      => $indent,
                                '$sourceapp'   => L10n::t($a->sourcename),
                                '$ww'          => $conv->getMode() === 'network' ? $ww : '',
-                               '$rand_num'    => random_digits(12)
+                               '$rand_num'    => Crypto::randomDigits(12)
                        ]);
                }
 
index 2b1ce0f02be5b77f78f3d1844c34ddd7fd010427..785860c182887d0104bafa66e741ab9e36860372 100644 (file)
@@ -476,4 +476,30 @@ class Crypto
 
                return self::decryptAES256CBC(base64url_decode($data['data']), $k, $i);
        }
+
+
+       /**
+        * Creates cryptographic secure random digits
+        *
+        * @param string $digits The count of digits
+        * @return int The random Digits
+        */
+       public static function randomDigits($digits)
+       {
+               $rn = '';
+
+               if (!function_exists('random_int')) {
+                       // using rand() function for PHP 5.x compatibility
+                       for ($i = 0; $i < $digits; $i++) {
+                               $rn .= rand(0, 9);
+                       }
+               } else {
+                       // generating cryptographically secure pseudo-random integers
+                       for ($i = 0; $i < $digits; $i++) {
+                               $rn .= random_int(0, 9);
+                       }
+               }
+
+               return $rn;
+       }
 }
diff --git a/tests/src/Util/CryptoTest.php b/tests/src/Util/CryptoTest.php
new file mode 100644 (file)
index 0000000..d014d28
--- /dev/null
@@ -0,0 +1,131 @@
+<?php
+
+// this is in the same namespace as Install for mocking 'rand' and 'random_init'
+namespace Friendica\Util;
+
+use PHPUnit\Framework\TestCase;
+
+class CryptoTest extends TestCase
+{
+       /**
+        * Replaces function_exists results with given mocks
+        *
+        * @param array $functions a list from function names and their result
+        */
+       private function setFunctions($functions)
+       {
+               global $phpMock;
+               $phpMock['function_exists'] = function($function) use ($functions) {
+                       foreach ($functions as $name => $value) {
+                               if ($function == $name) {
+                                       return $value;
+                               }
+                       }
+                       return '__phpunit_continue__';
+               };
+       }
+
+       /**
+        * Replaces rand results with given mocks
+        *
+        */
+       private function assertRand($min, $max)
+       {
+               global $phpMock;
+               $phpMock['rand'] = function($mMin, $mMax) use ($min, $max) {
+                       $this->assertEquals($min, $mMin);
+                       $this->assertEquals($max, $mMax);
+                       return 1;
+               };
+       }
+
+       /**
+        * Replaces rand results with given mocks
+        *
+        */
+       private function assertRandomInt($min, $max)
+       {
+               global $phpMock;
+               $phpMock['random_int'] = function($mMin, $mMax) use ($min, $max) {
+                       $this->assertEquals($min, $mMin);
+                       $this->assertEquals($max, $mMax);
+                       return 1;
+               };
+       }
+
+       public function testRandomDigitsRand()
+       {
+               $this->setFunctions(['random_int' => false]);
+               $this->assertRand(0, 9);
+
+               $test = Crypto::randomDigits(1);
+               $this->assertEquals(1, strlen($test));
+               $this->assertEquals(1, $test);
+
+               $test = Crypto::randomDigits(8);
+               $this->assertEquals(8, strlen($test));
+               $this->assertEquals(11111111, $test);
+       }
+
+
+       public function testRandomDigitsRandomInt()
+       {
+               $this->setFunctions(['random_int' => true]);
+               $this->assertRandomInt(0, 9);
+
+               $test = Crypto::randomDigits(1);
+               $this->assertEquals(1, strlen($test));
+               $this->assertEquals(1, $test);
+
+               $test = Crypto::randomDigits(8);
+               $this->assertEquals(8, strlen($test));
+               $this->assertEquals(11111111, $test);
+       }
+}
+
+/**
+ * A workaround to replace the PHP native function_exists() with a mocked function
+ *
+ * @param string $function_name the Name of the function
+ *
+ * @return bool true or false
+ */
+function function_exists($function_name)
+{
+       global $phpMock;
+       if (isset($phpMock['function_exists'])) {
+               $result = call_user_func_array($phpMock['function_exists'], func_get_args());
+               if ($result !== '__phpunit_continue__') {
+                       return $result;
+               }
+       }
+       return call_user_func_array('\function_exists', func_get_args());
+}
+
+/**
+ * A workaround to replace the PHP native rand() (< 7.0) with a mocked function
+ *
+ * @return int
+ */
+function rand($min, $max)
+{
+       global $phpMock;
+       if (isset($phpMock['rand'])) {
+               $result = call_user_func_array($phpMock['rand'], func_get_args());
+               return $result;
+       }
+}
+
+/**
+ * A workaround to replace the PHP native random_int() (>= 7.0) with a mocked function
+ *
+ * @return int
+ */
+function random_int($min, $max)
+{
+       global $phpMock;
+       if (isset($phpMock['random_int'])) {
+               $result = call_user_func_array($phpMock['random_int'], func_get_args());
+               return $result;
+       }
+}