Skip to content

Commit 1b7ddb3

Browse files
committed
✨ v5
1 parent 0556c5c commit 1b7ddb3

File tree

21 files changed

+101
-116
lines changed

21 files changed

+101
-116
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ jobs:
2222
fail-fast: true
2323
matrix:
2424
php-version:
25-
- "7.4"
26-
- "8.0"
27-
- "8.1"
2825
- "8.2"
2926
- "8.3"
3027

@@ -63,9 +60,6 @@ jobs:
6360
- ubuntu-latest
6461
- windows-latest
6562
php-version:
66-
- "7.4"
67-
- "8.0"
68-
- "8.1"
6963
- "8.2"
7064
- "8.3"
7165

.phan/config.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// that functions removed in php 7.0 exist.
1616
// (See `backward_compatibility_checks` for additional options)
1717
'target_php_version' => null,
18-
'minimum_target_php_version' => '7.4',
18+
'minimum_target_php_version' => '8.2',
1919

2020
// A list of directories that should be parsed for class and
2121
// method information. After excluding the directories
@@ -53,6 +53,5 @@
5353
],
5454
'suppress_issue_types' => [
5555
'PhanAccessMethodInternal',
56-
'PhanDeprecatedFunction',
5756
],
5857
];

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ A generator for counter based ([RFC 4226](https://tools.ietf.org/html/rfc4226))
1818

1919
# Documentation
2020
## Requirements
21-
- PHP 7.4+
21+
- PHP 8.2+
2222
- [`ext-curl`](https://www.php.net/manual/book.curl) for Battle.net and Steam Guard server time synchronization
2323
- [`ext-gmp`](https://www.php.net/manual/book.gmp) for Battle.net authenticator secret retrieval (RSA encryption)
2424
- [`ext-sodium`](https://www.php.net/manual/book.sodium) for constant time implementations of base64 encode/decode and hex2bin/bin2hex
@@ -29,11 +29,11 @@ A generator for counter based ([RFC 4226](https://tools.ietf.org/html/rfc4226))
2929

3030
via terminal: `composer require chillerlan/php-authenticator`
3131

32-
*composer.json* (note: replace `dev-main` with a [version constraint](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints), e.g. `^4.1` - see [releases](https://github.com/chillerlan/php-authenticator/releases) for valid versions)
32+
*composer.json* (note: replace `dev-main` with a [version constraint](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints), e.g. `^5.0` - see [releases](https://github.com/chillerlan/php-authenticator/releases) for valid versions)
3333
```json
3434
{
3535
"require": {
36-
"php": "^7.4 || ^8.0",
36+
"php": "^8.2",
3737
"chillerlan/php-authenticator": "dev-main"
3838
}
3939
}

composer.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "chillerlan/php-authenticator",
3-
"description": "A generator for counter- and time based 2-factor authentication codes (Google Authenticator). PHP 7.4+",
3+
"description": "A generator for counter- and time based 2-factor authentication codes (Google Authenticator). PHP 8.2+",
44
"homepage": "https://github.com/chillerlan/php-authenticator",
55
"license": "MIT",
66
"type": "library",
@@ -21,8 +21,8 @@
2121
"minimum-stability": "stable",
2222
"prefer-stable": true,
2323
"require": {
24-
"php": "^7.4 || ^8.0",
25-
"chillerlan/php-settings-container": "^2.1.4 || ^3.0",
24+
"php": "^8.2",
25+
"chillerlan/php-settings-container": "^3.0",
2626
"paragonie/constant_time_encoding": "^2.6"
2727
},
2828
"require-dev": {
@@ -32,7 +32,7 @@
3232
"ext-sodium": "*",
3333
"phan/phan": "^5.4",
3434
"phpmd/phpmd": "^2.13",
35-
"phpunit/phpunit": "^9.6",
35+
"phpunit/phpunit": "^10.2",
3636
"squizlabs/php_codesniffer": "^3.7"
3737
},
3838
"suggest": {
@@ -50,7 +50,7 @@
5050
},
5151
"scripts": {
5252
"phpunit": "@php vendor/bin/phpunit",
53-
"phan": "@php vendor/bin/phan"
53+
"phan": "@php vendor/bin/phan --allow-polyfill-parser"
5454
},
5555
"config": {
5656
"lock": false,

phpunit.xml.dist

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3-
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd"
44
bootstrap="vendor/autoload.php"
55
cacheResultFile=".build/phpunit.result.cache"
66
colors="true"
7-
verbose="true"
7+
beStrictAboutOutputDuringTests="true"
88
>
99
<testsuites>
1010
<testsuite name="php-authenticator test suite">
11-
<directory suffix=".php">./tests</directory>
11+
<directory suffix=".php">./tests/</directory>
12+
<exclude>tests/Authenticators/AuthenticatorInterfaceTestAbstract.php</exclude>
1213
</testsuite>
1314
</testsuites>
14-
<coverage processUncoveredFiles="true">
15-
<include>
16-
<directory suffix=".php">./src</directory>
17-
</include>
15+
<coverage>
1816
<report>
1917
<clover outputFile=".build/coverage/clover.xml"/>
2018
<xml outputDirectory=".build/coverage/coverage-xml"/>
2119
</report>
2220
</coverage>
21+
<logging>
22+
<junit outputFile=".build/logs/junit.xml"/>
23+
</logging>
24+
<source>
25+
<include>
26+
<directory>./src</directory>
27+
</include>
28+
</source>
2329
</phpunit>

src/Authenticator.php

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use chillerlan\Authenticator\Authenticators\AuthenticatorInterface;
1414
use chillerlan\Settings\SettingsContainerInterface;
1515
use InvalidArgumentException;
16+
use SensitiveParameter;
1617
use function http_build_query;
1718
use function rawurlencode;
1819
use function sprintf;
@@ -30,15 +31,14 @@
3031
*/
3132
class Authenticator{
3233

33-
/** @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\Authenticator\AuthenticatorOptions */
34-
protected SettingsContainerInterface $options;
35-
protected AuthenticatorInterface $authenticator;
36-
protected string $mode = AuthenticatorInterface::TOTP;
34+
protected SettingsContainerInterface|AuthenticatorOptions $options;
35+
protected AuthenticatorInterface $authenticator;
36+
protected string $mode = AuthenticatorInterface::TOTP;
3737

3838
/**
3939
* Authenticator constructor
4040
*/
41-
public function __construct(SettingsContainerInterface $options = null, string $secret = null){
41+
public function __construct(SettingsContainerInterface|AuthenticatorOptions $options = null, string $secret = null){
4242
// phpcs:ignore
4343
$this->setOptions($options ?? new AuthenticatorOptions);
4444

@@ -54,14 +54,13 @@ public function __construct(SettingsContainerInterface $options = null, string $
5454
* Please note that this will reset the secret phrase stored with the authenticator instance
5555
* if a different mode than the current is given.
5656
*/
57-
public function setOptions(SettingsContainerInterface $options):self{
57+
public function setOptions(SettingsContainerInterface|AuthenticatorOptions $options):self{
5858
$this->options = $options;
5959

6060
// invoke a new authenticator interface if necessary
6161
if(!isset($this->authenticator) || $this->options->mode !== $this->mode){
62-
$class = AuthenticatorInterface::MODES[$this->options->mode];
6362
$this->mode = $this->options->mode;
64-
$this->authenticator = new $class;
63+
$this->authenticator = new (AuthenticatorInterface::MODES[$this->options->mode])($this->options);
6564
}
6665

6766
$this->authenticator->setOptions($this->options);
@@ -74,7 +73,7 @@ public function setOptions(SettingsContainerInterface $options):self{
7473
*
7574
* @codeCoverageIgnore
7675
*/
77-
public function setSecret(string $encodedSecret):self{
76+
public function setSecret(#[SensitiveParameter] string $encodedSecret):self{
7877
$this->authenticator->setSecret($encodedSecret);
7978

8079
return $this;
@@ -120,7 +119,7 @@ public function code(int $data = null):string{
120119
*
121120
* @codeCoverageIgnore
122121
*/
123-
public function verify(string $otp, int $data = null):bool{
122+
public function verify(#[SensitiveParameter] string $otp, int $data = null):bool{
124123
return $this->authenticator->verify($otp, $data);
125124
}
126125

src/Authenticators/AuthenticatorAbstract.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use chillerlan\Settings\SettingsContainerInterface;
1616
use InvalidArgumentException;
1717
use RuntimeException;
18+
use SensitiveParameter;
1819
use function random_bytes;
1920
use function time;
2021
use function trim;
@@ -26,16 +27,15 @@ abstract class AuthenticatorAbstract implements AuthenticatorInterface{
2627

2728
protected const userAgent = 'chillerlanAuthenticator/5.0 +https://github.com/chillerlan/php-authenticator';
2829

29-
/** @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\Authenticator\AuthenticatorOptions */
30-
protected SettingsContainerInterface $options;
31-
protected ?string $secret = null;
32-
protected int $serverTime = 0;
33-
protected int $lastRequestTime = 0;
30+
protected SettingsContainerInterface|AuthenticatorOptions $options;
31+
protected ?string $secret = null;
32+
protected int $serverTime = 0;
33+
protected int $lastRequestTime = 0;
3434

3535
/**
3636
* AuthenticatorInterface constructor
3737
*/
38-
public function __construct(SettingsContainerInterface $options = null){
38+
public function __construct(SettingsContainerInterface|AuthenticatorOptions $options = null){
3939
// phpcs:ignore
4040
$this->setOptions($options ?? new AuthenticatorOptions);
4141
}
@@ -52,7 +52,7 @@ public function setOptions(SettingsContainerInterface $options):AuthenticatorInt
5252
/**
5353
* @inheritDoc
5454
*/
55-
public function setSecret(string $encodedSecret):AuthenticatorInterface{
55+
public function setSecret(#[SensitiveParameter] string $encodedSecret):AuthenticatorInterface{
5656
$this->secret = Base32::decode($this->checkEncodedSecret($encodedSecret));
5757

5858
return $this;

src/Authenticators/AuthenticatorInterface.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace chillerlan\Authenticator\Authenticators;
1212

1313
use chillerlan\Settings\SettingsContainerInterface;
14+
use SensitiveParameter;
1415

1516
/**
1617
*
@@ -49,7 +50,7 @@ public function setOptions(SettingsContainerInterface $options):AuthenticatorInt
4950
*
5051
* @throws \RuntimeException
5152
*/
52-
public function setSecret(string $encodedSecret):AuthenticatorInterface;
53+
public function setSecret(#[SensitiveParameter] string $encodedSecret):AuthenticatorInterface;
5354

5455
/**
5556
* Returns an encoded representation of the current secret phrase
@@ -89,14 +90,14 @@ public function getHMAC(int $counter):string;
8990
*
9091
* @internal
9192
*/
92-
public function getCode(string $hmac):int;
93+
public function getCode(#[SensitiveParameter] string $hmac):int;
9394

9495
/**
9596
* Formats the final output OTP from the given intermediate $code
9697
*
9798
* @internal
9899
*/
99-
public function getOTP(int $code):string;
100+
public function getOTP(#[SensitiveParameter] int $code):string;
100101

101102
/**
102103
* Creates a new OTP code with the given secret
@@ -114,6 +115,6 @@ public function code(int $data = null):string;
114115
* - a UNIX timestamp (TOTP)
115116
* - a counter value (HOTP)
116117
*/
117-
public function verify(string $otp, int $data = null):bool;
118+
public function verify(#[SensitiveParameter] string $otp, int $data = null):bool;
118119

119120
}

src/Authenticators/BattleNet.php

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use chillerlan\Authenticator\Common\Hex;
1616
use InvalidArgumentException;
1717
use RuntimeException;
18+
use SensitiveParameter;
1819
use function array_reverse;
1920
use function array_unshift;
2021
use function curl_close;
@@ -155,7 +156,7 @@ public function getHMAC(int $counter):string{
155156
/**
156157
* @inheritDoc
157158
*/
158-
public function getOTP(int $code):string{
159+
public function getOTP(#[SensitiveParameter] int $code):string{
159160
$code %= 100000000;
160161

161162
// length is fixed to 8 for Battle.net
@@ -182,7 +183,11 @@ public function getServerTime():int{
182183
* Retrieves the secret from Battle.net using the given serial and restore code.
183184
* If the public key for the serial is given (from a previous retrieval), it saves a server request.
184185
*/
185-
public function restoreSecret(string $serial, string $restore_code, string $public_key = null):array{
186+
public function restoreSecret(
187+
#[SensitiveParameter] string $serial,
188+
#[SensitiveParameter] string $restore_code,
189+
#[SensitiveParameter] string $public_key = null
190+
):array{
186191
$serial = $this->cleanSerial($serial);
187192
$region = $this->getRegion($serial);
188193

@@ -257,7 +262,7 @@ private function getRegion(string $serial):string{
257262
*
258263
* @throws \InvalidArgumentException
259264
*/
260-
private function cleanSerial(string $serial):string{
265+
private function cleanSerial(#[SensitiveParameter] string $serial):string{
261266
$serial = str_replace('-', '', strtoupper(trim($serial)));
262267

263268
if(!preg_match('/^[CNEUSKR]{2}\d{12}$/', $serial)){
@@ -270,7 +275,7 @@ private function cleanSerial(string $serial):string{
270275
/**
271276
*
272277
*/
273-
private function formatSerial(string $serial):string{
278+
private function formatSerial(#[SensitiveParameter] string $serial):string{
274279
$serial = $this->cleanSerial($serial);
275280
// split the numeric part into 3x 4 numbers
276281
$blocks = str_split(substr($serial, 2), 4);
@@ -318,7 +323,7 @@ private function request(string $endpoint, string $region, string $data = null):
318323
* Convert restore code char to byte but with appropriate mapping to exclude I,L,O and S.
319324
* e.g. A=10 but J=18 not 19 (as I is missing)
320325
*/
321-
private function convertRestoreCodeToByte(string $restore_code):string{
326+
private function convertRestoreCodeToByte(#[SensitiveParameter] string $restore_code):string{
322327
$chars = unpack('C*', $restore_code);
323328

324329
foreach($chars as &$c){
@@ -354,7 +359,7 @@ private function convertRestoreCodeToByte(string $restore_code):string{
354359
/**
355360
* Convert restore code byte to char but with appropriate mapping to exclude I,L,O and S.
356361
*/
357-
private function convertRestoreCodeToChar(string $data):string{
362+
private function convertRestoreCodeToChar(#[SensitiveParameter] string $data):string{
358363
$chars = unpack('C*', $data);
359364

360365
foreach($chars as &$c){
@@ -390,7 +395,7 @@ private function convertRestoreCodeToChar(string $data):string{
390395
/**
391396
*
392397
*/
393-
private function encrypt(string $data):string{
398+
private function encrypt(#[SensitiveParameter] string $data):string{
394399
$num = gmp_powm(gmp_import($data), self::rsa_exp_base10, self::rsa_mod_base10); // gmp_init(self::rsa_mod_base16, 16)
395400
$zero = gmp_init('0', 10);
396401
$ret = [];
@@ -406,7 +411,7 @@ private function encrypt(string $data):string{
406411
/**
407412
* @throws \RuntimeException
408413
*/
409-
private function decrypt(string $data, string $key):string{
414+
private function decrypt(#[SensitiveParameter] string $data, #[SensitiveParameter] string $key):string{
410415

411416
if(strlen($data) !== strlen($key)){
412417
throw new RuntimeException('The decryption key size and data size doesn\'t match');

src/Authenticators/HOTP.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace chillerlan\Authenticator\Authenticators;
1212

1313
use RuntimeException;
14+
use SensitiveParameter;
1415
use function hash_equals;
1516
use function hash_hmac;
1617
use function pack;
@@ -51,7 +52,7 @@ public function getHMAC(int $counter):string{
5152
/**
5253
* @inheritDoc
5354
*/
54-
public function getCode(string $hmac):int{
55+
public function getCode(#[SensitiveParameter] string $hmac):int{
5556
$data = unpack('C*', $hmac);
5657
$b = ($data[strlen($hmac)] & 0xF);
5758
// phpcs:ignore
@@ -61,7 +62,7 @@ public function getCode(string $hmac):int{
6162
/**
6263
* @inheritDoc
6364
*/
64-
public function getOTP(int $code):string{
65+
public function getOTP(#[SensitiveParameter] int $code):string{
6566
$code %= (10 ** $this->options->digits);
6667

6768
return str_pad((string)$code, $this->options->digits, '0', STR_PAD_LEFT);
@@ -79,7 +80,7 @@ public function code(int $data = null):string{
7980
/**
8081
* @inheritDoc
8182
*/
82-
public function verify(string $otp, int $data = null):bool{
83+
public function verify(#[SensitiveParameter] string $otp, int $data = null):bool{
8384
return hash_equals($this->code($data), $otp);
8485
}
8586

0 commit comments

Comments
 (0)