| [ Index ] |
PHP Cross Reference of MantisBT |
[Summary view] [Print] [Text view]
1 <?php 2 # MantisBT - A PHP based bugtracking system 3 4 # MantisBT is free software: you can redistribute it and/or modify 5 # it under the terms of the GNU General Public License as published by 6 # the Free Software Foundation, either version 2 of the License, or 7 # (at your option) any later version. 8 # 9 # MantisBT is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # GNU General Public License for more details. 13 # 14 # You should have received a copy of the GNU General Public License 15 # along with MantisBT. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Crypto API 19 * 20 * @package CoreAPI 21 * @subpackage CryptoAPI 22 * @copyright Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org 23 * @copyright Copyright (C) 2002 - 2011 MantisBT Team - mantisbt-dev@lists.sourceforge.net 24 * @link http://www.mantisbt.org 25 * 26 * @uses config_api.php 27 * @uses constant_inc.php 28 * @uses error_api.php 29 * @uses utility_api.php 30 */ 31 32 require_api( 'config_api.php' ); 33 require_api( 'constant_inc.php' ); 34 require_api( 'error_api.php' ); 35 require_api( 'utility_api.php' ); 36 37 /** 38 * Initialise the CryptoAPI subsystem. This function checks whether the master 39 * salt is specified correctly within the configuration. If not, a fatal error 40 * is produced to protect against invalid configuration impacting the security 41 * of the MantisBT installation. 42 * @return null 43 */ 44 function crypto_init() { 45 if ( !defined( 'MANTIS_MAINTENANCE_MODE' ) ) { 46 if ( strlen( config_get_global( 'crypto_master_salt' ) ) < 16 ) { 47 trigger_error( ERROR_CRYPTO_MASTER_SALT_INVALID, ERROR ); 48 } 49 } 50 return; 51 } 52 53 /** 54 * Generate a random string (raw binary output) for cryptographic purposes such 55 * as nonces, IVs, default passwords, etc. This function will attempt to 56 * generate strong randomness but can optionally be used to generate weaker 57 * randomness if less security is needed or a strong source of randomness isn't 58 * available. The use of weak randomness for cryptographic purposes is strongly 59 * discouraged because it contains low entropy and is predictable. 60 * 61 * Note that openssl_random_pseudo_bytes seems to perform very poorly on 62 * Windows servers. Therefore we don't event attempt to use this PRNG source 63 * if the server is running Windows. 64 * 65 * @param int $p_bytes Number of bytes of randomness required 66 * @param bool $p_require_strong_generator Whether or not a weak source of randomness can be used by this function 67 * @return string|null Raw binary string containing the requested number of bytes of random output or null if the output couldn't be created 68 */ 69 function crypto_generate_random_string( $p_bytes, $p_require_strong_generator = true ) { 70 71 # First we attempt to use the secure PRNG provided by OpenSSL in PHP 5.3 72 # Exclude Windows as per http://bugs.php.net/bug.php?id=51636 73 if ( !is_windows_server() && function_exists( 'openssl_random_pseudo_bytes' ) ) { 74 $t_random_bytes = openssl_random_pseudo_bytes( $p_bytes, $t_strong ); 75 if ( $t_random_bytes !== false ) { 76 if ( $p_require_strong_generator && $t_strong === true ) { 77 $t_random_string = $t_random_bytes; 78 } else if ( !$p_require_strong_generator ) { 79 $t_random_string = $t_random_bytes; 80 } 81 } 82 } 83 84 # Next we try to use the /dev/urandom PRNG provided on Linux systems. This 85 # is nowhere near as secure as /dev/random but it is still satisfactory for 86 # the needs of MantisBT, especially given the fact that we don't want this 87 # function to block while waiting for the system to generate more entropy. 88 if ( !is_windows_server() ) { 89 $t_urandom_fp = @fopen( '/dev/urandom', 'rb' ); 90 if ( $t_urandom_fp !== false ) { 91 $t_random_bytes = @fread( $t_urandom_fp, $p_bytes ); 92 if ( $t_random_bytes !== false ) { 93 $t_random_string = $t_random_bytes; 94 } 95 @fclose( $t_urandom_fp ); 96 } 97 } 98 99 # For Windows systems, we can try using Microsoft CryptoAPI to retrieve 100 # more reliable PRNG output than what PHP can provide by itself. 101 # !TODO 102 103 # At this point we've run out of possibilities for generating randomness 104 # from a strong source. Unless weak output is specifically allowed by the 105 # $p_require_strong_generator argument, we should return null as we've 106 # failed to generate randomness to a satisfactory security level. 107 if ( !isset( $t_random_string ) && $p_require_strong_generator ) { 108 return null; 109 } 110 111 # As a last resort we have to fall back to using the insecure Mersenne 112 # Twister pseudo random number generator provided in PHP. This DOES NOT 113 # produce cryptographically secure randomness and thus the output of the 114 # PRNG is easily guessable. In an attempt to make it harder to guess the 115 # internal state of the PRNG, we salt the PRNG output with a known secret 116 # and hash it. 117 if ( !isset( $t_random_string ) ) { 118 $t_secret_key = 'prng' . config_get_global( 'crypto_master_salt' ); 119 $t_random_bytes = ''; 120 for ( $i = 0; $i < $p_bytes; $i += 64 ) { 121 $t_random_segment = ''; 122 for ( $j = 0; $j < 64; $j++ ) { 123 $t_random_segment .= base_convert( mt_rand(), 10, 36 ); 124 } 125 $t_random_segment .= $i; 126 $t_random_segment .= $t_secret_key; 127 $t_random_bytes .= hash( 'whirlpool', $t_random_segment, true ); 128 } 129 $t_random_string = substr( $t_random_bytes, 0, $p_bytes ); 130 if ( $t_random_string === false ) { 131 return null; # Unexpected error 132 } 133 } 134 135 return $t_random_string; 136 } 137 138 /** 139 * Generate a strong random string (raw binary output) for cryptographic 140 * purposes such as nonces, IVs, default passwords, etc. If a strong source 141 * of randomness is not available, this function will fail and produce an 142 * error. Strong randomness is different from weak randomness in that a strong 143 * randomness generator doesn't produce predictable output and has much higher 144 * entropy. Where randomness is being used for cryptographic purposes, a strong 145 * source of randomness should always be used. 146 * @param int $p_bytes Number of bytes of strong randomness required 147 * @return string Raw binary string containing the requested number of bytes of random output 148 */ 149 function crypto_generate_strong_random_string( $p_bytes ) { 150 $t_random_string = crypto_generate_random_string( $p_bytes, true ); 151 if ( $t_random_string === null ) { 152 trigger_error( ERROR_CRYPTO_CAN_NOT_GENERATE_STRONG_RANDOMNESS, ERROR ); 153 } 154 return $t_random_string; 155 } 156 157 /** 158 * Generate a nonce encoded using the base64 with URI safe alphabet approach 159 * described in RFC4648. Note that the minimum length is rounded up to the next 160 * number with a factor of 4 so that padding is never added to the end of the 161 * base64 output. This means the '=' padding character is never present in the 162 * output. Due to the reduced character set of base64 encoding, the actual 163 * amount of entropy produced by this function for a given output string length 164 * is 3/4 (0.75) that of raw unencoded output produced with the 165 * crypto_generate_strong_random_string( $p_bytes ) function. 166 * @param int $p_minimum_length Minimum number of characters required for the nonce 167 * @return string Nonce encoded according to the base64 with URI safe alphabet approach described in RFC4648 168 */ 169 function crypto_generate_uri_safe_nonce( $p_minimum_length ) { 170 $t_length_mod4 = $p_minimum_length % 4; 171 $t_adjusted_length = $p_minimum_length + 4 - ($t_length_mod4 ? $t_length_mod4 : 4); 172 $t_raw_bytes_required = ( $t_adjusted_length / 4 ) * 3; 173 if ( !is_windows_server() ) { 174 $t_random_bytes = crypto_generate_strong_random_string( $t_raw_bytes_required ); 175 } else { 176 # It's currently not possible to generate strong random numbers 177 # with PHP on Windows so we have to resort to using PHP's 178 # built-in insecure PRNG. 179 $t_random_bytes = crypto_generate_random_string( $t_raw_bytes_required, false ); 180 } 181 $t_base64_encoded = base64_encode( $t_random_bytes ); 182 # Note: no need to translate trailing = padding characters because our 183 # length rounding ensures that padding is never required. 184 $t_random_nonce = strtr( $t_base64_encoded, '+/', '-_' ); 185 return $t_random_nonce; 186 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Jul 28 15:48:31 2011 | Cross-referenced by PHPXref 0.7 |