- Timestamp:
- 11/08/2017 11:47:04 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/random_compat/random_bytes_dev_urandom.php
r36886 r42130 5 5 * 6 6 * The MIT License (MIT) 7 * 8 * Copyright (c) 2015 Paragon Initiative Enterprises7 * 8 * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises 9 9 * 10 10 * Permission is hereby granted, free of charge, to any person obtaining a copy … … 31 31 } 32 32 33 /** 34 * Unless open_basedir is enabled, use /dev/urandom for 35 * random numbers in accordance with best practices 36 * 37 * Why we use /dev/urandom and not /dev/random 38 * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers 39 * 40 * @param int $bytes 41 * 42 * @throws Exception 43 * 44 * @return string 45 */ 46 function random_bytes($bytes) 47 { 48 static $fp = null; 33 if (!is_callable('random_bytes')) { 49 34 /** 50 * This block should only be run once 35 * Unless open_basedir is enabled, use /dev/urandom for 36 * random numbers in accordance with best practices 37 * 38 * Why we use /dev/urandom and not /dev/random 39 * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers 40 * 41 * @param int $bytes 42 * 43 * @throws Exception 44 * 45 * @return string 51 46 */ 52 if (empty($fp)) { 47 function random_bytes($bytes) 48 { 49 static $fp = null; 53 50 /** 54 * We use /dev/urandom if it is a char device. 55 * We never fall back to /dev/random 51 * This block should only be run once 56 52 */ 57 $fp = fopen('/dev/urandom', 'rb'); 58 if (!empty($fp)) { 59 $st = fstat($fp); 60 if (($st['mode'] & 0170000) !== 020000) { 61 fclose($fp); 62 $fp = false; 53 if (empty($fp)) { 54 /** 55 * We use /dev/urandom if it is a char device. 56 * We never fall back to /dev/random 57 */ 58 $fp = fopen('/dev/urandom', 'rb'); 59 if (!empty($fp)) { 60 $st = fstat($fp); 61 if (($st['mode'] & 0170000) !== 020000) { 62 fclose($fp); 63 $fp = false; 64 } 65 } 66 67 if (!empty($fp)) { 68 /** 69 * stream_set_read_buffer() does not exist in HHVM 70 * 71 * If we don't set the stream's read buffer to 0, PHP will 72 * internally buffer 8192 bytes, which can waste entropy 73 * 74 * stream_set_read_buffer returns 0 on success 75 */ 76 if (is_callable('stream_set_read_buffer')) { 77 stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER); 78 } 79 if (is_callable('stream_set_chunk_size')) { 80 stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER); 81 } 63 82 } 64 83 } 65 84 85 try { 86 $bytes = RandomCompat_intval($bytes); 87 } catch (TypeError $ex) { 88 throw new TypeError( 89 'random_bytes(): $bytes must be an integer' 90 ); 91 } 92 93 if ($bytes < 1) { 94 throw new Error( 95 'Length must be greater than 0' 96 ); 97 } 98 99 /** 100 * This if() block only runs if we managed to open a file handle 101 * 102 * It does not belong in an else {} block, because the above 103 * if (empty($fp)) line is logic that should only be run once per 104 * page load. 105 */ 66 106 if (!empty($fp)) { 67 107 /** 68 * stream_set_read_buffer() does not exist in HHVM 69 * 70 * If we don't set the stream's read buffer to 0, PHP will 71 * internally buffer 8192 bytes, which can waste entropy 72 * 73 * stream_set_read_buffer returns 0 on success 108 * @var int 74 109 */ 75 if (function_exists('stream_set_read_buffer')) { 76 stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER); 77 } 78 if (function_exists('stream_set_chunk_size')) { 79 stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER); 110 $remaining = $bytes; 111 112 /** 113 * @var string|bool 114 */ 115 $buf = ''; 116 117 /** 118 * We use fread() in a loop to protect against partial reads 119 */ 120 do { 121 /** 122 * @var string|bool 123 */ 124 $read = fread($fp, $remaining); 125 if (!is_string($read)) { 126 if ($read === false) { 127 /** 128 * We cannot safely read from the file. Exit the 129 * do-while loop and trigger the exception condition 130 * 131 * @var string|bool 132 */ 133 $buf = false; 134 break; 135 } 136 } 137 /** 138 * Decrease the number of bytes returned from remaining 139 */ 140 $remaining -= RandomCompat_strlen($read); 141 /** 142 * @var string|bool 143 */ 144 $buf = $buf . $read; 145 } while ($remaining > 0); 146 147 /** 148 * Is our result valid? 149 */ 150 if (is_string($buf)) { 151 if (RandomCompat_strlen($buf) === $bytes) { 152 /** 153 * Return our random entropy buffer here: 154 */ 155 return $buf; 156 } 80 157 } 81 158 } 82 }83 159 84 try {85 $bytes = RandomCompat_intval($bytes);86 } catch (TypeError $ex) {87 throw new TypeError(88 ' random_bytes(): $bytes must be an integer'160 /** 161 * If we reach here, PHP has failed us. 162 */ 163 throw new Exception( 164 'Error reading from source device' 89 165 ); 90 166 } 91 92 if ($bytes < 1) {93 throw new Error(94 'Length must be greater than 0'95 );96 }97 98 /**99 * This if() block only runs if we managed to open a file handle100 *101 * It does not belong in an else {} block, because the above102 * if (empty($fp)) line is logic that should only be run once per103 * page load.104 */105 if (!empty($fp)) {106 $remaining = $bytes;107 $buf = '';108 109 /**110 * We use fread() in a loop to protect against partial reads111 */112 do {113 $read = fread($fp, $remaining);114 if ($read === false) {115 /**116 * We cannot safely read from the file. Exit the117 * do-while loop and trigger the exception condition118 */119 $buf = false;120 break;121 }122 /**123 * Decrease the number of bytes returned from remaining124 */125 $remaining -= RandomCompat_strlen($read);126 $buf .= $read;127 } while ($remaining > 0);128 129 /**130 * Is our result valid?131 */132 if ($buf !== false) {133 if (RandomCompat_strlen($buf) === $bytes) {134 /**135 * Return our random entropy buffer here:136 */137 return $buf;138 }139 }140 }141 142 /**143 * If we reach here, PHP has failed us.144 */145 throw new Exception(146 'Error reading from source device'147 );148 167 }
Note: See TracChangeset
for help on using the changeset viewer.