6
6
7
7
use function array_key_exists ;
8
8
use CBOR \Decoder ;
9
- use CBOR \MapObject ;
10
9
use CBOR \Normalizable ;
11
10
use function is_array ;
12
- use function ord ;
13
11
use Psr \EventDispatcher \EventDispatcherInterface ;
14
12
use Psr \Log \LoggerInterface ;
15
13
use Psr \Log \NullLogger ;
16
- use Symfony \Component \Uid \Uuid ;
17
14
use Throwable ;
18
- use function unpack ;
19
- use Webauthn \AttestedCredentialData ;
20
- use Webauthn \AuthenticationExtensions \AuthenticationExtensionsClientOutputsLoader ;
21
- use Webauthn \AuthenticatorData ;
15
+ use Webauthn \AuthenticatorDataLoader ;
22
16
use Webauthn \Event \AttestationObjectLoaded ;
23
17
use Webauthn \Exception \InvalidDataException ;
24
18
use Webauthn \MetadataService \CanLogData ;
29
23
30
24
class AttestationObjectLoader implements CanDispatchEvents, CanLogData
31
25
{
32
- private const FLAG_AT = 0b01000000 ;
33
-
34
- private const FLAG_ED = 0b10000000 ;
35
-
36
- private readonly Decoder $ decoder ;
37
-
38
26
private LoggerInterface $ logger ;
39
27
40
28
private EventDispatcherInterface $ dispatcher ;
41
29
42
30
public function __construct (
43
31
private readonly AttestationStatementSupportManager $ attestationStatementSupportManager
44
32
) {
45
- $ this ->decoder = Decoder::create ();
46
33
$ this ->logger = new NullLogger ();
47
34
$ this ->dispatcher = new NullEventDispatcher ();
48
35
}
@@ -65,7 +52,7 @@ public function load(string $data): AttestationObject
65
52
]);
66
53
$ decodedData = Base64::decode ($ data );
67
54
$ stream = new StringStream ($ decodedData );
68
- $ parsed = $ this -> decoder ->decode ($ stream );
55
+ $ parsed = Decoder:: create () ->decode ($ stream );
69
56
70
57
$ this ->logger ->info ('Loading the Attestation Statement ' );
71
58
$ parsed instanceof Normalizable || throw InvalidDataException::create (
@@ -94,69 +81,17 @@ public function load(string $data): AttestationObject
94
81
$ attestationObject ,
95
82
'Invalid attestation object '
96
83
);
97
- $ authData = $ attestationObject ['authData ' ];
98
84
99
85
$ attestationStatementSupport = $ this ->attestationStatementSupportManager ->get ($ attestationObject ['fmt ' ]);
100
86
$ attestationStatement = $ attestationStatementSupport ->load ($ attestationObject );
101
87
$ this ->logger ->info ('Attestation Statement loaded ' );
102
88
$ this ->logger ->debug ('Attestation Statement loaded ' , [
103
89
'attestationStatement ' => $ attestationStatement ,
104
90
]);
91
+ $ authData = $ attestationObject ['authData ' ];
92
+ $ authDataLoader = AuthenticatorDataLoader::create ();
93
+ $ authenticatorData = $ authDataLoader ->load ($ authData );
105
94
106
- $ authDataStream = new StringStream ($ authData );
107
- $ rp_id_hash = $ authDataStream ->read (32 );
108
- $ flags = $ authDataStream ->read (1 );
109
- $ signCount = $ authDataStream ->read (4 );
110
- $ signCount = unpack ('N ' , $ signCount );
111
- $ this ->logger ->debug (sprintf ('Signature counter: %d ' , $ signCount [1 ]));
112
-
113
- $ attestedCredentialData = null ;
114
- if (0 !== (ord ($ flags ) & self ::FLAG_AT )) {
115
- $ this ->logger ->info ('Attested Credential Data is present ' );
116
- $ aaguid = Uuid::fromBinary ($ authDataStream ->read (16 ));
117
- $ credentialLength = $ authDataStream ->read (2 );
118
- $ credentialLength = unpack ('n ' , $ credentialLength );
119
- $ credentialId = $ authDataStream ->read ($ credentialLength [1 ]);
120
- $ credentialPublicKey = $ this ->decoder ->decode ($ authDataStream );
121
- $ credentialPublicKey instanceof MapObject || throw InvalidDataException::create (
122
- $ credentialPublicKey ,
123
- 'The data does not contain a valid credential public key. '
124
- );
125
- $ attestedCredentialData = new AttestedCredentialData (
126
- $ aaguid ,
127
- $ credentialId ,
128
- (string ) $ credentialPublicKey
129
- );
130
- $ this ->logger ->info ('Attested Credential Data loaded ' );
131
- $ this ->logger ->debug ('Attested Credential Data loaded ' , [
132
- 'at ' => $ attestedCredentialData ,
133
- ]);
134
- }
135
-
136
- $ extension = null ;
137
- if (0 !== (ord ($ flags ) & self ::FLAG_ED )) {
138
- $ this ->logger ->info ('Extension Data loaded ' );
139
- $ extension = $ this ->decoder ->decode ($ authDataStream );
140
- $ extension = AuthenticationExtensionsClientOutputsLoader::load ($ extension );
141
- $ this ->logger ->info ('Extension Data loaded ' );
142
- $ this ->logger ->debug ('Extension Data loaded ' , [
143
- 'ed ' => $ extension ,
144
- ]);
145
- }
146
- $ authDataStream ->isEOF () || throw InvalidDataException::create (
147
- null ,
148
- 'Invalid authentication data. Presence of extra bytes. '
149
- );
150
- $ authDataStream ->close ();
151
-
152
- $ authenticatorData = new AuthenticatorData (
153
- $ authData ,
154
- $ rp_id_hash ,
155
- $ flags ,
156
- $ signCount [1 ],
157
- $ attestedCredentialData ,
158
- $ extension
159
- );
160
95
$ attestationObject = new AttestationObject ($ data , $ attestationStatement , $ authenticatorData );
161
96
$ this ->logger ->info ('Attestation Object loaded ' );
162
97
$ this ->logger ->debug ('Attestation Object ' , [
0 commit comments