Skip to content

Commit 2051744

Browse files
authored
ECC support for TPM Attn (#250)
ECC support for TPM Attn
1 parent 95f74fa commit 2051744

6 files changed

+271
-4
lines changed

src/webauthn/src/AttestationStatement/TPMAttestationStatementSupport.php

+20-4
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,7 @@ private function checkPubArea(string $data): array
213213

214214
$parameters = $this->getParameters($type, $pubArea);
215215

216-
$uniqueLength = unpack('n', $pubArea->read(2))[1];
217-
$unique = $pubArea->read($uniqueLength);
216+
$unique = $this->getUnique($type, $pubArea);
218217
Assertion::true($pubArea->isEOF(), 'Invalid public area. Presence of extra bytes.');
219218
$pubArea->close();
220219

@@ -234,13 +233,13 @@ private function checkPubArea(string $data): array
234233
private function getParameters(string $type, StringStream $stream): array
235234
{
236235
return match (bin2hex($type)) {
237-
'0001', '0014', '0016' => [
236+
'0001' => [
238237
'symmetric' => $stream->read(2),
239238
'scheme' => $stream->read(2),
240239
'keyBits' => unpack('n', $stream->read(2))[1],
241240
'exponent' => $this->getExponent($stream->read(4)),
242241
],
243-
'0018' => [
242+
'0023' => [
244243
'symmetric' => $stream->read(2),
245244
'scheme' => $stream->read(2),
246245
'curveId' => $stream->read(2),
@@ -250,6 +249,23 @@ private function getParameters(string $type, StringStream $stream): array
250249
};
251250
}
252251

252+
private function getUnique(string $type, StringStream $stream): string
253+
{
254+
switch (bin2hex($type)) {
255+
case '0001':
256+
$uniqueLength = unpack('n', $stream->read(2))[1];
257+
return $stream->read($uniqueLength);
258+
case '0023':
259+
$xLen = unpack('n', $stream->read(2))[1];
260+
$x = $stream->read($xLen);
261+
$yLen = unpack('n', $stream->read(2))[1];
262+
$y = $stream->read($yLen);
263+
return "\04" . $x . $y;
264+
default:
265+
throw new InvalidArgumentException('Unsupported type');
266+
}
267+
}
268+
253269
private function getExponent(string $exponent): string
254270
{
255271
return bin2hex($exponent) === '00000000' ? Base64::decodeUrlSafe('AQAB') : $exponent;

src/webauthn/src/AuthenticatorAttestationResponseValidator.php

+2
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ public function check(
177177
$this->checkMetadataStatement($publicKeyCredentialCreationOptions, $attestationObject);
178178
$fmt = $attestationObject->getAttStmt()
179179
->getFmt();
180+
180181
Assertion::true(
181182
$this->attestationStatementSupportManager->has($fmt),
182183
'Unsupported attestation statement format.'
@@ -270,6 +271,7 @@ private function checkMetadataStatement(
270271

271272
return;
272273
}
274+
273275
$this->logger->debug('Anonymization required. AAGUID and Attestation Statement changed.', [
274276
'aaguid' => $aaguid,
275277
'AttestationStatement' => $attestationStatement,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Webauthn\Tests\Unit\AttestationStatement;
6+
7+
use Http\Mock\Client;
8+
use Nyholm\Psr7\Factory\Psr17Factory;
9+
use Nyholm\Psr7\ServerRequest;
10+
use PHPUnit\Framework\TestCase;
11+
use Webauthn\AttestationStatement\AttestationObjectLoader;
12+
use Webauthn\AttestationStatement\AttestationStatementSupportManager;
13+
use Webauthn\AttestationStatement\NoneAttestationStatementSupport;
14+
use Webauthn\AttestationStatement\TPMAttestationStatementSupport;
15+
use Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler;
16+
use Webauthn\AuthenticatorAttestationResponseValidator;
17+
use Webauthn\MetadataService\CertificateChain\PhpCertificateChainValidator;
18+
use Webauthn\PublicKeyCredentialCreationOptions;
19+
use Webauthn\PublicKeyCredentialDescriptor;
20+
use Webauthn\PublicKeyCredentialLoader;
21+
use Webauthn\PublicKeyCredentialParameters;
22+
use Webauthn\PublicKeyCredentialRpEntity;
23+
use Webauthn\PublicKeyCredentialUserEntity;
24+
use Webauthn\Tests\Unit\DummyMetadataStatementRepository;
25+
use Webauthn\Tests\Unit\DummyPublicKeyCredentialSourceRepository;
26+
use Webauthn\TokenBinding\IgnoreTokenBindingHandler;
27+
28+
/**
29+
* @internal
30+
*/
31+
final class TPMAttestationStatementSupportTest extends TestCase
32+
{
33+
/**
34+
* @test
35+
*/
36+
public function theAttestationStatementIsAValidECC(): void
37+
{
38+
//Given
39+
$metadataStatementRepository = new DummyMetadataStatementRepository();
40+
$pkSourceRepository = new DummyPublicKeyCredentialSourceRepository();
41+
$attnManager = AttestationStatementSupportManager::create();
42+
$attnManager->add(TPMAttestationStatementSupport::create());
43+
$attnManager->add(NoneAttestationStatementSupport::create());
44+
$attnLoader = AttestationObjectLoader::create($attnManager);
45+
$pkLoader = PublicKeyCredentialLoader::create($attnLoader);
46+
$data = '{"id":"BoLAd0jIDI0ztrH1N45XQ_0w_N5ndt3hpNixQi3J2No", "rawId":"BoLAd0jIDI0ztrH1N45XQ_0w_N5ndt3hpNixQi3J2No", "response":{"attestationObject":"o2NmbXRjdHBtZ2F0dFN0bXSmY2FsZzn__mNzaWdZAQAzaz3HmrpCUlkEV2iv-TF2_y0MD7MVc0rLyuD_Ah3X9vx3G21WgeI89PyyvEYw3yEUUdO7sn6YxubMfuePpuSawYKAeSbw3O4LkMDC2fqZmlLyTfoC8L1_8vExv6mWPN7H5U6E_K7IZ38H3mO736ie-mDyoXxalj4WkA9zjKXJM5t7GhHQAqtDaX4HmM47pFH25atgQnoLdB0MTzh6jgYjIiDrMSOqhrQYskiaX_LFfKTiWfviwMOYcMA8FkRPc05LKvPTxp-bx_ghHrd_gIAUA3MjfElVYCVfveMnI61ZwARnf0cTrFp7vfga85YeAXaLOu29JifjodW6DsjL_dnXY3ZlcmMyLjBjeDVjglkFtTCCBbEwggOZoAMCAQICEAaSyUKea0mgpfZbwvZ7byMwDQYJKoZIhvcNAQELBQAwQTE_MD0GA1UEAxM2RVVTLU5UQy1LRVlJRC0yM0Y0RTIyQUQzQkUzNzRBNDQ5NzcyOTU0QUEyODNBRUQ3NTI1NzJFMB4XDTIxMTEyNTIxMzA1NFoXDTI3MDYwMzE3NTE0N1owADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANwiGFmQdIOYto4qGegANWT-LdSr5T5_tj7E_aKtLSNP8bqc6eP11VvCi9ZFnbjiFxi1NdY2GAbUDb3zr1PnZpOcwvn1gh704PLtkZYFkwvFRvm5bIvtsuqYgn71MCup1GCTeJ3EcylidbVpmwX5s9XK5vyRsMpQ1TxPwxPq32toIBcQ3pgZyb9Ic_m1IfWE_hC_XlwZzqfFnFL7XszCGwJmziFjML9VeBrdv0dkrDWMv1sNI1PDDm_JQ8iZwZ83At3qsgnmwN4zudOMUPRMJBNeiVBj9GjW7tV9tSG2Oa_F_JUo0b1Gr_y08PSMhAckj6ZaR8_EBppoty9CbTm65nsCAwEAAaOCAeQwggHgMA4GA1UdDwEB_wQEAwIHgDAMBgNVHRMBAf8EAjAAMG0GA1UdIAEB_wRjMGEwXwYJKwYBBAGCNxUfMFIwUAYIKwYBBQUHAgIwRB5CAFQAQwBQAEEAIAAgAFQAcgB1AHMAdABlAGQAIAAgAFAAbABhAHQAZgBvAHIAbQAgACAASQBkAGUAbgB0AGkAdAB5MBAGA1UdJQQJMAcGBWeBBQgDMEoGA1UdEQEB_wRAMD6kPDA6MTgwDgYFZ4EFAgMMBWlkOjcyMBAGBWeBBQICDAdOUENUNzV4MBQGBWeBBQIBDAtpZDo0RTU0NDMwMDAfBgNVHSMEGDAWgBTTjd-fy_wwa14b1TQrBpJk2U7fpTAdBgNVHQ4EFgQUeq9wlX_04m4THgx-yMSO7QwViv8wgbIGCCsGAQUFBwEBBIGlMIGiMIGfBggrBgEFBQcwAoaBkmh0dHA6Ly9hemNzcHJvZGV1c2Fpa3B1Ymxpc2guYmxvYi5jb3JlLndpbmRvd3MubmV0L2V1cy1udGMta2V5aWQtMjNmNGUyMmFkM2JlMzc0YTQ0OTc3Mjk1NGFhMjgzYWVkNzUyNTcyZS8xMzY0YTJkMy1hZTU0LTQ3YjktODdmMy0zMjA1NDE5NDc0MGUuY2VyMA0GCSqGSIb3DQEBCwUAA4ICAQCiPgQwqysYPQpMiRDpxbsx24d1xVX_kiUwwcQJE3mSYvwe4tnaQSHjlfB3OkpDMjotxFl33oUMxxScjSrgp_1o6rdkiO6QvPMgsqDMX4w-dmWn00akwNbMasTxg39Ceqtocw4i-R9AlNwndpe3QUIt8xkQ5dhlcIF8lc1dXmgz4mkMAtOi3VgaNvHTsRF9pLbTczJss608X8b4gHqM4t7lfIcRB8DvSyfXc7T3k21-4_3jvAb2HRoCCAyv8_XXn1UwkWTrXMLUSiE1p5Sl8ba8I_86Hsemsc0aflwRZrrY2pC3aaA3QbbfAyskiaFPw-ZibY9p0_QVq1XhAKa-dDd70mWvTGKQdrqfZI_SC5zccvDAm6aefAfnYBY2fV92ZFriihA2ULcJaESz3X3JkiK4eO1k0T2uf9-rL4lUEADibwpnsZOBeNWBsztvXDmcZGR_MSoRIQygKMw2U7AproqBPDRDFwhS5yc9UHvD6dMZ3PLx4i_eo-BLr-QJ2HARoyK8KuV0xLEq3XyjWdfZDbAueUVgtic14wK9jiSbhycRT2WV3-QU8KPm5_QCt_eBPwY81a-q84jm2ue_ok8-LYrmWpvihqRhFhK9MLVS96QaHeeuDehYNDWsSIVCr9jB-lchueZ-kZqwyl_4pPMrM7wLXBOR-bV5_pAPv3u_RvQmhVkG7zCCBuswggTToAMCAQICEzMAAAQHrjuoB9SvW8wAAAAABAcwDQYJKoZIhvcNAQELBQAwgYwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xNjA0BgNVBAMTLU1pY3Jvc29mdCBUUE0gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxNDAeFw0yMTA2MDMxNzUxNDdaFw0yNzA2MDMxNzUxNDdaMEExPzA9BgNVBAMTNkVVUy1OVEMtS0VZSUQtMjNGNEUyMkFEM0JFMzc0QTQ0OTc3Mjk1NEFBMjgzQUVENzUyNTcyRTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMkPU9X8JhPBwDxmFm84D31b8xN5NQz0XR8Nji_-Z8v3WtC4lSdEwJUwqvZkj5OQ3wPA_6haONcCHzqTZhyz1aheOPhXmEeWFWjEiJFj07crEZb9wM4rM1fdcf3vCQNSSDlogC5AM-tITx31hm0YffIrzM3n70fNBBfvlw8t-yhZVOavj7l29gKsyvkR0IadruvLVWWVeH9rueHVrOwlU4wUJpjD41d4U87M3FgUGK2YacQxT0BPHzaOCTE9YhylG5fA_eCF7Q1SxAe347uIaS6I3GhAootzJy9XYeFp_uhc1Yp2hMh5wdeRkm15WKb7tE9T4vwHp0VCQEkUQn1ClN_s7PpfKNFp-DB9ez0Fh7tqag6AssrKE6LgOjfWDWUcgzgIiFLvv9Gx797IZj8LDazK1iGSqI2D8zmmxnGG47MevfY8q2udJW1G4nOcjw49x6XZHmnT3VpVKcTDbI9bEsyc2R9vngftF9FgnEVdyt-QRqE0UqEXJmjLhcxBMeyFZJd_bEAutSBpWugPk10IPFRkXppsuHMZFHJVP96IWwVmm6Q4mX018K996XDubAGblbhvPzJ9NFL_e7xM2ev3rAalz2CzSLYs48EXym7dqGTnP7F9DaF2O0IHT0GQ951wFVoGmA-IYsTMVsdlhVaImCuHgahu1W94H6BvtDkGGku7AgMBAAGjggGOMIIBijAOBgNVHQ8BAf8EBAMCAoQwGwYDVR0lBBQwEgYJKwYBBAGCNxUkBgVngQUIAzAWBgNVHSAEDzANMAsGCSsGAQQBgjcVHzASBgNVHRMBAf8ECDAGAQH_AgEAMB0GA1UdDgQWBBTTjd-fy_wwa14b1TQrBpJk2U7fpTAfBgNVHSMEGDAWgBR6jArOL0hiF-KU0a5VwVLscXSkVjBwBgNVHR8EaTBnMGWgY6Bhhl9odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBUUE0lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDE0LmNybDB9BggrBgEFBQcBAQRxMG8wbQYIKwYBBQUHMAKGYWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVFBNJTIwUm9vdCUyMENlcnRpZmljYXRlJTIwQXV0aG9yaXR5JTIwMjAxNC5jcnQwDQYJKoZIhvcNAQELBQADggIBAIQJqhFB71eZzZMq0w866QXDKlHcGyIa_IkTK4p5ejIdIA7FJ8neeVToAKUt9ULEb1Od2ir1y5Qx5Zp_edf4F8aikn-yw61hNB3FQ4iSV49eqEMe2Fx6OMBmHRWGtUjAlf5g_N2Qc6rHela2d69nQbpSF3Nq7AESguXxnoqZ-4CGUW0jC_b93sTd5fESHs_iwFX-zWKCwCXerqCuI3PqYWOlbCnftYhsI1CD638wJxw4YFXdSmOrF8dDnd6tlH_0qCZrBX-k4N-8QgK1-BDYIxmvUBnpLFDDitB2dP6YIglY0VcjkPd3BDmodHknG4GQeAvJKHpqF91Y3K1rOWvn4JqzHFvL3JgXgL7LbC_h9EF50HeHayPCToTS8Pmg_4dfUaCwNlxPvu9GvjrDKDNNEV5T73iWMV_GQbVsx6JULAljCthYLo-55mONDcr1x7kakXlQT-yIdIQ57Ix8eHz_qkJkvWxbw8vOgrXhkLK0jGAvW_YSkTV7G9_TYDJ--8IjPPHC1bexKq72-L7KetwH6LbWHGeYkJnaZ1zqeN4USxyJn8K4uhwnjSeK2sZ942zn5EnZnjd85yfdkPLcQY8xtYiWNjc_PprTrjhLyMO71VdMkTDiTTtDha37qywNISPV7vBv8YDiDjX8ElsWbTHTC0XgBp0h-RkjaRKI5C4eTUebZ3B1YkFyZWFYdgAjAAsABAByACCd_8vzbDg65pn7mGjcbcuJ1xU4hL4oA5IsEkFYv60irgAQABAAAwAQACCweOEk52r8mnJ6y9bsGcM3V4dL1LWt8I67Jjx5mcrFuAAgjwd_jaCEEOAJLV97kX3VgbxzopPYMC4NqEFjD0m55PpoY2VydEluZm9Yof9UQ0eAFwAiAAvgBLotxyAAbygBG4efe84V0SVYnO6xLrYaC1oyLgTt3QAUjcjAdORvuzxCfLBU7KNxPFSPE84AAAAUHn9jxccO2yRJARoXARNN0IPNWxnEACIACxfcHNQuRgb_05OKyBrS_1kY5IYxOl67gTlqkHd4g6slACIAC7tcXSHNTw8ANLeZd3PKooKsgrMIlGD47aunn05BcquwaGF1dGhEYXRhWKRqubvw35oW-R27M7uxMvr50Xx4LEgmxuxw7O5Y2X71KkUAAAAACJhwWMrcS4G24TDeUNy-lgAgBoLAd0jIDI0ztrH1N45XQ_0w_N5ndt3hpNixQi3J2NqlAQIDJiABIVggsHjhJOdq_JpyesvW7BnDN1eHS9S1rfCOuyY8eZnKxbgiWCCPB3-NoIQQ4AktX3uRfdWBvHOik9gwLg2oQWMPSbnk-g", "clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiRTJZZWJNbUc5OTkyWGlhbHBGTDFsa1BwdE9JQlBlS3NwaE5rdDFKY2JLayIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uZmlyc3R5ZWFyLmlkLmF1IiwiY3Jvc3NPcmlnaW4iOmZhbHNlLCJvdGhlcl9rZXlzX2Nhbl9iZV9hZGRlZF9oZXJlIjoiZG8gbm90IGNvbXBhcmUgY2xpZW50RGF0YUpTT04gYWdhaW5zdCBhIHRlbXBsYXRlLiBTZWUgaHR0cHM6Ly9nb28uZ2wveWFiUGV4In0"}, "type":"public-key", "extensions":{"appid":null, "cred_blob":null, "cred_props":{"rk":true}}}';
47+
48+
$options = PublicKeyCredentialCreationOptions::create(
49+
PublicKeyCredentialRpEntity::create('https://webauthn.firstyear.id.au'),
50+
PublicKeyCredentialUserEntity::create('j.d', '0123456789', 'John Doe'),
51+
base64_decode('E2YebMmG9992XialpFL1lkPptOIBPeKsphNkt1JcbKk', true),
52+
[PublicKeyCredentialParameters::create(PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, 0)]
53+
)
54+
->setAttestation(PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT);
55+
$validator = AuthenticatorAttestationResponseValidator::create(
56+
$attnManager,
57+
$pkSourceRepository,
58+
IgnoreTokenBindingHandler::create(),
59+
ExtensionOutputCheckerHandler::create()
60+
)->enableMetadataStatementSupport(
61+
$metadataStatementRepository,
62+
$metadataStatementRepository,
63+
new PhpCertificateChainValidator(new Client(), new Psr17Factory())
64+
);
65+
$request = new ServerRequest('POST', 'https://webauthn.firstyear.id.au');
66+
67+
//When
68+
$response = $pkLoader->load($data);
69+
$source = $validator->check($response->getResponse(), $options, $request);
70+
71+
//Then
72+
static::assertSame('08987058-cadc-4b81-b6e1-30de50dcbe96', $source->getAaguid()->toRfc4122());
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Webauthn\Tests\Unit;
6+
7+
use const JSON_THROW_ON_ERROR;
8+
use Webauthn\MetadataService\MetadataStatementRepository;
9+
use Webauthn\MetadataService\Service\MetadataBLOBPayloadEntry;
10+
use Webauthn\MetadataService\Statement\MetadataStatement;
11+
use Webauthn\MetadataService\StatusReportRepository;
12+
13+
/**
14+
* @internal
15+
*/
16+
final class DummyMetadataStatementRepository implements MetadataStatementRepository, StatusReportRepository
17+
{
18+
public function findOneByAAGUID(string $aaguid): ?MetadataStatement
19+
{
20+
if ($aaguid !== '08987058-cadc-4b81-b6e1-30de50dcbe96') {
21+
return null;
22+
}
23+
24+
return $this->loadWindowsHelloMDS()
25+
->getMetadataStatement();
26+
}
27+
28+
public function findStatusReportsByAAGUID(string $aaguid): array
29+
{
30+
if ($aaguid !== '08987058-cadc-4b81-b6e1-30de50dcbe96') {
31+
return [];
32+
}
33+
34+
return $this->loadWindowsHelloMDS()
35+
->getStatusReports();
36+
}
37+
38+
private function loadWindowsHelloMDS(): MetadataBLOBPayloadEntry
39+
{
40+
$data = file_get_contents(__DIR__ . '/../../windows-hello.json');
41+
42+
return MetadataBLOBPayloadEntry::createFromArray(json_decode($data, true, 512, JSON_THROW_ON_ERROR));
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Webauthn\Tests\Unit;
6+
7+
use Webauthn\PublicKeyCredentialSource;
8+
use Webauthn\PublicKeyCredentialSourceRepository;
9+
use Webauthn\PublicKeyCredentialUserEntity;
10+
11+
/**
12+
* @internal
13+
*/
14+
final class DummyPublicKeyCredentialSourceRepository implements PublicKeyCredentialSourceRepository
15+
{
16+
public function findOneByCredentialId(string $publicKeyCredentialId): ?PublicKeyCredentialSource
17+
{
18+
return null;
19+
}
20+
21+
public function findAllForUserEntity(PublicKeyCredentialUserEntity $publicKeyCredentialUserEntity): array
22+
{
23+
return [];
24+
}
25+
26+
public function saveCredentialSource(PublicKeyCredentialSource $publicKeyCredentialSource): void
27+
{
28+
}
29+
}

tests/windows-hello.json

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
{
2+
"aaguid": "08987058-cadc-4b81-b6e1-30de50dcbe96",
3+
"metadataStatement": {
4+
"legalHeader": "https://fidoalliance.org/metadata/metadata-statement-legal-header/",
5+
"aaguid": "08987058-cadc-4b81-b6e1-30de50dcbe96",
6+
"description": "Windows Hello Hardware Authenticator",
7+
"authenticatorVersion": 1,
8+
"protocolFamily": "fido2",
9+
"schema": 3,
10+
"upv": [
11+
{
12+
"major": 1,
13+
"minor": 0
14+
}
15+
],
16+
"authenticationAlgorithms": [
17+
"rsassa_pkcsv15_sha256_raw"
18+
],
19+
"publicKeyAlgAndEncodings": [
20+
"cose"
21+
],
22+
"attestationTypes": [
23+
"attca"
24+
],
25+
"userVerificationDetails": [
26+
[
27+
{
28+
"userVerificationMethod": "eyeprint_internal"
29+
}
30+
],
31+
[
32+
{
33+
"userVerificationMethod": "passcode_internal"
34+
}
35+
],
36+
[
37+
{
38+
"userVerificationMethod": "fingerprint_internal"
39+
}
40+
],
41+
[
42+
{
43+
"userVerificationMethod": "faceprint_internal"
44+
}
45+
]
46+
],
47+
"keyProtection": [
48+
"hardware"
49+
],
50+
"isKeyRestricted": false,
51+
"matcherProtection": [
52+
"software"
53+
],
54+
"attachmentHint": [
55+
"internal"
56+
],
57+
"tcDisplay": [],
58+
"attestationRootCertificates": [
59+
"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"
60+
],
61+
"icon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAACkUlEQVR42uyai3GDMAyGQyegGzACnaCMkBHoBhkhnSAj0A2SDaAT0E6QbEA3cOXW6XEpBtnImMv9utOllxjF/qKHLTdRSm0gdnkAAgACIAACIAACIAACIAgAARAAARAAARAAARBEAFCSJINKkpLuSTtSZbQz76W25zhKkpFWPbtaz6Q75vPuoluuPmqxlZK2yi76s9RznjlpN2K7CrFWaUAHNS0HT0Atw3YpDSjxbdoPuaziG3uk579cvIdeWsbQD7L7NAYoWpKmLy8chueO5reB7KKKrQnQJdDYn9AJZHc5QBT7enINY2hjxrqItsvJWSdxFxKuYlOlWJmE6zPPcsJuN7WFiF7me5DOAws4OyZyG6TOsr/KQziDaJm/mcy2V1V0+T0JeXxqqlrWC9mGGy3O6wwFaI0SdR+EMg9AEAACIAByqViZb+/prgFdN6qb306j3lTWs0BJ76Qjw0ktO+3ad60PQhMrfM9YwqK7lUPe4j+/OR40cDaqJeJ+xo80JsWih1WTBAcb8ysKrb+TfowQKy3v55wbBkk49FJbQusqr4snadL9hEtXC3nO1G1HG6UfxIj5oDnJlHPOVVAerWGmvYQxwc70hiTh7Bidy3/3ZFE6isxf8epNhUCl4n5ftYqWKzMP3IIquaFnquXO0sZ1yn/RWq69SuK6GdPXORfSz4HPnk1bNXO0+UZze5HqKIodNYwnHVVcOUivNcStxj4CGFYhWAWgXgmuF4JzdMhn6wDUm1DpmFyVY7IvQqeTRdod2v2F8lNn/gcpW+rUsOi9mAmFwlSo3Pw9JQ3p+8bhgnAMkPM613BxOBQqc2FEB4SmPQSAAAiAAAiAAAiAAAiAIAAEQAAEQAAEQPco3wIMADOXgFhOTghuAAAAAElFTkSuQmCC",
62+
"authenticatorGetInfo": {
63+
"versions": [
64+
"FIDO_2_0"
65+
],
66+
"aaguid": "08987058cadc4b81b6e130de50dcbe96",
67+
"options": {
68+
"plat": true,
69+
"rk": true,
70+
"up": true
71+
},
72+
"maxCredentialCountInList": 100,
73+
"maxCredentialIdLength": 32,
74+
"transports": [
75+
"internal"
76+
],
77+
"algorithms": [
78+
{
79+
"type": "public-key",
80+
"alg": -257
81+
}
82+
],
83+
"minPINLength": 4,
84+
"firmwareVersion": 19042
85+
}
86+
},
87+
"statusReports": [
88+
{
89+
"status": "FIDO_CERTIFIED_L1",
90+
"effectiveDate": "2020-08-05",
91+
"certificationDescriptor": "Windows Hello Hardware Authenticator",
92+
"certificateNumber": "FIDO20020190418002",
93+
"certificationPolicyVersion": "1.3.6",
94+
"certificationRequirementsVersion": "1.1.0"
95+
},
96+
{
97+
"status": "FIDO_CERTIFIED",
98+
"effectiveDate": "2020-08-05"
99+
}
100+
],
101+
"timeOfLastStatusChange": "2020-08-05"
102+
}

0 commit comments

Comments
 (0)