File: TimeLimitedToken.php

package info (click to toggle)
simplesamlphp 1.16.3-1%2Bdeb10u2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 21,036 kB
  • sloc: php: 73,175; ansic: 875; sh: 83; perl: 82; xml: 52; makefile: 46
file content (147 lines) | stat: -rw-r--r-- 4,320 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php

namespace SimpleSAML\Auth;

/**
 * A class that generates and verifies time-limited tokens.
 */
class TimeLimitedToken
{

    /**
     * @var string
     */
    protected $secretSalt;

    /**
     * @var int
     */
    protected $lifetime;

    /**
     * @var int
     */
    protected $skew;

    /**
     * @var string
     */
    protected $algo;


    /**
     * Create a new time-limited token.
     *
     * Please note that the default algorithm will change in SSP 1.15.0 to SHA-256 instead of SHA-1.
     *
     * @param int $lifetime Token lifetime in seconds. Defaults to 900 (15 min).
     * @param string $secretSalt A random and unique salt per installation. Defaults to the salt in the configuration.
     * @param int $skew The allowed time skew (in seconds) to correct clock deviations. Defaults to 1 second.
     * @param string $algo The hash algorithm to use to generate the tokens. Defaults to SHA-1.
     *
     * @throws \InvalidArgumentException if the given parameters are invalid.
     */
    public function __construct($lifetime = 900, $secretSalt = null, $skew = 1, $algo = 'sha1')
    {
        if ($secretSalt === null) {
            $secretSalt = \SimpleSAML\Utils\Config::getSecretSalt();
        }

        if (!in_array($algo, hash_algos(), true)) {
            throw new \InvalidArgumentException('Invalid hash algorithm "'.$algo.'"');
        }

        $this->secretSalt = $secretSalt;
        $this->lifetime = $lifetime;
        $this->skew = $skew;
        $this->algo = $algo;
    }


    /**
     * Add some given data to the current token. This data will be needed later too for token validation.
     *
     * This mechanism can be used to provide context for a token, such as a user identifier of the only subject
     * authorised to use it. Note also that multiple data can be added to the token. This means that upon validation,
     * not only the same data must be added, but also in the same order.
     *
     * @param string $data The data to incorporate into the current token.
     */
    public function addVerificationData($data)
    {
        $this->secretSalt .= '|'.$data;
    }


    /**
     * Calculates a token value for a given offset.
     *
     * @param int $offset The offset to use.
     * @param int|null $time The time stamp to which the offset is relative to. Defaults to the current time.
     *
     * @return string The token for the given time and offset.
     */
    private function calculateTokenValue($offset, $time = null)
    {
        if ($time === null) {
            $time = time();
        }
        // a secret salt that should be randomly generated for each installation
        return hash(
            $this->algo,
            $offset.':'.floor(($time - $offset) / ($this->lifetime + $this->skew)).':'.$this->secretSalt
        );
    }


    /**
     * Generates a token that contains an offset and a token value, using the current offset.
     *
     * @return string A time-limited token with the offset respect to the beginning of its time slot prepended.
     */
    public function generate()
    {
        $time = time();
        $current_offset = ($time - $this->skew) % ($this->lifetime + $this->skew);
        return dechex($current_offset).'-'.$this->calculateTokenValue($current_offset, $time);
    }


    /**
     * @see generate
     * @deprecated This method will be removed in SSP 2.0. Use generate() instead.
     */
    public function generate_token()
    {
        return $this->generate();
    }


    /**
     * Validates a token by calculating the token value for the provided offset and comparing it.
     *
     * @param string $token The token to validate.
     *
     * @return boolean True if the given token is currently valid, false otherwise.
     */
    public function validate($token)
    {
        $splittoken = explode('-', $token);
        if (count($splittoken) !== 2) {
            return false;
        }
        $offset = intval(hexdec($splittoken[0]));
        $value = $splittoken[1];
        return ($this->calculateTokenValue($offset) === $value);
    }


    /**
     * @see validate
     * @deprecated This method will be removed in SSP 2.0. Use validate() instead.
     */
    public function validate_token($token)
    {
        return $this->validate($token);
    }
}