public static WebAuthnAssertion VerifyAssertionResult(Fido2Configuration fido2Config, string requestJSON, string resultJSON, Func <string, byte[]> getStoredPublicKey) { var fido2 = new Fido2(fido2Config); IsUserHandleOwnerOfCredentialIdAsync callback = (args) => { var u = args.UserHandle; var id = args.CredentialId; return(Task.FromResult(true)); }; var request = Newtonsoft.Json.JsonConvert.DeserializeObject <AssertionOptions>(requestJSON); AuthenticatorAssertionRawResponse assertionResponse = Newtonsoft.Json.JsonConvert.DeserializeObject <AuthenticatorAssertionRawResponse>(resultJSON); var credentialId = System.Convert.ToBase64String(assertionResponse.Id); uint storedCounter = 0; // 0 means always success var publicKey = getStoredPublicKey(credentialId); var success = fido2.MakeAssertionAsync(assertionResponse, request, publicKey, storedCounter, callback).Result; var clientDataJson = Newtonsoft.Json.JsonConvert.DeserializeObject <AuthenticatorResponse>(System.Text.UTF8Encoding.UTF8.GetString(assertionResponse.Response.ClientDataJson)); var challenge = clientDataJson.Challenge; return(new WebAuthnAssertion { verified = true, challenge = System.Convert.ToBase64String(clientDataJson.Challenge), credentialId = credentialId, publicKey = System.Convert.ToBase64String(publicKey), userHandle = assertionResponse.Response.UserHandle }); }
public static WebAuthnAssertion VerifyAttestationResult(Fido2Configuration fido2Config, string requestJSON, string resultJSON) { var fido2 = new Fido2(fido2Config); IsCredentialIdUniqueToUserAsyncDelegate callback = (IsCredentialIdUniqueToUserParams args) => { var id = args.CredentialId; // generated ID by authenticator(should be always unique for each authenticator, equivalent to client cert) var u = args.User; // user info, kind of useless as this can be changed by js at client side return(Task.FromResult(true)); }; var request = Newtonsoft.Json.JsonConvert.DeserializeObject <CredentialCreateOptions>(requestJSON); AuthenticatorAttestationRawResponse regResponse = Newtonsoft.Json.JsonConvert.DeserializeObject <AuthenticatorAttestationRawResponse>(resultJSON); var success = fido2.MakeNewCredentialAsync(regResponse, request, callback).Result; var clientDataJson = Newtonsoft.Json.JsonConvert.DeserializeObject <AuthenticatorResponse>(System.Text.UTF8Encoding.UTF8.GetString(regResponse.Response.ClientDataJson)); var challenge = System.Convert.ToBase64String(clientDataJson.Challenge); var credentialId = System.Convert.ToBase64String(success.Result.CredentialId); var publicKey = System.Convert.ToBase64String(success.Result.PublicKey); var signingCounter = success.Result.Counter; // designed for replay attact prevention but useless for a multiple node situation var user = success.Result.User; var aaguid = success.Result.Aaguid; return(new WebAuthnAssertion { verified = true, challenge = challenge, credentialId = credentialId, publicKey = publicKey, signingCounter = signingCounter, aaguid = aaguid, userHandle = request.User.Id }); }
public void Validate_Success_Empty() { var config = new Fido2Configuration(); var result = _validator.Validate(config, false); result.Failed.Should().BeFalse(); }
public async Task TestAppleAttestationAsync() { var jsonPost = JsonConvert.DeserializeObject <AuthenticatorAttestationRawResponse>(File.ReadAllText("./attestationAppleResponse.json")); var options = JsonConvert.DeserializeObject <CredentialCreateOptions>(File.ReadAllText("./attestationAppleOptions.json")); var o = AuthenticatorAttestationResponse.Parse(jsonPost); var config = new Fido2Configuration { Origin = "https://6cc3c9e7967a.ngrok.io" }; await o.VerifyAsync(options, config, (x) => Task.FromResult(true), _metadataService, null); byte[] ad = o.AttestationObject.AuthData; // TODO : Why read ad ? Is the test finished ? }
public static string MakeWebAuthnAttestationRequest(Fido2Configuration fido2Config, byte[] challenge, LoginUsr LUser, List <PublicKeyCredentialDescriptor> excludedCredentials) { string usrId = LUser.UsrId.ToString(); string usrIdB64 = System.Convert.ToBase64String(usrId.ToUtf8ByteArray()); Fido2User user = new Fido2User { DisplayName = LUser.UsrName, /* must be restricted to no more than than 64 for device like yubikey as it would fail without reason */ //Name = (Guid.NewGuid().ToString() + " " + DateTime.UtcNow.ToString("o")).Left(64), //Id= Guid.NewGuid().ToString().ToUtf8ByteArray() Name = LUser.LoginName, Id = usrIdB64.ToUtf8ByteArray() }; AuthenticatorSelection authenticatorSelection = new AuthenticatorSelection { RequireResidentKey = false, UserVerification = UserVerificationRequirement.Discouraged, // AuthenticatorAttachment = AuthenticatorAttachment.Platform, }; AttestationConveyancePreference attConveyancePreference = AttestationConveyancePreference.None; AuthenticationExtensionsClientInputs clientExtensions = new AuthenticationExtensionsClientInputs { Extensions = true, SimpleTransactionAuthorization = string.Format("you are registering to {0}", fido2Config.ServerName), Location = true, UserVerificationMethod = true, BiometricAuthenticatorPerformanceBounds = new AuthenticatorBiometricPerfBounds { FAR = float.MaxValue, FRR = float.MaxValue } }; var fido2 = new Fido2(fido2Config); // must do this for the verification to work var options = fido2.RequestNewCredential(user, excludedCredentials, authenticatorSelection, attConveyancePreference, clientExtensions); // the challenge is random byte but we need more info, replace it options.Challenge = challenge; var createRequest = Fido2NetLib.CredentialCreateOptions.Create(fido2Config , challenge, user, authenticatorSelection, attConveyancePreference , excludedCredentials != null && excludedCredentials.Count > 0 ? excludedCredentials : null , clientExtensions); string createRequestJson = options.ToJson(); return(createRequestJson); }
public UnitTest1() { var MDSAccessKey = Environment.GetEnvironmentVariable("fido2:MDSAccessKey"); var CacheDir = Environment.GetEnvironmentVariable("fido2:MDSCacheDirPath"); // Only create and use MetadataService if we have an accesskey MetadataService = string.IsNullOrEmpty(MDSAccessKey) ? null : MDSMetadata.Instance(MDSAccessKey, CacheDir); if (null != MetadataService) { if (false == MetadataService.IsInitialized()) { MetadataService.Initialize().Wait(); } } config = new Fido2Configuration { Origin = "https://localhost:44329" }; }
public Fido2Tests() { var MDSAccessKey = Environment.GetEnvironmentVariable("fido2:MDSAccessKey"); //var CacheDir = Environment.GetEnvironmentVariable("fido2:MDSCacheDirPath"); var services = new ServiceCollection(); var staticClient = new StaticMetadataRepository(); var repos = new List <IMetadataRepository>(); repos.Add(staticClient); if (!string.IsNullOrEmpty(MDSAccessKey)) { repos.Add(new Fido2MetadataServiceRepository(MDSAccessKey, null)); } services.AddDistributedMemoryCache(); services.AddLogging(); var provider = services.BuildServiceProvider(); var memCache = provider.GetService <IDistributedCache>(); var service = new DistributedCacheMetadataService( repos, memCache, provider.GetService <ILogger <DistributedCacheMetadataService> >()); service.Initialize().Wait(); _metadataService = service; _config = new Fido2Configuration { Origin = "https://localhost:44329" }; }
public static string MakeWebAuthnAssertionRequest(Fido2Configuration fido2Config, byte[] challenge, List <PublicKeyCredentialDescriptor> allowedCredentials) { AuthenticatorSelection authSelection = new AuthenticatorSelection { RequireResidentKey = false, UserVerification = UserVerificationRequirement.Preferred, // AuthenticatorAttachment = null, }; AuthenticationExtensionsClientInputs clientExtensions = new AuthenticationExtensionsClientInputs { Extensions = true, SimpleTransactionAuthorization = string.Format("you are registering to {0}", fido2Config.ServerName), Location = true, UserVerificationMethod = true, }; var fido2 = new Fido2(fido2Config); var assertionRequest = Fido2NetLib.AssertionOptions.Create(fido2Config, challenge, allowedCredentials, UserVerificationRequirement.Preferred, clientExtensions); string assertionRequestJson = assertionRequest.ToJson(); return(assertionRequestJson); }
public Fido2Service(ApplicationDbContextFactory contextFactory, IFido2 fido2, Fido2Configuration fido2Configuration) { _contextFactory = contextFactory; _fido2 = fido2; _fido2Configuration = fido2Configuration; }
static Fido2Tests() { var MDSAccessKey = Environment.GetEnvironmentVariable("fido2:MDSAccessKey"); var services = new ServiceCollection(); var staticClient = new StaticMetadataRepository(); var repos = new List <IMetadataRepository>(); repos.Add(staticClient); if (!string.IsNullOrEmpty(MDSAccessKey)) { repos.Add(new Fido2MetadataServiceRepository(MDSAccessKey, null)); } services.AddDistributedMemoryCache(); services.AddLogging(); var provider = services.BuildServiceProvider(); var memCache = provider.GetService <IDistributedCache>(); var service = new DistributedCacheMetadataService( repos, memCache, provider.GetService <ILogger <DistributedCacheMetadataService> >()); service.Initialize().Wait(); _metadataService = service; _config = new Fido2Configuration { Origin = "https://localhost:44329" }; _validCOSEParameters = new List <object[]>(); _validCOSEParameters.Add(new object[3] { COSE.KeyType.EC2, COSE.Algorithm.ES256, COSE.EllipticCurve.P256 }); _validCOSEParameters.Add(new object[3] { COSE.KeyType.EC2, COSE.Algorithm.ES384, COSE.EllipticCurve.P384 }); _validCOSEParameters.Add(new object[3] { COSE.KeyType.EC2, COSE.Algorithm.ES512, COSE.EllipticCurve.P521 }); _validCOSEParameters.Add(new object[2] { COSE.KeyType.RSA, COSE.Algorithm.RS256 }); _validCOSEParameters.Add(new object[2] { COSE.KeyType.RSA, COSE.Algorithm.RS384 }); _validCOSEParameters.Add(new object[2] { COSE.KeyType.RSA, COSE.Algorithm.RS512 }); _validCOSEParameters.Add(new object[2] { COSE.KeyType.RSA, COSE.Algorithm.PS256 }); _validCOSEParameters.Add(new object[2] { COSE.KeyType.RSA, COSE.Algorithm.PS384 }); _validCOSEParameters.Add(new object[2] { COSE.KeyType.RSA, COSE.Algorithm.PS512 }); _validCOSEParameters.Add(new object[3] { COSE.KeyType.OKP, COSE.Algorithm.EdDSA, COSE.EllipticCurve.Ed25519 }); }