-
Notifications
You must be signed in to change notification settings - Fork 0
/
TezosIdentifier.php
117 lines (99 loc) · 2.67 KB
/
TezosIdentifier.php
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
<?php
declare(strict_types = 1);
namespace App\Identifier;
use ArrayAccess;
use Authentication\Identifier\AbstractIdentifier;
use Authentication\Identifier\Resolver\ResolverAwareTrait;
use Bzzhh\Pezos\Keys\PubKey;
class TezosIdentifier extends AbstractIdentifier {
use ResolverAwareTrait;
/**
* @var string
*/
public const CREDENTIAL_PK = 'pk';
/**
* @var string
*/
public const CREDENTIAL_PKH = 'pkh';
/**
* @var string
*/
public const CREDENTIAL_MESSAGE = 'message';
/**
* @var string
*/
public const CREDENTIAL_SIGNATURE = 'signature';
/**
* Default configuration.
* - `fields` The fields to use to identify a user by:
* - `pk`: a public key
* - `pkh`: the matching public key hash
* - `message` the payload
* - `signature` the signed payload
* - `resolver` The resolver implementation to use.
*
* @var array<string, mixed>
*/
protected array $_defaultConfig = [
'fields' => [
self::CREDENTIAL_PK => 'pk',
self::CREDENTIAL_PKH => 'pkh',
self::CREDENTIAL_MESSAGE => 'message',
self::CREDENTIAL_SIGNATURE => 'signature',
],
'resolver' => 'Authentication.Orm',
];
/**
* @inheritDoc
*
* @param array<string, mixed> $credentials
*
* @return \ArrayAccess|array<string, mixed>|null
*/
public function identify(array $credentials): ArrayAccess|array|null {
if (!isset($credentials[static::CREDENTIAL_PKH])) {
return null;
}
$identity = $this->_findIdentity($credentials[static::CREDENTIAL_PKH]);
if (array_key_exists(static::CREDENTIAL_MESSAGE, $credentials)
&& array_key_exists(static::CREDENTIAL_SIGNATURE, $credentials)
) {
$pk = $credentials[static::CREDENTIAL_PK];
$message = $credentials[static::CREDENTIAL_MESSAGE];
$signature = $credentials[static::CREDENTIAL_SIGNATURE];
if (!$this->_checkSignature($pk, $message, $signature)) {
return null;
}
}
return $identity;
}
/**
* TODO: additional message verification?
* is the csrf enough to make sure nothing has been tampered?
*
* @param string $pk
* @param string $message
* @param string $signature
*
* @return bool
*/
protected function _checkSignature(string $pk, string $message, string $signature): bool {
$pubKey = PubKey::fromBase58($pk);
if (!$pubKey->verifySignature($signature, $message)
&& !$pubKey->verifySignature($signature, bin2hex($message))
) {
return false;
}
return true;
}
/**
* Find a user record using the username/identifier provided.
*
* @param string $identifier The username/identifier.
*
* @return \ArrayAccess|array<string, mixed>|null
*/
protected function _findIdentity(string $identifier) {
return $this->getResolver()->find(['address' => $identifier]);
}
}