/// <summary> /// SetUserCredential method implementation /// </summary> public bool SetUserCredential(MFAWebAuthNUser user, MFAUserCredential credential) { bool result = false; try { credential.UserId = user.Id; List <MFAUserCredential> _lst = _mfacredusers.GetData(); _lst.Where(s => s.UserId.SequenceEqual(user.Id) && (s.Descriptor.Id.SequenceEqual(credential.Descriptor.Id))).ToList() .ForEach(s => { s.AaGuid = credential.AaGuid; s.CredType = credential.CredType; s.Descriptor = credential.Descriptor; s.Descriptor.Id = credential.Descriptor.Id; s.Descriptor.Transports = credential.Descriptor.Transports; s.Descriptor.Type = credential.Descriptor.Type; s.PublicKey = credential.PublicKey; s.RegDate = credential.RegDate; s.SignatureCounter = credential.SignatureCounter; s.UserHandle = credential.UserHandle; s.UserId = credential.UserId; result = true; }); _mfacredusers.SetData(_lst); } catch (Exception ex) { DataLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error, 5000); throw new Exception(ex.Message); } return(result); }
/// <summary> /// SetRegisterCredentialResult method implementation /// </summary> private int SetRegisterCredentialResult(AuthenticationContext ctx, string jsonResponse) { try { string jsonOptions = ctx.CredentialOptions; if (string.IsNullOrEmpty(jsonOptions)) { throw new ArgumentNullException(jsonOptions); } if (string.IsNullOrEmpty(jsonResponse)) { throw new ArgumentNullException(jsonResponse); } MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, ctx.UPN); if (user != null) { RegisterCredentialOptions options = RegisterCredentialOptions.FromJson(jsonOptions); bool callback(IsCredentialIdUniqueToUserParams args) { var users = RuntimeRepository.GetUsersByCredentialId(Config, user, args.CredentialId); if (users.Count > 0) { return(false); } return(true); } AuthenticatorAttestationRawResponse attestationResponse = JsonConvert.DeserializeObject <AuthenticatorAttestationRawResponse>(jsonResponse); RegisterCredentialResult success = _webathn.SetRegisterCredentialResult(attestationResponse, options, callback); RuntimeRepository.AddUserCredential(Config, options.User.FromCore(), new MFAUserCredential { Descriptor = new MFAPublicKeyCredentialDescriptor(success.Result.CredentialId), PublicKey = success.Result.PublicKey, UserHandle = success.Result.User.Id, SignatureCounter = success.Result.Counter, CredType = success.Result.CredType, RegDate = DateTime.Now, AaGuid = success.Result.Aaguid }); return((int)AuthenticationResponseKind.Biometrics); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"), System.Diagnostics.EventLogEntryType.Error, 5000); return((int)AuthenticationResponseKind.Error); } } catch (Exception e) { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), System.Diagnostics.EventLogEntryType.Error, 5000); return((int)AuthenticationResponseKind.Error); } }
/// <summary> /// UpdateCounter method implementation /// </summary> public void UpdateCounter(MFAWebAuthNUser user, byte[] credentialId, uint counter) { string credsid = HexaEncoding.GetHexStringFromByteArray(credentialId); MFAUserCredential cred = GetCredentialByCredentialId(user, credsid); if (cred != null) { cred.SignatureCounter = counter; SetUserCredential(user, cred); } }
internal static Fido2User ToCore(this MFAWebAuthNUser user) { var usr = new Fido2User() { DisplayName = user.DisplayName, Id = user.Id, Name = user.Name }; return(usr); }
/// <summary> /// GetUser method implementation /// </summary> public MFAWebAuthNUser GetUser(int challengesize, string username) { MFAWebAuthNUser result = new MFAWebAuthNUser() { Id = CheckSumEncoding.EncodeUserID(challengesize, username), Name = username, DisplayName = username }; return(result); }
/// <summary> /// GetUsersByCredentialId method implementation /// </summary> public List <MFAWebAuthNUser> GetUsersByCredentialId(MFAWebAuthNUser user, byte[] credentialId) { List <MFAWebAuthNUser> _users = new List <MFAWebAuthNUser>(); string credsid = HexaEncoding.GetHexStringFromByteArray(credentialId); MFAUserCredential cred = GetCredentialByCredentialId(user, credsid); if (cred != null) { _users.Add(user); } return(_users); }
/// <summary> /// SetLoginAssertionResult method implementation /// </summary> private int SetLoginAssertionResult(AuthenticationContext ctx, string jsonResponse) { try { string jsonOptions = ctx.AssertionOptions; if (string.IsNullOrEmpty(jsonOptions)) { throw new ArgumentNullException(jsonOptions); } if (string.IsNullOrEmpty(jsonResponse)) { throw new ArgumentNullException(jsonResponse); } MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, ctx.UPN); if (user != null) { AssertionOptions options = AssertionOptions.FromJson(jsonOptions); AuthenticatorAssertionRawResponse clientResponse = JsonConvert.DeserializeObject <AuthenticatorAssertionRawResponse>(jsonResponse); MFAUserCredential creds = RuntimeRepository.GetCredentialById(Config, user, clientResponse.Id); if (creds == null) { throw new Exception("Unknown credentials"); } uint storedCounter = creds.SignatureCounter; bool callback(IsUserHandleOwnerOfCredentialIdParams args) { var storedCreds = RuntimeRepository.GetCredentialsByUserHandle(Config, user, args.UserHandle); return(storedCreds.Exists(c => c.Descriptor.Id.SequenceEqual(args.CredentialId))); } AssertionVerificationResult res = _webathn.SetAssertionResult(clientResponse, options, creds.PublicKey, storedCounter, callback); RuntimeRepository.UpdateCounter(Config, user, res.CredentialId, res.Counter); return((int)AuthenticationResponseKind.Biometrics); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"), System.Diagnostics.EventLogEntryType.Error, 5000); return((int)AuthenticationResponseKind.Error); } } catch (Exception e) { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), System.Diagnostics.EventLogEntryType.Error, 5000); return((int)AuthenticationResponseKind.Error); } }
/// <summary> /// GetCredentialsByUser method implementation /// </summary> public List <MFAUserCredential> GetCredentialsByUser(MFAWebAuthNUser user) { try { List <MFAUserCredential> _creds = _mfacredusers.GetData(); return(_creds.Where(s => s.UserId.SequenceEqual(user.Id)).ToList()); } catch (Exception ex) { DataLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error, 5000); throw new Exception(ex.Message); } }
/// <summary> /// GetCredentialByCredentialId method implementation /// </summary> public MFAUserCredential GetCredentialByCredentialId(MFAWebAuthNUser user, string credentialId) { try { List <MFAUserCredential> _creds = _mfacredusers.GetData(); return(_creds.FirstOrDefault(s => s.UserId.SequenceEqual(user.Id) && (HexaEncoding.GetHexStringFromByteArray(s.Descriptor.Id)).Equals(credentialId))); } catch (Exception ex) { DataLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error, 5000); throw new Exception(ex.Message); } }
/// <summary> /// RemoveUserCredential method implementation /// </summary> public bool RemoveUserCredential(MFAWebAuthNUser user, string credentialId) { try { List <MFAUserCredential> _lst = _mfacredusers.GetData(); int res = _lst.RemoveAll(s => s.UserId.SequenceEqual(user.Id) && (HexaEncoding.GetHexStringFromByteArray(s.Descriptor.Id)).Equals(credentialId)); _mfacredusers.SetData(_lst); return(res > 0); } catch (Exception ex) { DataLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error, 5000); throw new Exception(ex.Message); } }
/// <summary> /// AddCredential method implementation /// </summary> public bool AddUserCredential(MFAWebAuthNUser user, MFAUserCredential credential) { try { credential.UserId = user.Id; List <MFAUserCredential> _lst = _mfacredusers.GetData(); _lst.Add(credential); _mfacredusers.SetData(_lst); return(true); } catch (Exception ex) { DataLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error, 5000); throw new Exception(ex.Message); } }
/// <summary> /// GetUserStoredCredentials method implementation /// </summary> public List <WebAuthNCredentialInformation> GetUserStoredCredentials(string upn) { List <WebAuthNCredentialInformation> wcreds = new List <WebAuthNCredentialInformation>(); try { MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, upn); if (user != null) { List <MFAUserCredential> creds = RuntimeRepository.GetCredentialsByUser(Config, user); if (creds.Count == 0) { return(null); } // return wcreds; foreach (MFAUserCredential st in creds) { WebAuthNCredentialInformation itm = new WebAuthNCredentialInformation() { CredentialID = HexaEncoding.GetHexStringFromByteArray(st.Descriptor.Id), AaGuid = st.AaGuid, CredType = st.CredType, RegDate = st.RegDate, SignatureCounter = st.SignatureCounter, NickName = st.NickName }; if (st.Descriptor.Type != null) { itm.Type = EnumExtensions.ToEnumMemberValue(st.Descriptor.Type.Value); } wcreds.Add(itm); } return(wcreds.OrderByDescending(c => c.RegDate).ToList()); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", upn, "User does not exists !"), EventLogEntryType.Error, 5000); throw new ArgumentNullException(string.Format("{0}\r\n{1}", upn, "User does not exists !"));; } } catch (Exception e) { Log.WriteEntry(string.Format("{0}\r\n{1}", upn, e.Message), EventLogEntryType.Error, 5000); throw e; } }
/// <summary> /// RemoveUserStoredCredentials method implementation /// </summary> public void RemoveUserStoredCredentials(string upn, string credentialid) { try { MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, upn); if (user != null) { RuntimeRepository.RemoveUserCredential(Config, user, credentialid); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", upn, "User does not exists !"), EventLogEntryType.Error, 5000); throw new ArgumentNullException(string.Format("{0}\r\n{1}", upn, "User does not exists !"));; } } catch (Exception e) { Log.WriteEntry(string.Format("{0}\r\n{1}", upn, e.Message), EventLogEntryType.Error, 5000); throw e; } }
/// <summary> /// GetRegisterCredentialOptions method implementation /// </summary> private string GetRegisterCredentialOptions(AuthenticationContext ctx) { try { if (string.IsNullOrEmpty(ctx.UPN)) { throw new ArgumentNullException(ctx.UPN); } string attType = this.ConveyancePreference; // none, direct, indirect string authType = this.Attachement; // <empty>, platform, cross-platform string userVerification = this.UserVerificationRequirement; // preferred, required, discouraged bool requireResidentKey = this.RequireResidentKey; // true,false MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, ctx.UPN); if (user != null) { List <MFAPublicKeyCredentialDescriptor> existingKeys = RuntimeRepository.GetCredentialsByUser(Config, user).Select(c => c.Descriptor).ToList(); // 3. Create options AuthenticatorSelection authenticatorSelection = new AuthenticatorSelection { RequireResidentKey = requireResidentKey, UserVerification = userVerification.ToEnum <UserVerificationRequirement>() }; if (!string.IsNullOrEmpty(authType)) { authenticatorSelection.AuthenticatorAttachment = authType.ToEnum <AuthenticatorAttachment>(); } AuthenticationExtensionsClientInputs exts = new AuthenticationExtensionsClientInputs() { Extensions = this.Extentions, UserVerificationIndex = this.UserVerificationIndex, Location = this.Location, UserVerificationMethod = this.UserVerificationMethod, EnforceCredProtect = this.EnforceCredProtect, CredProtect = this.CredProtect, HmacSecret = this.HmacSecret, BiometricAuthenticatorPerformanceBounds = new AuthenticatorBiometricPerfBounds { FAR = float.MaxValue, FRR = float.MaxValue } }; RegisterCredentialOptions options = _webathn.GetRegisterCredentialOptions(user.ToCore(), existingKeys.ToCore(), authenticatorSelection, attType.ToEnum <AttestationConveyancePreference>(), exts); string result = options.ToJson(); ctx.CredentialOptions = result; return(result); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"), EventLogEntryType.Error, 5000); string result = (new RegisterCredentialOptions { Status = "error", ErrorMessage = string.Format("{0}", "User does not exists !") }).ToJson(); ctx.CredentialOptions = result; return(result); } } catch (Exception e) { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), System.Diagnostics.EventLogEntryType.Error, 5000); string result = (new RegisterCredentialOptions { Status = "error", ErrorMessage = string.Format("{0}{1}", e.Message, e.InnerException != null ? " (" + e.InnerException.Message + ")" : "") }).ToJson(); ctx.CredentialOptions = result; return(result); } }
/// <summary> /// GetCredentialsByUserHandle method implementation /// </summary> public List <MFAUserCredential> GetCredentialsByUserHandle(MFAWebAuthNUser user, byte[] userHandle) { List <MFAUserCredential> _lst = GetCredentialsByUser(user); return(_lst.Where(c => c.UserHandle.SequenceEqual(userHandle)).ToList()); }
/// <summary> /// GetCredentialById method implementation /// </summary> public MFAUserCredential GetCredentialById(MFAWebAuthNUser user, byte[] id) { string credsid = HexaEncoding.GetHexStringFromByteArray(id); return(GetCredentialByCredentialId(user, credsid)); }
/// <summary> /// RemoveUserStoredCredentials method implementation /// </summary> public void RemoveUserStoredCredentials(AuthenticationContext ctx, string credentialid) { MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, ctx.UPN); RuntimeRepository.RemoveUserCredential(Config, user, credentialid); }
/// <summary> /// SetLoginAssertionResult method implementation /// </summary> private int SetLoginAssertionResult(AuthenticationContext ctx, string jsonResponse, out string error) { bool isDeserialized = false; try { string jsonOptions = ctx.AssertionOptions; if (string.IsNullOrEmpty(jsonOptions)) { throw new ArgumentNullException(jsonOptions); } if (string.IsNullOrEmpty(jsonResponse)) { throw new ArgumentNullException(jsonResponse); } MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, ctx.UPN); if (user != null) { AssertionOptions options = AssertionOptions.FromJson(jsonOptions); try { AuthenticatorAssertionRawResponse clientResponse = JsonConvert.DeserializeObject <AuthenticatorAssertionRawResponse>(jsonResponse); isDeserialized = true; MFAUserCredential creds = RuntimeRepository.GetCredentialById(Config, user, clientResponse.Id); if (creds == null) { throw new Exception("Unknown credentials"); } AuthenticatorData authData = new AuthenticatorData(clientResponse.Response.AuthenticatorData); bool isnocount = Utilities.IsNoCounterDevice(this.Config.WebAuthNProvider.Configuration, ctx); uint authCounter = 0; uint storedCounter = 0; if (!isnocount) { authCounter = authData.SignCount; storedCounter = creds.SignatureCounter; } else if ((authCounter > 0) && (authCounter <= storedCounter)) { ResourcesLocale Resources = new ResourcesLocale(ctx.Lcid); throw new Exception(Resources.GetString(ResourcesLocaleKind.FIDOHtml, "BIOERRORAUTHREPLAY")); } #pragma warning disable CS1998 // Cette méthode async n'a pas d'opérateur 'await' et elle s'exécutera de façon synchrone IsUserHandleOwnerOfCredentialIdAsync callback = async(args) => #pragma warning restore CS1998 // Cette méthode async n'a pas d'opérateur 'await' et elle s'exécutera de façon synchrone { var storedCreds = RuntimeRepository.GetCredentialsByUserHandle(Config, user, args.UserHandle); return(storedCreds.Exists(c => c.Descriptor.Id.SequenceEqual(args.CredentialId))); }; // Apple counter always 0 AssertionVerificationResult res = _webathn.SetAssertionResult(clientResponse, options, creds.PublicKey, storedCounter, callback).Result; if (!isnocount) { RuntimeRepository.UpdateCounter(Config, user, res.CredentialId, res.Counter); } else { RuntimeRepository.UpdateCounter(Config, user, res.CredentialId, 0); } if (!authData.UserPresent || !authData.UserVerified) { switch (creds.CredType) { case "none": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.None)); break; case "android-key": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.AndroidKey)); break; case "android-safetynet": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.AndroidSafetyNet)); break; case "fido-u2f": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.Fido2U2f)); break; case "packed": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.Packed)); break; case "tpm": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.TPM)); break; case "apple": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.Apple)); break; default: ctx.PinRequirements = false; break; } } else { ctx.PinRequirements = false; } error = string.Empty; return((int)AuthenticationResponseKind.Biometrics); } catch (Exception ex) { if (isDeserialized) { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, ex.Message), EventLogEntryType.Error, 5000); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, jsonResponse), EventLogEntryType.Error, 5000); } error = ex.Message; return((int)AuthenticationResponseKind.Error); } } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"), EventLogEntryType.Error, 5000); error = string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"); return((int)AuthenticationResponseKind.Error); } } catch (Exception e) { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), EventLogEntryType.Error, 5000); error = e.Message; return((int)AuthenticationResponseKind.Error); } }
/// <summary> /// SetRegisterCredentialResult method implementation /// </summary> private int SetRegisterCredentialResult(AuthenticationContext ctx, string jsonResponse, out string error) { bool isDeserialized = false; try { string jsonOptions = ctx.CredentialOptions; if (string.IsNullOrEmpty(jsonOptions)) { throw new ArgumentNullException(jsonOptions); } if (string.IsNullOrEmpty(jsonResponse)) { throw new ArgumentNullException(jsonResponse); } MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, ctx.UPN); if (user != null) { CredentialCreateOptions options = CredentialCreateOptions.FromJson(jsonOptions); #pragma warning disable CS1998 // Cette méthode async n'a pas d'opérateur 'await' et elle s'exécutera de façon synchrone IsCredentialIdUniqueToUserAsyncDelegate callback = async(args) => #pragma warning restore CS1998 // Cette méthode async n'a pas d'opérateur 'await' et elle s'exécutera de façon synchrone { var users = RuntimeRepository.GetUsersByCredentialId(Config, user, args.CredentialId); if (users.Count > 0) { return(false); } return(true); }; AuthenticatorAttestationRawResponse attestationResponse = JsonConvert.DeserializeObject <AuthenticatorAttestationRawResponse>(jsonResponse); isDeserialized = true; CredentialMakeResult success = _webathn.SetRegisterCredentialResult(attestationResponse, options, callback).Result; RuntimeRepository.AddUserCredential(Config, user, new MFAUserCredential { Descriptor = new MFAPublicKeyCredentialDescriptor(success.Result.CredentialId), PublicKey = success.Result.PublicKey, UserHandle = success.Result.User.Id, SignatureCounter = success.Result.Counter, CredType = success.Result.CredType, RegDate = DateTime.Now, AaGuid = success.Result.Aaguid, NickName = ctx.NickName }); error = string.Empty; return((int)AuthenticationResponseKind.Biometrics); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"), System.Diagnostics.EventLogEntryType.Error, 5000); error = string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"); return((int)AuthenticationResponseKind.Error); } } catch (Exception e) { if (isDeserialized) { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), EventLogEntryType.Error, 5000); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, jsonResponse), EventLogEntryType.Error, 5000); } error = e.Message; return((int)AuthenticationResponseKind.Error); } }
/// <summary> /// SetLoginAssertionResult method implementation /// </summary> private int SetLoginAssertionResult(AuthenticationContext ctx, string jsonResponse, out string error) { bool isDeserialized = false; try { string jsonOptions = ctx.AssertionOptions; if (string.IsNullOrEmpty(jsonOptions)) { throw new ArgumentNullException(jsonOptions); } if (string.IsNullOrEmpty(jsonResponse)) { throw new ArgumentNullException(jsonResponse); } MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, ctx.UPN); if (user != null) { AssertionOptions options = AssertionOptions.FromJson(jsonOptions); try { AuthenticatorAssertionRawResponse clientResponse = JsonConvert.DeserializeObject <AuthenticatorAssertionRawResponse>(jsonResponse); isDeserialized = true; MFAUserCredential creds = RuntimeRepository.GetCredentialById(Config, user, clientResponse.Id); if (creds == null) { throw new Exception("Unknown credentials"); } // Check Replay AuthenticatorData authData = new AuthenticatorData(clientResponse.Response.AuthenticatorData); uint authCounter = authData.SignCount; uint storedCounter = creds.SignatureCounter; if ((authCounter <= 0) || (authCounter <= storedCounter)) { ResourcesLocale Resources = new ResourcesLocale(ctx.Lcid); throw new Exception(Resources.GetString(ResourcesLocaleKind.Html, "BIOERRORAUTHREPLAY")); } bool callback(IsUserHandleOwnerOfCredentialIdParams args) { var storedCreds = RuntimeRepository.GetCredentialsByUserHandle(Config, user, args.UserHandle); return(storedCreds.Exists(c => c.Descriptor.Id.SequenceEqual(args.CredentialId))); } AssertionVerificationResult res = _webathn.SetAssertionResult(clientResponse, options, creds.PublicKey, storedCounter, callback); RuntimeRepository.UpdateCounter(Config, user, res.CredentialId, res.Counter); if (!authData.UserPresent || !authData.UserVerified) { switch (creds.CredType) { case "none": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.None)); break; case "android-key": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.AndroidKey)); break; case "android-safetynet": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.AndroidSafetyNet)); break; case "fido-u2f": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.Fido2U2f)); break; case "packed": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.Packed)); break; case "tpm": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.TPM)); break; case "apple": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.Apple)); break; default: ctx.PinRequirements = false; break; } } else { ctx.PinRequirements = false; } error = string.Empty; return((int)AuthenticationResponseKind.Biometrics); } catch (Exception ex) { if (isDeserialized) { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, ex.Message), EventLogEntryType.Error, 5000); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, jsonResponse), EventLogEntryType.Error, 5000); } error = ex.Message; return((int)AuthenticationResponseKind.Error); } } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"), EventLogEntryType.Error, 5000); error = string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"); return((int)AuthenticationResponseKind.Error); } } catch (Exception e) { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), EventLogEntryType.Error, 5000); error = e.Message; return((int)AuthenticationResponseKind.Error); } }
/// <summary> /// SetLoginAssertionResult method implementation /// </summary> private int SetLoginAssertionResult(AuthenticationContext ctx, string jsonResponse) { try { string jsonOptions = ctx.AssertionOptions; if (string.IsNullOrEmpty(jsonOptions)) { throw new ArgumentNullException(jsonOptions); } if (string.IsNullOrEmpty(jsonResponse)) { throw new ArgumentNullException(jsonResponse); } MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, ctx.UPN); if (user != null) { AssertionOptions options = AssertionOptions.FromJson(jsonOptions); AuthenticatorAssertionRawResponse clientResponse = JsonConvert.DeserializeObject <AuthenticatorAssertionRawResponse>(jsonResponse); // AuthData Flags byte flag = clientResponse.Response.AuthenticatorData[32]; var userpresent = (flag & (1 << 0)) != 0; var userverified = (flag & (1 << 2)) != 0; var attestedcred = (flag & (1 << 6)) != 0; var hasextenddata = (flag & (1 << 7)) != 0; MFAUserCredential creds = RuntimeRepository.GetCredentialById(Config, user, clientResponse.Id); if (creds == null) { throw new Exception("Unknown credentials"); } uint storedCounter = creds.SignatureCounter; bool callback(IsUserHandleOwnerOfCredentialIdParams args) { var storedCreds = RuntimeRepository.GetCredentialsByUserHandle(Config, user, args.UserHandle); return(storedCreds.Exists(c => c.Descriptor.Id.SequenceEqual(args.CredentialId))); } AssertionVerificationResult res = _webathn.SetAssertionResult(clientResponse, options, creds.PublicKey, storedCounter, callback); RuntimeRepository.UpdateCounter(Config, user, res.CredentialId, res.Counter); if (!userpresent || !userverified) { switch (creds.CredType) { case "none": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.None)); break; case "android-key": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.AndroidKey)); break; case "android-safetynet": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.AndroidSafetyNet)); break; case "fido-u2f": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.Fido2U2f)); break; case "packed": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.Packed)); break; case "tpm": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.TPM)); break; case "apple": ctx.PinRequirements = (this.PinRequirements.HasFlag(WebAuthNPinRequirements.Apple)); break; default: ctx.PinRequirements = false; break; } } else { ctx.PinRequirements = false; } return((int)AuthenticationResponseKind.Biometrics); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"), System.Diagnostics.EventLogEntryType.Error, 5000); return((int)AuthenticationResponseKind.Error); } } catch (Exception e) { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), System.Diagnostics.EventLogEntryType.Error, 5000); return((int)AuthenticationResponseKind.Error); } }