Completed
Push — master ( 4bde32...7747d8 )
by Antonio Carlos
02:10
created

Base32::checkForValidCharacters()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
1
<?php
2
3
namespace PragmaRX\Google2FA\Support;
4
5
use ParagonIE\ConstantTime\Base32 as ParagonieBase32;
6
use PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException;
7
8
trait Base32
9
{
10
    /**
11
     * Generate a digit secret key in base32 format.
12
     *
13
     * @param int $length
14
     *
15
     * @return string
16
     */
17
    public function generateBase32RandomKey($length = 16, $prefix = '')
18
    {
19
        $b32 = '234567QWERTYUIOPASDFGHJKLZXCVBNM';
20
21
        $secret = $prefix ? $this->toBase32($prefix) : '';
22
23
        for ($i = 0; $i < $length; $i++) {
24
            $secret .= $b32[$this->getRandomNumber()];
25
        }
26
27
        $this->validateSecret($secret);
28
29
        return $secret;
30
    }
31
32
    /**
33
     * Decodes a base32 string into a binary string.
34
     *
35
     * @param string $b32
36
     *
37
     * @throws InvalidCharactersException
38
     *
39
     * @return int
40
     */
41
    public function base32Decode($b32)
42
    {
43
        $b32 = strtoupper($b32);
44
45
        $this->validateSecret($b32);
46
47
        return ParagonieBase32::decodeUpper($b32);
48
    }
49
50
    /**
51
     * Encode a string to Base32.
52
     *
53
     * @param $string
54
     *
55
     * @return mixed
56
     */
57
    public function toBase32($string)
58
    {
59
        $encoded = ParagonieBase32::encodeUpper($string);
60
61
        return str_replace('=', '', $encoded);
62
    }
63
64
    /**
65
     * Get a random number.
66
     *
67
     * @param $from
68
     * @param $to
69
     *
70
     * @return int
71
     */
72
    protected function getRandomNumber($from = 0, $to = 31)
73
    {
74
        return random_int($from, $to);
75
    }
76
77
    /**
78
     * Validate the secret.
79
     *
80
     * @param $b32
81
     */
82
    protected function validateSecret($b32)
83
    {
84
        $this->checkForValidCharacters($b32);
85
86
        $this->checkGoogleAuthenticatorCompatibility($b32);
87
    }
88
89
    /**
90
     * Check if the secret key is compatible with Google Authenticator.
91
     *
92
     * @param $b32
93
     *
94
     * @throws IncompatibleWithGoogleAuthenticatorException
95
     */
96
    protected function checkGoogleAuthenticatorCompatibility($b32)
97
    {
98
        if ($this->enforceGoogleAuthenticatorCompatibility && ((strlen($b32) & (strlen($b32) - 1)) !== 0)) {
0 ignored issues
show
Bug introduced by
The property enforceGoogleAuthenticatorCompatibility does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
99
            throw new IncompatibleWithGoogleAuthenticatorException();
100
        }
101
    }
102
103
    /**
104
     * Check if all secret key characters are valid.
105
     *
106
     * @param $b32
107
     *
108
     * @throws InvalidCharactersException
109
     */
110
    protected function checkForValidCharacters($b32)
111
    {
112
        if (!preg_match('/^['.static::VALID_FOR_B32.']+$/', $b32, $match)) {
113
            throw new InvalidCharactersException();
114
        }
115
    }
116
}
117