using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; using Bit.Core.Models.Table; using Bit.Core.Enums; using OtpNet; namespace Bit.Core.Identity { public class AuthenticatorTokenProvider : IUserTwoFactorTokenProvider { public Task CanGenerateTwoFactorTokenAsync(UserManager manager, User user) { var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Authenticator); var canGenerate = user.TwoFactorProviderIsEnabled(TwoFactorProviderType.Authenticator) && !string.IsNullOrWhiteSpace((string)provider.MetaData["Key"]); return Task.FromResult(canGenerate); } public Task GenerateAsync(string purpose, UserManager manager, User user) { return Task.FromResult(null); } public Task ValidateAsync(string purpose, string token, UserManager manager, User user) { var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Authenticator); var otp = new Totp(Base32Encoding.ToBytes((string)provider.MetaData["Key"])); long timeStepMatched; var valid = otp.VerifyTotp(token, out timeStepMatched, new VerificationWindow(1, 1)); return Task.FromResult(valid); } } }