Beispiel #1
0
        public async Task <string> GenerateAsync(string purpose, UserManager <User> manager, User user)
        {
            if (!user.Premium)
            {
                return(null);
            }

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

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

            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(null);
            }

            await _u2fRepository.DeleteManyByUserIdAsync(user.Id);

            var challenges = new List <object>();

            foreach (var key in keys)
            {
                var registration = new DeviceRegistration(key.KeyHandleBytes, key.PublicKeyBytes,
                                                          key.CertificateBytes, key.Counter);
                var auth = U2fLib.StartAuthentication(Utilities.CoreHelpers.U2fAppIdUrl(_globalSettings), registration);

                // Maybe move this to a bulk create when we support more than 1 key?
                await _u2fRepository.CreateAsync(new U2f
                {
                    AppId        = auth.AppId,
                    Challenge    = auth.Challenge,
                    KeyHandle    = auth.KeyHandle,
                    Version      = auth.Version,
                    UserId       = user.Id,
                    CreationDate = DateTime.UtcNow
                });

                challenges.Add(new
                {
                    appId     = auth.AppId,
                    challenge = auth.Challenge,
                    keyHandle = auth.KeyHandle,
                    version   = auth.Version
                });
            }

            var token = JsonConvert.SerializeObject(challenges);

            return(token);
        }
Beispiel #2
0
        public async Task <string> GenerateAsync(string purpose, UserManager <User> manager, User user)
        {
            var userService = _serviceProvider.GetRequiredService <IUserService>();

            if (!(await userService.CanAccessPremium(user)))
            {
                return(null);
            }

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

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

            await _u2fRepository.DeleteManyByUserIdAsync(user.Id);

            try
            {
                var challengeBytes = U2fLib.Crypto.GenerateChallenge();
                var appId          = Utilities.CoreHelpers.U2fAppIdUrl(_globalSettings);
                var oldChallenges  = new List <object>();
                var challengeKeys  = new List <object>();
                foreach (var key in keys)
                {
                    var registration = new DeviceRegistration(key.Item2.KeyHandleBytes, key.Item2.PublicKeyBytes,
                                                              key.Item2.CertificateBytes, key.Item2.Counter);
                    var auth = U2fLib.StartAuthentication(appId, registration, challengeBytes);

                    // TODO: Maybe move this to a bulk create?
                    await _u2fRepository.CreateAsync(new U2f
                    {
                        AppId        = auth.AppId,
                        Challenge    = auth.Challenge,
                        KeyHandle    = auth.KeyHandle,
                        Version      = auth.Version,
                        UserId       = user.Id,
                        CreationDate = DateTime.UtcNow
                    });

                    challengeKeys.Add(new
                    {
                        keyHandle = auth.KeyHandle,
                        version   = auth.Version
                    });

                    // TODO: Old challenges array is here for backwards compat. Remove in the future.
                    oldChallenges.Add(new
                    {
                        appId     = auth.AppId,
                        challenge = auth.Challenge,
                        keyHandle = auth.KeyHandle,
                        version   = auth.Version
                    });
                }

                var oldToken = JsonConvert.SerializeObject(oldChallenges);
                var token    = JsonConvert.SerializeObject(new
                {
                    appId     = appId,
                    challenge = challengeBytes.ByteArrayToBase64String(),
                    keys      = challengeKeys
                });
                return($"{token}|{oldToken}");
            }
            catch (U2fException)
            {
                return(null);
            }
        }