From c4cc36b076b8977202ba5bec2aa610b7b318bb8d Mon Sep 17 00:00:00 2001
From: Antonin <zepcome@gmail.com>
Date: Thu, 2 Apr 2015 11:58:35 +0200
Subject: [PATCH] Using more secure token

---
 app/classes/Framadate/Security/Token.php | 60 +++++++++++++++++++++++-
 1 file changed, 58 insertions(+), 2 deletions(-)

diff --git a/app/classes/Framadate/Security/Token.php b/app/classes/Framadate/Security/Token.php
index 7222dbfa..b4a4b9bd 100644
--- a/app/classes/Framadate/Security/Token.php
+++ b/app/classes/Framadate/Security/Token.php
@@ -5,14 +5,17 @@ class Token {
 
     private $time;
     private $value;
+    private $length;
+    private static $codeAlphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';
 
-    function __construct() {
+    function __construct($length = 64) {
+        $this->length = $length;
         $this->time = time() + TOKEN_TIME;
         $this->value = $this->generate();
     }
 
     private function generate() {
-        return sha1(uniqid(mt_rand(), true));
+        return self::getToken($this->length);
     }
 
     public function getTime() {
@@ -31,5 +34,58 @@ class Token {
         return $value === $this->value;
     }
 
+    /**
+     * Get a secure token if possible, or a less secure one if not.
+     *
+     * @param int $length The token length
+     * @param bool $crypto_strong If passed, tells if the token is "cryptographically strong" or not.
+     * @return string
+     */
+    public static function getToken($length, &$crypto_strong = false) {
+        if (function_exists('openssl_random_pseudo_bytes')) {
+            openssl_random_pseudo_bytes(1, $crypto_strong); // Fake use to see if the algorithm used was "cryptographically strong"
+            return self::getSecureToken($length);
+        }
+        return self::getUnsecureToken($length);
+    }
+
+    public static function getUnsecureToken($length) {
+        $string = '';
+        mt_srand();
+        for ($i = 0; $i < $length; $i++) {
+            $string .= self::$codeAlphabet[mt_rand() % strlen(self::$codeAlphabet)];
+        }
+
+        return $string;
+    }
+
+    /**
+     * @author http://stackoverflow.com/a/13733588
+     */
+    public static function getSecureToken($length){
+        $token = "";
+        for($i=0;$i<$length;$i++){
+            $token .= self::$codeAlphabet[self::crypto_rand_secure(0,strlen(self::$codeAlphabet))];
+        }
+        return $token;
+    }
+
+    /**
+     * @author http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322
+     */
+    private static function crypto_rand_secure($min, $max) {
+        $range = $max - $min;
+        if ($range < 0) return $min; // not so random...
+        $log = log($range, 2);
+        $bytes = (int) ($log / 8) + 1; // length in bytes
+        $bits = (int) $log + 1; // length in bits
+        $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
+        do {
+            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
+            $rnd = $rnd & $filter; // discard irrelevant bits
+        } while ($rnd >= $range);
+        return $min + $rnd;
+    }
+
 }
  
\ No newline at end of file
-- 
GitLab