blob: efee496cb6aab56a3079bdaa6f1e65876ea955b5 [file] [log] [blame]
Nico Huberee52fbc2023-06-24 11:52:57 +00001<?php
2/*
3 * SimpleID
4 *
5 * Copyright (C) Kelvin Mo 2010
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public
18 * License along with this program; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * $Id$
22 */
23
24/**
25 * Functions related to generating random bits and unique values.
26 *
27 * @package simpleid
28 * @since 0.8
29 * @filesource
30 */
31
32if (!defined('SIMPLEID_RAND_SOURCE')) {
33 /**
34 * The source of random bits. On Unix-like systems, this could be /dev/random
35 * or /dev/urandom
36 */
37 define('SIMPLEID_RAND_SOURCE', '/dev/urandom');
38}
39
40/**
41 * Obtains a number of random bytes. This function uses an entropy source specified
42 * in SIMPLEID_RAND_SOURCE. If SIMPLEID_RAND_SOURCE is not available, the mt_rand()
43 * PHP function is used
44 * If the native PHP random_bytes function exists (PHP 7+), this function won't be defined here.
45 *
46 * @param int $num_bytes the number of bytes to generate
47 * @return string a string containing random bytes
48 */
49if(!function_exists('random_bytes')) {
50 function random_bytes($num_bytes) {
51 static $f = null;
52 $bytes = '';
53 if ($f === null) {
54 if (SIMPLEID_RAND_SOURCE === null) {
55 $f = FALSE;
56 } else {
57 $f = @fopen(SIMPLEID_RAND_SOURCE, "r");
58 }
59 }
60 if ($f === FALSE) {
61 $bytes = '';
62 for ($i = 0; $i < $num_bytes; $i += 4) {
63 $bytes .= pack('L', mt_rand());
64 }
65 $bytes = substr($bytes, 0, $num_bytes);
66 } else {
67 $bytes = fread($f, $num_bytes);
68 }
69 return $bytes;
70 }
71}
72
73/**
74 * Obtains a random string of a specified number of bytes of entropy.
75 *
76 * The function calls the {@link random_bytes()} function with the specified
77 * number of bytes, then converts to a string containing only alphanumeric
78 * characters (case sensitive), plus the characters ., _ and -.
79 *
80 * The conversion method is based on the Base64 encoding. However, non-standard
81 * characters are used so that users are not confused and attempt to decode
82 * the returned string.
83 *
84 * @param int $num_bytes the approximate number of bytes of entropy in the
85 * random string
86 * @return string the random string
87 */
88function random_secret($num_bytes = 32) {
89 return strtr(base64_encode(random_bytes($num_bytes)),
90 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
91 '-_.9876543210zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA');
92}
93
94/**
95 * Generates a relatively unique identifier which can be used as, among other things,
96 * an OpenID association handle or an OAuth client identifier. The identifier
97 * returned is at least 24 characters long and contains only hexadecimal characters.
98 *
99 * Note that the identifier returned is not cryptographically secure.
100 *
101 * @return string a relatively unique identifier
102 */
103function random_id() {
104 $timeofday = gettimeofday();
105 return vsprintf('%08x%08x', $timeofday) . bin2hex(random_bytes(4));
106}
107?>