Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please review #59

Merged
merged 12 commits into from
Oct 28, 2018
Prev Previous commit
Next Next commit
Add Yubico root and aaguid to metadata
  • Loading branch information
aseigler committed Oct 19, 2018
commit deefd86537bca5376a19408737c0311c14277d9d
39 changes: 20 additions & 19 deletions fido2-net-lib/AuthenticatorAttestationResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -545,35 +545,36 @@ public async Task<AttestationVerificationSuccess> VerifyAsync(CredentialCreateOp
{
MetadataTOCPayloadEntry entry = metadataService.GetEntry(authData.AttData.GuidAaguid);

if (null != entry)
if (null != entry && null != entry.MetadataStatement)
{
if (entry.Hash != entry.MetadataStatement.Hash) throw new Fido2VerificationException("Authenticator metadata statement has invalid hash");
if (null != entry.MetadataStatement)

var hasBasicFull = entry.MetadataStatement.AttestationTypes.Contains((ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL);
if (false == hasBasicFull &&
null != trustPath &&
trustPath.FirstOrDefault().Subject != trustPath.FirstOrDefault().Issuer) throw new Fido2VerificationException("Attestation with full attestation from authentictor that does not support full attestation");
if (true == hasBasicFull && null != trustPath && trustPath.FirstOrDefault().Subject != trustPath.FirstOrDefault().Issuer)
{
var hasBasicFull = entry.MetadataStatement.AttestationTypes.Contains((ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL);
if (false == hasBasicFull &&
null != trustPath && trustPath.FirstOrDefault().Subject != trustPath.FirstOrDefault().Issuer) throw new Fido2VerificationException("Attestation with full attestation from authentictor that does not support full attestation");
if (true == hasBasicFull && null != trustPath && trustPath.FirstOrDefault().Subject != trustPath.FirstOrDefault().Issuer)
var root = new X509Certificate2(Convert.FromBase64String(entry.MetadataStatement.AttestationRootCertificates.FirstOrDefault()));
var chain = new X509Chain();
chain.ChainPolicy.ExtraStore.Add(root);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
if (trustPath.Length > 1)
{
var root = new X509Certificate2(Convert.FromBase64String(entry.MetadataStatement.AttestationRootCertificates.FirstOrDefault()));
var chain = new X509Chain();
chain.ChainPolicy.ExtraStore.Add(root);
if (trustPath.Length > 1)
foreach (var cert in trustPath.Skip(1).Reverse())
{
foreach (X509Certificate2 cert in trustPath.Skip(1).Reverse())
{
chain.ChainPolicy.ExtraStore.Add(cert);
}
chain.ChainPolicy.ExtraStore.Add(cert);
}
var valid = chain.Build(trustPath[0]);
if (false == valid)
{
}
var valid = chain.Build(trustPath[0]);
if (false == valid)
{

}
}
}

foreach (StatusReport report in entry.StatusReports)
foreach (var report in entry.StatusReports)
{
if (true == Enum.IsDefined(typeof(UndesiredAuthenticatorStatus), (UndesiredAuthenticatorStatus) report.Status)) throw new Fido2VerificationException("Authenticator found with undesirable status");
}
Expand Down
51 changes: 42 additions & 9 deletions fido2-net-lib/MetadataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -534,24 +534,57 @@ public void CustomTOCPayloadFromCache()
{
if (true == System.IO.Directory.Exists(_cacheDir + @"\Custom"))
{
foreach (string filename in System.IO.Directory.GetFiles(_cacheDir + @"\Custom"))
foreach (var filename in System.IO.Directory.GetFiles(_cacheDir + @"\Custom"))
{
var rawStatement = System.IO.File.ReadAllText(filename);
var statement = JsonConvert.DeserializeObject<MetadataStatement>(rawStatement);
var entry = new MetadataTOCPayloadEntry();
entry.AaGuid = statement.AaGuid;
entry.MetadataStatement = statement;
entry.StatusReports = new StatusReport[] { new StatusReport() { Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED } };
var entry = new MetadataTOCPayloadEntry
{
AaGuid = statement.AaGuid,
MetadataStatement = statement,
StatusReports = new StatusReport[] { new StatusReport() { Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED } }
};
if (null != entry.AaGuid) payload.Add(new System.Guid(entry.AaGuid), entry);
}
}
else
{
var entry = new MetadataTOCPayloadEntry();
entry.AaGuid = "2b2ecbb4-59b4-44fa-868d-a072485d8ae0";
entry.StatusReports = new StatusReport[] { new StatusReport() { Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED } };
entry.MetadataStatement = new MetadataStatement() { AttestationTypes = new ushort[] { (ushort) MetadataAttestationType.ATTESTATION_BASIC_FULL } };
var entry = new MetadataTOCPayloadEntry
{
AaGuid = "2b2ecbb4-59b4-44fa-868d-a072485d8ae0",
Hash = "",
StatusReports = new StatusReport[] { new StatusReport() { Status = AuthenticatorStatus.NOT_FIDO_CERTIFIED } },
MetadataStatement = new MetadataStatement() { AttestationTypes = new ushort[] { (ushort)MetadataAttestationType.ATTESTATION_BASIC_FULL }, Hash = "" }
};
payload.Add(new System.Guid(entry.AaGuid), entry);

// from https://developers.yubico.com/U2F/yubico-u2f-ca-certs.txt
var yubicoRoot = "MIIDHjCCAgagAwIBAgIEG0BT9zANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZ" +
"dWJpY28gVTJGIFJvb3QgQ0EgU2VyaWFsIDQ1NzIwMDYzMTAgFw0xNDA4MDEwMDAw" +
"MDBaGA8yMDUwMDkwNDAwMDAwMFowLjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290" +
"IENBIFNlcmlhbCA0NTcyMDA2MzEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK" +
"AoIBAQC/jwYuhBVlqaiYWEMsrWFisgJ+PtM91eSrpI4TK7U53mwCIawSDHy8vUmk" +
"5N2KAj9abvT9NP5SMS1hQi3usxoYGonXQgfO6ZXyUA9a+KAkqdFnBnlyugSeCOep" +
"8EdZFfsaRFtMjkwz5Gcz2Py4vIYvCdMHPtwaz0bVuzneueIEz6TnQjE63Rdt2zbw" +
"nebwTG5ZybeWSwbzy+BJ34ZHcUhPAY89yJQXuE0IzMZFcEBbPNRbWECRKgjq//qT" +
"9nmDOFVlSRCt2wiqPSzluwn+v+suQEBsUjTGMEd25tKXXTkNW21wIWbxeSyUoTXw" +
"LvGS6xlwQSgNpk2qXYwf8iXg7VWZAgMBAAGjQjBAMB0GA1UdDgQWBBQgIvz0bNGJ" +
"hjgpToksyKpP9xv9oDAPBgNVHRMECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAN" +
"BgkqhkiG9w0BAQsFAAOCAQEAjvjuOMDSa+JXFCLyBKsycXtBVZsJ4Ue3LbaEsPY4" +
"MYN/hIQ5ZM5p7EjfcnMG4CtYkNsfNHc0AhBLdq45rnT87q/6O3vUEtNMafbhU6kt" +
"hX7Y+9XFN9NpmYxr+ekVY5xOxi8h9JDIgoMP4VB1uS0aunL1IGqrNooL9mmFnL2k" +
"LVVee6/VR6C5+KSTCMCWppMuJIZII2v9o4dkoZ8Y7QRjQlLfYzd3qGtKbw7xaF1U" +
"sG/5xUb/Btwb2X2g4InpiB/yt/3CpQXpiWX/K4mBvUKiGn05ZsqeY1gx4g0xLBqc" +
"U9psmyPzK+Vsgw2jeRQ5JlKDyqE0hebfC1tvFu0CCrJFcw==";

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 = "", AttestationRootCertificates = new string[] { yubicoRoot } }
};
payload.Add(new System.Guid(yubico.AaGuid), yubico);
}
}

Expand Down