Ejemplo n.º 1
0
        public async Task <bool> CompleteU2fRegistrationAsync(User user, string deviceResponse)
        {
            if (string.IsNullOrWhiteSpace(deviceResponse))
            {
                return(false);
            }

            var challenges = await _u2fRepository.GetManyByUserIdAsync(user.Id);

            if (!challenges?.Any() ?? true)
            {
                return(false);
            }

            var registerResponse = BaseModel.FromJson <RegisterResponse>(deviceResponse);

            var challenge = challenges.OrderBy(i => i.Id).Last(i => i.KeyHandle == null);
            var statedReg = new StartedRegistration(challenge.Challenge, challenge.AppId);
            var reg       = U2fLib.FinishRegistration(statedReg, registerResponse);

            await _u2fRepository.DeleteManyByUserIdAsync(user.Id);

            // Add device
            var providers = user.GetTwoFactorProviders();

            if (providers == null)
            {
                providers = new Dictionary <TwoFactorProviderType, TwoFactorProvider>();
            }
            else if (providers.ContainsKey(TwoFactorProviderType.U2f))
            {
                providers.Remove(TwoFactorProviderType.U2f);
            }

            providers.Add(TwoFactorProviderType.U2f, new TwoFactorProvider
            {
                MetaData = new Dictionary <string, object>
                {
                    ["Key1"] = new TwoFactorProvider.U2fMetaData
                    {
                        KeyHandle   = reg.KeyHandle == null ? null : Utils.ByteArrayToBase64String(reg.KeyHandle),
                        PublicKey   = reg.PublicKey == null ? null : Utils.ByteArrayToBase64String(reg.PublicKey),
                        Certificate = reg.AttestationCert == null ? null : Utils.ByteArrayToBase64String(reg.AttestationCert),
                        Compromised = false,
                        Counter     = reg.Counter
                    }
                },
                Enabled = true
            });
            user.SetTwoFactorProviders(providers);
            await UpdateTwoFactorProviderAsync(user, TwoFactorProviderType.U2f);

            return(true);
        }
Ejemplo n.º 2
0
        public async Task <bool> ValidateAsync(string purpose, string token, UserManager <User> manager, User user)
        {
            if (!user.Premium || string.IsNullOrWhiteSpace(token))
            {
                return(false);
            }

            var provider = user.GetTwoFactorProvider(TwoFactorProviderType.U2f);

            if (!HasProperMetaData(provider))
            {
                return(false);
            }

            var keys = new List <TwoFactorProvider.U2fMetaData>();

            var key1 = new TwoFactorProvider.U2fMetaData((dynamic)provider.MetaData["Key1"]);

            if (!key1?.Compromised ?? false)
            {
                keys.Add(key1);
            }

            if (keys.Count == 0)
            {
                return(false);
            }

            var authenticateResponse = BaseModel.FromJson <AuthenticateResponse>(token);
            var key = keys.FirstOrDefault(f => f.KeyHandle == authenticateResponse.KeyHandle);

            if (key == null)
            {
                return(false);
            }

            var challenges = await _u2fRepository.GetManyByUserIdAsync(user.Id);

            if (challenges.Count == 0)
            {
                return(false);
            }

            // User will have a authentication request for each device they have registered so get the one that matches
            // the device key handle
            var challenge = challenges.FirstOrDefault(c => c.KeyHandle == authenticateResponse.KeyHandle);

            if (challenge == null)
            {
                return(false);
            }

            var success      = true;
            var registration = new DeviceRegistration(key.KeyHandleBytes, key.PublicKeyBytes, key.CertificateBytes,
                                                      key.Counter);

            try
            {
                var auth = new StartedAuthentication(challenge.Challenge, challenge.AppId, challenge.KeyHandle);
                U2fLib.FinishAuthentication(auth, authenticateResponse, registration);
            }
            catch (U2fException)
            {
                success = false;
            }

            // Update database
            await _u2fRepository.DeleteManyByUserIdAsync(user.Id);

            key.Counter     = registration.Counter;
            key.Compromised = registration.IsCompromised;

            var providers = user.GetTwoFactorProviders();

            providers[TwoFactorProviderType.U2f].MetaData["Key1"] = key;
            user.SetTwoFactorProviders(providers);
            await manager.UpdateAsync(user);

            return(success);
        }
Ejemplo n.º 3
0
        public async Task <bool> CompleteU2fRegistrationAsync(User user, int id, string name, string deviceResponse)
        {
            if (string.IsNullOrWhiteSpace(deviceResponse))
            {
                return(false);
            }

            var challenges = await _u2fRepository.GetManyByUserIdAsync(user.Id);

            if (!challenges?.Any() ?? true)
            {
                return(false);
            }

            var registerResponse = BaseModel.FromJson <RegisterResponse>(deviceResponse);

            try
            {
                var challenge  = challenges.OrderBy(i => i.Id).Last(i => i.KeyHandle == null);
                var startedReg = new StartedRegistration(challenge.Challenge, challenge.AppId);
                var reg        = U2fLib.FinishRegistration(startedReg, registerResponse);

                await _u2fRepository.DeleteManyByUserIdAsync(user.Id);

                // Add device
                var providers = user.GetTwoFactorProviders();
                if (providers == null)
                {
                    providers = new Dictionary <TwoFactorProviderType, TwoFactorProvider>();
                }
                var provider = user.GetTwoFactorProvider(TwoFactorProviderType.U2f);
                if (provider == null)
                {
                    provider = new TwoFactorProvider();
                }
                if (provider.MetaData == null)
                {
                    provider.MetaData = new Dictionary <string, object>();
                }

                if (provider.MetaData.Count >= 5)
                {
                    // Can only register up to 5 keys
                    return(false);
                }

                var keyId = $"Key{id}";
                if (provider.MetaData.ContainsKey(keyId))
                {
                    provider.MetaData.Remove(keyId);
                }

                provider.Enabled = true;
                provider.MetaData.Add(keyId, new TwoFactorProvider.U2fMetaData
                {
                    Name        = name,
                    KeyHandle   = reg.KeyHandle == null ? null : Utils.ByteArrayToBase64String(reg.KeyHandle),
                    PublicKey   = reg.PublicKey == null ? null : Utils.ByteArrayToBase64String(reg.PublicKey),
                    Certificate = reg.AttestationCert == null ? null : Utils.ByteArrayToBase64String(reg.AttestationCert),
                    Compromised = false,
                    Counter     = reg.Counter
                });

                if (providers.ContainsKey(TwoFactorProviderType.U2f))
                {
                    providers.Remove(TwoFactorProviderType.U2f);
                }

                providers.Add(TwoFactorProviderType.U2f, provider);
                user.SetTwoFactorProviders(providers);
                await UpdateTwoFactorProviderAsync(user, TwoFactorProviderType.U2f);

                return(true);
            }
            catch (U2fException e)
            {
                Logger.LogError(e, "Complete U2F registration error.");
                return(false);
            }
        }