/// <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> /// 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); } }
/// <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> /// 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> /// 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, 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> /// 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); } }