Subversion Repositories oidplus

Rev

Rev 1099 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1099 Rev 1116
Line 23... Line 23...
23
\defined('INSIDE_OIDPLUS') or die;
23
\defined('INSIDE_OIDPLUS') or die;
24
// phpcs:enable PSR1.Files.SideEffects
24
// phpcs:enable PSR1.Files.SideEffects
25
 
25
 
26
class OIDplusAuthPluginBCrypt extends OIDplusAuthPlugin {
26
class OIDplusAuthPluginBCrypt extends OIDplusAuthPlugin {
27
 
27
 
-
 
28
        /**
-
 
29
         * @param bool $html
-
 
30
         * @return void
-
 
31
         * @throws OIDplusException
-
 
32
         */
28
        public function init($html=true) {
33
        public function init(bool $html=true) {
29
                // Note: Example #3 here https://www.php.net/manual/en/function.password-hash.php can help you with finding a good cost value
34
                // Note: Example #3 here https://www.php.net/manual/en/function.password-hash.php can help you with finding a good cost value
30
                OIDplus::config()->prepareConfigKey('ra_bcrypt_cost', 'How complex should the BCrypt hash of RA passwords be? (Only for plugin A3_bcrypt; values 4-31, default 10)', 10, OIDplusConfig::PROTECTION_EDITABLE, function($value) {
35
                OIDplus::config()->prepareConfigKey('ra_bcrypt_cost', 'How complex should the BCrypt hash of RA passwords be? (Only for plugin A3_bcrypt; values 4-31, default 10)', '10', OIDplusConfig::PROTECTION_EDITABLE, function($value) {
31
                        if (empty($value) || !is_int($value) || ($value<4) || ($value>31)) {
36
                        if (empty($value) || !is_numeric($value) || ($value<4) || ($value>31)) {
32
                                throw new OIDplusException(_L('Invalid value for "cost" (must be 4-31, default 10).'));
37
                                throw new OIDplusException(_L('Invalid value for "cost" (must be 4-31, default 10).'));
33
                        }
38
                        }
34
                });
39
                });
35
        }
40
        }
36
 
41
 
-
 
42
        /**
-
 
43
         * @param string $authKey
-
 
44
         * @return bool
-
 
45
         */
37
        private function supportedCryptAlgo($authKey) {
46
        private function supportedCryptAlgo(string $authKey): bool {
38
                return str_starts_with($authKey, '$2$')  ||
47
                return str_starts_with($authKey, '$2$')  ||
39
                       str_starts_with($authKey, '$2a$') ||
48
                       str_starts_with($authKey, '$2a$') ||
40
                       str_starts_with($authKey, '$2b$') ||
49
                       str_starts_with($authKey, '$2b$') ||
41
                       str_starts_with($authKey, '$2x$') ||
50
                       str_starts_with($authKey, '$2x$') ||
42
                       str_starts_with($authKey, '$2y$');
51
                       str_starts_with($authKey, '$2y$');
43
        }
52
        }
44
 
53
 
-
 
54
        /**
-
 
55
         * @param OIDplusRAAuthInfo $authInfo
-
 
56
         * @param string $check_password
-
 
57
         * @return bool
-
 
58
         */
45
        public function verify(OIDplusRAAuthInfo $authInfo, $check_password) {
59
        public function verify(OIDplusRAAuthInfo $authInfo, string $check_password): bool {
46
                $authKey = $authInfo->getAuthKey();
60
                $authKey = $authInfo->getAuthKey();
47
 
61
 
48
                if (!$this->supportedCryptAlgo($authKey)) {
62
                if (!$this->supportedCryptAlgo($authKey)) {
49
                        // Unsupported algorithm
63
                        // Unsupported algorithm
50
                        return false;
64
                        return false;
Line 55... Line 69...
55
                // Alg Cost   Salt (128 bit)             Hash
69
                // Alg Cost   Salt (128 bit)             Hash
56
 
70
 
57
                return password_verify($check_password, $authKey);
71
                return password_verify($check_password, $authKey);
58
        }
72
        }
59
 
73
 
-
 
74
        /**
-
 
75
         * @param string $password
-
 
76
         * @return OIDplusRAAuthInfo
-
 
77
         * @throws OIDplusException
-
 
78
         */
60
        public function generate($password): OIDplusRAAuthInfo {
79
        public function generate(string $password): OIDplusRAAuthInfo {
61
                if (strlen($password) > 72) throw new OIDplusException(_L('Password is too long (max %1 bytes)',72));
80
                if (strlen($password) > 72) throw new OIDplusException(_L('Password is too long (max %1 bytes)',72));
62
                $cost = OIDplus::config()->getValue('ra_bcrypt_cost', 10);
81
                $cost = OIDplus::config()->getValue('ra_bcrypt_cost', 10);
63
                $calc_authkey = password_hash($password, PASSWORD_BCRYPT, array("cost" => $cost));
82
                $calc_authkey = password_hash($password, PASSWORD_BCRYPT, array("cost" => $cost));
64
                if (!$calc_authkey) throw new OIDplusException(_L('Error creating password hash'));
83
                if (!$calc_authkey) throw new OIDplusException(_L('Error creating password hash'));
65
                assert($this->supportedCryptAlgo($calc_authkey));
84
                assert($this->supportedCryptAlgo($calc_authkey));
66
                return new OIDplusRAAuthInfo($calc_authkey);
85
                return new OIDplusRAAuthInfo($calc_authkey);
67
        }
86
        }
68
 
87
 
-
 
88
        /**
-
 
89
         * @param string $reason
-
 
90
         * @return bool
-
 
91
         */
69
        public function availableForHash(&$reason): bool {
92
        public function availableForHash(string &$reason): bool {
70
                if (version_compare(PHP_VERSION, '7.4.0') >= 0) {
93
                if (version_compare(PHP_VERSION, '7.4.0') >= 0) {
71
                        $ok = in_array('2',  password_algos()) ||
94
                        $ok = in_array('2',  password_algos()) ||
72
                              in_array('2a', password_algos()) ||
95
                              in_array('2a', password_algos()) ||
73
                              in_array('2b', password_algos()) ||
96
                              in_array('2b', password_algos()) ||
74
                              in_array('2x', password_algos()) ||
97
                              in_array('2x', password_algos()) ||
Line 82... Line 105...
82
 
105
 
83
                $reason = _L('No fitting hash algorithm found');
106
                $reason = _L('No fitting hash algorithm found');
84
                return false;
107
                return false;
85
        }
108
        }
86
 
109
 
-
 
110
        /**
-
 
111
         * @param string $reason
-
 
112
         * @return bool
-
 
113
         */
87
        public function availableForVerify(&$reason): bool {
114
        public function availableForVerify(string &$reason): bool {
88
                return $this->availableForHash($reason);
115
                return $this->availableForHash($reason);
89
        }
116
        }
90
 
117
 
91
}
118
}