示例#1
0
        public void MetadataTOCPayloadEntry_Can_Be_JSON_Roundtripped()
        {
            var input = new MetadataTOCPayloadEntry()
            {
                AaGuid                 = Guid.NewGuid().ToString(),
                MetadataStatement      = new MetadataStatement(),
                StatusReports          = Array.Empty <StatusReport>(),
                TimeOfLastStatusChange = DateTime.UtcNow.ToString("o")
            };

            input.MetadataStatement.AaGuid                  = Guid.NewGuid().ToString();
            input.MetadataStatement.Description             = "Test entry";
            input.MetadataStatement.AuthenticatorVersion    = 1;
            input.MetadataStatement.AssertionScheme         = "abc123";
            input.MetadataStatement.AuthenticationAlgorithm = 1;
            input.MetadataStatement.Upv = new UafVersion[] { new UafVersion
                                                             {
                                                                 Major = 1,
                                                                 Minor = 0,
                                                             } };
            input.MetadataStatement.AttestationTypes            = new ushort[] { 1 };
            input.MetadataStatement.UserVerificationDetails     = Array.Empty <VerificationMethodDescriptor[]>();
            input.MetadataStatement.AttestationRootCertificates = new string[] { "..." };

            var json = JsonConvert.SerializeObject(input);

            var output = JsonConvert.DeserializeObject <MetadataTOCPayloadEntry>(json);

            Assert.Equal(input.AaGuid, output.AaGuid);
        }
示例#2
0
        public async Task <MetadataStatement> GetMetadataStatement(MetadataTOCPayloadEntry entry)
        {
            if (_toc == null)
            {
                await GetToc();
            }

            if (!string.IsNullOrEmpty(entry.AaGuid) && Guid.TryParse(entry.AaGuid, out Guid parsedAaGuid))
            {
                if (_entries.ContainsKey(parsedAaGuid))
                {
                    return(_entries[parsedAaGuid].MetadataStatement);
                }
            }

            return(null);
        }
示例#3
0
        public async Task <MetadataStatement> GetMetadataStatement(MetadataTOCPayloadEntry entry)
        {
            var statementBase64Url = await DownloadStringAsync(entry.Url);

            var tocAlg = await GetTocAlg();

            var statementBytes  = Base64Url.Decode(statementBase64Url);
            var statementString = Encoding.UTF8.GetString(statementBytes, 0, statementBytes.Length);
            var statement       = JsonConvert.DeserializeObject <MetadataStatement>(statementString);

            using (HashAlgorithm hasher = CryptoUtils.GetHasher(new HashAlgorithmName(tocAlg)))
            {
                statement.Hash = Base64Url.Encode(hasher.ComputeHash(Encoding.UTF8.GetBytes(statementBase64Url)));
            }

            return(statement);
        }
示例#4
0
        public async Task <MetadataStatement> GetMetadataStatement(MetadataTOCPayloadEntry entry)
        {
            var statementBase64Url = await DownloadStringAsync(entry.Url + "/?token=" + _token);

            var tocAlg = await GetTocAlg();

            var statementBytes  = Base64Url.Decode(statementBase64Url);
            var statementString = Encoding.UTF8.GetString(statementBytes, 0, statementBytes.Length);
            var statement       = JsonConvert.DeserializeObject <MetadataStatement>(statementString);

            using (HashAlgorithm hasher = CryptoUtils.GetHasher(new HashAlgorithmName(tocAlg)))
            {
                statement.Hash = Base64Url.Encode(hasher.ComputeHash(Encoding.UTF8.GetBytes(statementBase64Url)));
            }

            if (!HashesAreEqual(entry.Hash, statement.Hash))
            {
                throw new VerificationException("TOC entry and statement hashes do not match");
            }

            return(statement);
        }
示例#5
0
        public Task <MetadataTOCPayload> GetToc()
        {
            if (Directory.Exists(_path))
            {
                foreach (var filename in Directory.GetFiles(_path))
                {
                    var rawStatement     = File.ReadAllText(filename);
                    var statement        = JsonConvert.DeserializeObject <MetadataStatement>(rawStatement);
                    var conformanceEntry = new MetadataTOCPayloadEntry
                    {
                        AaGuid            = statement.AaGuid,
                        MetadataStatement = statement,
                        StatusReports     = new StatusReport[]
                        {
                            new StatusReport
                            {
                                Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                            }
                        }
                    };
                    if (null != conformanceEntry.AaGuid)
                    {
                        _entries.Add(new Guid(conformanceEntry.AaGuid), conformanceEntry);
                    }
                }
            }

            _toc = new MetadataTOCPayload()
            {
                Entries     = _entries.Select(o => o.Value).ToArray(),
                NextUpdate  = "", //Empty means it won't get cached
                LegalHeader = "Local FAKE",
                Number      = 1
            };

            return(Task.FromResult(_toc));
        }
        public async Task <MetadataTOCPayload> GetToc()
        {
            var yubico = new MetadataTOCPayloadEntry
            {
                AaGuid        = "f8a011f3-8c0a-4d15-8006-17111f9edc7d",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport()
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Yubico YubiKey FIDO2",
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };

            _entries.Add(new Guid(yubico.AaGuid), yubico);

            // YubiKey 5 USB and NFC AAGUID values from https://support.yubico.com/support/solutions/articles/15000014219-yubikey-5-series-technical-manual#AAGUID_Valuesxf002do
            var yubikey5usb = new MetadataTOCPayloadEntry
            {
                AaGuid        = "cb69481e-8ff7-4039-93ec-0a2729a154a8",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Yubico YubiKey 5 USB",
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };

            _entries.Add(new Guid(yubikey5usb.AaGuid), yubikey5usb);

            var yubikey5nfc = new MetadataTOCPayloadEntry
            {
                AaGuid        = "fa2b99dc-9e39-4257-8f92-4a30d23c4118",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Yubico YubiKey 5 NFC",
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };

            _entries.Add(new Guid(yubikey5nfc.AaGuid), yubikey5nfc);

            var yubicoSecuriyKeyNfc = new MetadataTOCPayloadEntry
            {
                AaGuid        = "6d44ba9b-f6ec-2e49-b930-0c8fe920cb73",
                Hash          = "",
                StatusReports = new StatusReport[] { new StatusReport()
                                                     {
                                                         Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                                                     } },
                MetadataStatement = new MetadataStatement
                {
                    Description                 = "Yubico Security Key NFC",
                    Icon                        = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIzLjAuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9Ill1YmljbyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiCgkgdmlld0JveD0iMCAwIDc2OCA3NjgiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDc2OCA3Njg7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojOUFDQTNDO30KPC9zdHlsZT4KPHBvbHlnb24gaWQ9IlkiIGNsYXNzPSJzdDAiIHBvaW50cz0iMjE4LjQzLDIxMS44MSAzMTYuNDksMjExLjgxIDM4Ni41Miw0MDAuMDcgNDUzLjIsMjExLjgxIDU0OS41NywyMTEuODEgMzg3LjA4LDYxMS44NiAKCTI4Ni4yMyw2MTEuODYgMzMyLjE3LDUwMi4wNCAiLz4KPHBhdGggaWQ9IkNpcmNsZV8xXyIgY2xhc3M9InN0MCIgZD0iTTM4NCwwQzE3MS45MiwwLDAsMTcxLjkyLDAsMzg0czE3MS45MiwzODQsMzg0LDM4NHMzODQtMTcxLjkyLDM4NC0zODRTNTk2LjA4LDAsMzg0LDB6CgkgTTM4NCw2OTMuNThDMjEzLjAyLDY5My41OCw3NC40Miw1NTQuOTgsNzQuNDIsMzg0UzIxMy4wMiw3NC40MiwzODQsNzQuNDJTNjkzLjU4LDIxMy4wMiw2OTMuNTgsMzg0UzU1NC45OCw2OTMuNTgsMzg0LDY5My41OHoiLz4KPC9zdmc+Cg==",
                    AttachmentHint              = 6,
                    AttestationTypes            = new ushort[] { (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL },
                    Hash                        = "",
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };

            _entries.Add(new Guid(yubicoSecuriyKeyNfc.AaGuid), yubicoSecuriyKeyNfc);

            var msftWhfbSoftware = new MetadataTOCPayloadEntry
            {
                AaGuid        = "6028B017-B1D4-4C02-B4B3-AFCDAFC96BB2",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Windows Hello software authenticator"
                }
            };

            _entries.Add(new Guid(msftWhfbSoftware.AaGuid), msftWhfbSoftware);
            var msftWhfbSoftwareVbs = new MetadataTOCPayloadEntry
            {
                AaGuid        = "6E96969E-A5CF-4AAD-9B56-305FE6C82795",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Windows Hello VBS software authenticator"
                }
            };

            _entries.Add(new Guid(msftWhfbSoftwareVbs.AaGuid), msftWhfbSoftwareVbs);
            var msftWhfbHardware = new MetadataTOCPayloadEntry
            {
                AaGuid        = "08987058-CADC-4B81-B6E1-30DE50DCBE96",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Windows Hello hardware authenticator"
                }
            };

            _entries.Add(new Guid(msftWhfbHardware.AaGuid), msftWhfbHardware);
            var msftWhfbHardwareVbs = new MetadataTOCPayloadEntry
            {
                AaGuid        = "9DDD1817-AF5A-4672-A2B9-3E3DD95000A9",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Windows Hello VBS hardware authenticator"
                }
            };

            _entries.Add(new Guid(msftWhfbHardwareVbs.AaGuid), msftWhfbHardwareVbs);

            var solostatement = await DownloadStringAsync("https://raw.githubusercontent.com/solokeys/solo/master/metadata/Solo-FIDO2-CTAP2-Authenticator.json");

            var soloMetadataStatement = JsonConvert.DeserializeObject <MetadataStatement>(solostatement);
            var soloKeysSolo          = new MetadataTOCPayloadEntry
            {
                AaGuid        = soloMetadataStatement.AaGuid,
                Url           = "https://raw.githubusercontent.com/solokeys/solo/master/metadata/Solo-FIDO2-CTAP2-Authenticator.json",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = soloMetadataStatement
            };

            _entries.Add(new Guid(soloKeysSolo.AaGuid), soloKeysSolo);

            foreach (var entry in _entries)
            {
                entry.Value.MetadataStatement.AaGuid = entry.Value.AaGuid;
            }

            _toc = new MetadataTOCPayload()
            {
                Entries     = _entries.Select(o => o.Value).ToArray(),
                NextUpdate  = _cacheUntil?.ToString("yyyy-MM-dd") ?? "", //Results in no caching
                LegalHeader = "Static FAKE",
                Number      = 1
            };

            return(_toc);
        }
        public async Task <MetadataTOCPayload> GetToc()
        {
            #region Yubico
            // Yubico Security Key (5.1.x)
            var yubico = new MetadataTOCPayloadEntry
            {
                AaGuid        = "f8a011f3-8c0a-4d15-8006-17111f9edc7d",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport()
                    {
                        Status = AuthenticatorStatus.FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Yubico Security Key (5.1.x)",
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };
            _entries.Add(new Guid(yubico.AaGuid), yubico);

            // YubiKey 5 (5.1.x) USB and NFC AAGUID values from https://support.yubico.com/support/solutions/articles/15000014219-yubikey-5-series-technical-manual#AAGUID_Valuesxf002do

            // Yubikey 5 & YubiKey 5C & YubiKey 5C Nano & YubiKey 5 Nano (5.1.x)
            var yubikey5usb = new MetadataTOCPayloadEntry
            {
                AaGuid        = "cb69481e-8ff7-4039-93ec-0a2729a154a8",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash           = "",
                    Description    = "Yubikey 5, YubiKey 5C, YubiKey 5C Nano, YubiKey 5 Nano (5.1.x)",
                    AttachmentHint = 6,
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };
            _entries.Add(new Guid(yubikey5usb.AaGuid), yubikey5usb);

            // Yubikey 5 & YubiKey 5C & YubiKey 5C Nano & YubiKey 5 Nano (5.2.x)
            var yubikey5usb52 = new MetadataTOCPayloadEntry
            {
                AaGuid        = "ee882879-721c-4913-9775-3dfcce97072a",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash           = "",
                    Description    = "Yubikey 5, YubiKey 5C, YubiKey 5C Nano, YubiKey 5 Nano (5.2.x)",
                    AttachmentHint = 6,
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };
            _entries.Add(new Guid(yubikey5usb52.AaGuid), yubikey5usb52);

            // YubiKey 5 NFC (5.1.x)
            var yubikey5nfc = new MetadataTOCPayloadEntry
            {
                AaGuid        = "fa2b99dc-9e39-4257-8f92-4a30d23c4118",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash           = "",
                    Description    = "Yubico YubiKey 5 NFC (5.1.x)",
                    AttachmentHint = 30,
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };
            _entries.Add(new Guid(yubikey5nfc.AaGuid), yubikey5nfc);

            // YubiKey 5 NFC (5.2.x)
            var yubikey5nfc52 = new MetadataTOCPayloadEntry
            {
                AaGuid        = "2fc0579f-8113-47ea-b116-bb5a8db9202a",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash           = "",
                    Description    = "Yubico YubiKey 5 NFC (5.2.x)",
                    AttachmentHint = 30,
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };
            _entries.Add(new Guid(yubikey5nfc52.AaGuid), yubikey5nfc52);

            // YubiKey 5Ci (5.2.x)
            var yubikey5Ci = new MetadataTOCPayloadEntry
            {
                AaGuid        = "c5ef55ff-ad9a-4b9f-b580-adebafe026d",
                Hash          = "",
                StatusReports = new StatusReport[] { new StatusReport()
                                                     {
                                                         Status = AuthenticatorStatus.FIDO_CERTIFIED
                                                     } },
                MetadataStatement = new MetadataStatement
                {
                    Description                 = "Yubikey 5Ci (5.2.x)",
                    AttachmentHint              = 6,
                    AttestationTypes            = new ushort[] { (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL },
                    Hash                        = "",
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };
            _entries.Add(new Guid(yubikey5Ci.AaGuid), yubikey5Ci);

            // Security Key 5.2.x
            var yubicoSecuriyKey52 = new MetadataTOCPayloadEntry
            {
                AaGuid        = "b92c3f9a-c014-4056-887f-140a2501163b",
                Hash          = "",
                StatusReports = new StatusReport[] { new StatusReport()
                                                     {
                                                         Status = AuthenticatorStatus.FIDO_CERTIFIED
                                                     } },
                MetadataStatement = new MetadataStatement
                {
                    Description                 = "Yubico Security Key (5.2.x)",
                    AttachmentHint              = 6,
                    AttestationTypes            = new ushort[] { (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL },
                    Hash                        = "",
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };
            _entries.Add(new Guid(yubicoSecuriyKey52.AaGuid), yubicoSecuriyKey52);

            // Security Key NFC 5.1.x
            var yubicoSecuriyKeyNfc = new MetadataTOCPayloadEntry
            {
                AaGuid        = "6d44ba9b-f6ec-2e49-b930-0c8fe920cb73",
                Hash          = "",
                StatusReports = new StatusReport[] { new StatusReport()
                                                     {
                                                         Status = AuthenticatorStatus.FIDO_CERTIFIED
                                                     } },
                MetadataStatement = new MetadataStatement
                {
                    Description                 = "Yubico Security Key NFC (5.1.x)",
                    AttachmentHint              = 30,
                    AttestationTypes            = new ushort[] { (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL },
                    Hash                        = "",
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };
            _entries.Add(new Guid(yubicoSecuriyKeyNfc.AaGuid), yubicoSecuriyKeyNfc);

            // Security Key NFC 5.2.x
            var yubicoSecuriyKeyNfc52 = new MetadataTOCPayloadEntry
            {
                AaGuid        = "149a2021-8ef6-4133-96b8-81f8d5b7f1f5",
                Hash          = "",
                StatusReports = new StatusReport[] { new StatusReport()
                                                     {
                                                         Status = AuthenticatorStatus.FIDO_CERTIFIED
                                                     } },
                MetadataStatement = new MetadataStatement
                {
                    Description                 = "Yubico Security Key NFC (5.2.x)",
                    AttachmentHint              = 30,
                    AttestationTypes            = new ushort[] { (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL },
                    Hash                        = "",
                    AttestationRootCertificates = new string[]
                    {
                        YUBICO_ROOT
                    }
                }
            };
            _entries.Add(new Guid(yubicoSecuriyKeyNfc52.AaGuid), yubicoSecuriyKeyNfc52);

            #endregion

            #region Microsoft Hello
            var msftWhfbSoftware = new MetadataTOCPayloadEntry
            {
                AaGuid        = "6028B017-B1D4-4C02-B4B3-AFCDAFC96BB2",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Windows Hello software authenticator"
                }
            };
            _entries.Add(new Guid(msftWhfbSoftware.AaGuid), msftWhfbSoftware);

            var msftWhfbSoftwareVbs = new MetadataTOCPayloadEntry
            {
                AaGuid        = "6E96969E-A5CF-4AAD-9B56-305FE6C82795",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Windows Hello VBS software authenticator"
                }
            };
            _entries.Add(new Guid(msftWhfbSoftwareVbs.AaGuid), msftWhfbSoftwareVbs);

            var msftWhfbHardware = new MetadataTOCPayloadEntry
            {
                AaGuid        = "08987058-CADC-4B81-B6E1-30DE50DCBE96",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Windows Hello hardware authenticator"
                }
            };
            _entries.Add(new Guid(msftWhfbHardware.AaGuid), msftWhfbHardware);

            var msftWhfbHardwareVbs = new MetadataTOCPayloadEntry
            {
                AaGuid        = "9DDD1817-AF5A-4672-A2B9-3E3DD95000A9",
                Hash          = "",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = new MetadataStatement
                {
                    AttestationTypes = new ushort[]
                    {
                        (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL
                    },
                    Hash        = "",
                    Description = "Windows Hello VBS hardware authenticator"
                }
            };
            _entries.Add(new Guid(msftWhfbHardwareVbs.AaGuid), msftWhfbHardwareVbs);
            #endregion

            #region Solo
            var solostatement = await DownloadStringAsync("https://raw.githubusercontent.com/solokeys/solo/master/metadata/Solo-FIDO2-CTAP2-Authenticator.json");

            var soloMetadataStatement = JsonConvert.DeserializeObject <MetadataStatement>(solostatement);
            var soloKeysSolo          = new MetadataTOCPayloadEntry
            {
                AaGuid        = soloMetadataStatement.AaGuid,
                Url           = "https://raw.githubusercontent.com/solokeys/solo/master/metadata/Solo-FIDO2-CTAP2-Authenticator.json",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = soloMetadataStatement
            };
            _entries.Add(new Guid(soloKeysSolo.AaGuid), soloKeysSolo);

            var soloTapStatement = await DownloadStringAsync("https://raw.githubusercontent.com/solokeys/solo/master/metadata/SoloTap-FIDO2-CTAP2-Authenticator.json");

            var soloTapMetadataStatement = JsonConvert.DeserializeObject <MetadataStatement>(soloTapStatement);
            var soloTapMetadata          = new MetadataTOCPayloadEntry
            {
                AaGuid        = soloTapMetadataStatement.AaGuid,
                Url           = "https://raw.githubusercontent.com/solokeys/solo/master/metadata/SoloTap-FIDO2-CTAP2-Authenticator.json",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = soloTapMetadataStatement
            };
            _entries.Add(new Guid(soloTapMetadata.AaGuid), soloTapMetadata);

            var soloSomuStatement = await DownloadStringAsync("https://raw.githubusercontent.com/solokeys/solo/master/metadata/Somu-FIDO2-CTAP2-Authenticator.json");

            var soloSomuMetadataStatement = JsonConvert.DeserializeObject <MetadataStatement>(soloSomuStatement);
            var soloSomuMetadata          = new MetadataTOCPayloadEntry
            {
                AaGuid        = soloSomuMetadataStatement.AaGuid,
                Url           = "https://raw.githubusercontent.com/solokeys/solo/master/metadata/Somu-FIDO2-CTAP2-Authenticator.json",
                StatusReports = new StatusReport[]
                {
                    new StatusReport
                    {
                        Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED
                    }
                },
                MetadataStatement = soloSomuMetadataStatement
            };
            _entries.Add(new Guid(soloSomuMetadata.AaGuid), soloSomuMetadata);

            #endregion

            foreach (var entry in _entries)
            {
                entry.Value.MetadataStatement.AaGuid = entry.Value.AaGuid;
            }

            _toc = new MetadataTOCPayload()
            {
                Entries     = _entries.Select(o => o.Value).ToArray(),
                NextUpdate  = _cacheUntil?.ToString("yyyy-MM-dd") ?? "", //Results in no caching
                LegalHeader = "Static FAKE",
                Number      = 1
            };

            return(_toc);
        }