Example #1
0
        public async Task PostUserKeyToKeyConnector(string keyConnectorUrl, KeyConnectorUserKeyRequest request)
        {
            using (var requestMessage = new HttpRequestMessage())
            {
                var authHeader = await GetActiveBearerTokenAsync();

                requestMessage.Version    = new Version(1, 0);
                requestMessage.Method     = HttpMethod.Post;
                requestMessage.RequestUri = new Uri(string.Concat(keyConnectorUrl, "/user-keys"));
                requestMessage.Headers.Add("Authorization", string.Concat("Bearer ", authHeader));
                requestMessage.Content = new StringContent(JsonConvert.SerializeObject(request, _jsonSettings),
                                                           Encoding.UTF8, "application/json");

                HttpResponseMessage response;
                try
                {
                    response = await _httpClient.SendAsync(requestMessage);
                }
                catch (Exception e)
                {
                    throw new ApiException(HandleWebError(e));
                }
                if (!response.IsSuccessStatusCode)
                {
                    var error = await HandleErrorAsync(response, false, true);

                    throw new ApiException(error);
                }
            }
        }
Example #2
0
        public async Task MigrateUser()
        {
            var organization = await GetManagingOrganization();

            var key = await _cryptoService.GetKeyAsync();

            try
            {
                var keyConnectorRequest = new KeyConnectorUserKeyRequest(key.EncKeyB64);
                await _apiService.PostUserKeyToKeyConnector(organization.KeyConnectorUrl, keyConnectorRequest);
            }
            catch (Exception e)
            {
                throw new Exception("Unable to reach Key Connector", e);
            }

            await _apiService.PostConvertToKeyConnector();
        }
Example #3
0
        private async Task <AuthResult> LogInHelperAsync(string email, string hashedPassword, string localHashedPassword,
                                                         string code, string codeVerifier, string redirectUrl, SymmetricCryptoKey key,
                                                         TwoFactorProviderType?twoFactorProvider = null, string twoFactorToken = null, bool?remember = null,
                                                         string captchaToken = null, string orgId = null)
        {
            var storedTwoFactorToken = await _tokenService.GetTwoFactorTokenAsync(email);

            var appId = await _appIdService.GetAppIdAsync();

            var deviceRequest = new DeviceRequest(appId, _platformUtilsService);

            string[] emailPassword;
            string[] codeCodeVerifier;
            if (email != null && hashedPassword != null)
            {
                emailPassword = new[] { email, hashedPassword };
            }
            else
            {
                emailPassword = null;
            }
            if (code != null && codeVerifier != null && redirectUrl != null)
            {
                codeCodeVerifier = new[] { code, codeVerifier, redirectUrl };
            }
            else
            {
                codeCodeVerifier = null;
            }

            TokenRequest request;

            if (twoFactorToken != null && twoFactorProvider != null)
            {
                request = new TokenRequest(emailPassword, codeCodeVerifier, twoFactorProvider, twoFactorToken, remember,
                                           captchaToken, deviceRequest);
            }
            else if (storedTwoFactorToken != null)
            {
                request = new TokenRequest(emailPassword, codeCodeVerifier, TwoFactorProviderType.Remember,
                                           storedTwoFactorToken, false, captchaToken, deviceRequest);
            }
            else
            {
                request = new TokenRequest(emailPassword, codeCodeVerifier, null, null, false, captchaToken, deviceRequest);
            }

            var response = await _apiService.PostIdentityTokenAsync(request);

            ClearState();
            var result = new AuthResult {
                TwoFactor = response.TwoFactorNeeded, CaptchaSiteKey = response.CaptchaResponse?.SiteKey
            };

            if (result.CaptchaNeeded)
            {
                return(result);
            }

            if (result.TwoFactor)
            {
                // Two factor required.
                Email = email;
                MasterPasswordHash      = hashedPassword;
                LocalMasterPasswordHash = localHashedPassword;
                Code                      = code;
                CodeVerifier              = codeVerifier;
                SsoRedirectUrl            = redirectUrl;
                _key                      = _setCryptoKeys ? key : null;
                TwoFactorProvidersData    = response.TwoFactorResponse.TwoFactorProviders2;
                result.TwoFactorProviders = response.TwoFactorResponse.TwoFactorProviders2;
                CaptchaToken              = response.TwoFactorResponse.CaptchaToken;
                return(result);
            }

            var tokenResponse = response.TokenResponse;

            result.ResetMasterPassword = tokenResponse.ResetMasterPassword;
            result.ForcePasswordReset  = tokenResponse.ForcePasswordReset;
            if (tokenResponse.TwoFactorToken != null)
            {
                await _tokenService.SetTwoFactorTokenAsync(tokenResponse.TwoFactorToken, email);
            }
            await _tokenService.SetAccessTokenAsync(tokenResponse.AccessToken, true);

            await _stateService.AddAccountAsync(
                new Account(
                    new Account.AccountProfile()
            {
                UserId = _tokenService.GetUserId(),
                Email = _tokenService.GetEmail(),
                Name = _tokenService.GetName(),
                KdfType = tokenResponse.Kdf,
                KdfIterations = tokenResponse.KdfIterations,
                HasPremiumPersonally = _tokenService.GetPremium(),
            },
                    new Account.AccountTokens()
            {
                AccessToken = tokenResponse.AccessToken,
                RefreshToken = tokenResponse.RefreshToken,
            }
                    )
                );

            _messagingService.Send("accountAdded");
            if (_setCryptoKeys)
            {
                if (key != null)
                {
                    await _cryptoService.SetKeyAsync(key);
                }

                if (localHashedPassword != null)
                {
                    await _cryptoService.SetKeyHashAsync(localHashedPassword);
                }

                if (code == null || tokenResponse.Key != null)
                {
                    if (tokenResponse.KeyConnectorUrl != null)
                    {
                        await _keyConnectorService.GetAndSetKey(tokenResponse.KeyConnectorUrl);
                    }

                    await _cryptoService.SetEncKeyAsync(tokenResponse.Key);

                    // User doesn't have a key pair yet (old account), let's generate one for them.
                    if (tokenResponse.PrivateKey == null)
                    {
                        try
                        {
                            var keyPair = await _cryptoService.MakeKeyPairAsync();

                            await _apiService.PostAccountKeysAsync(new KeysRequest
                            {
                                PublicKey           = keyPair.Item1,
                                EncryptedPrivateKey = keyPair.Item2.EncryptedString
                            });

                            tokenResponse.PrivateKey = keyPair.Item2.EncryptedString;
                        }
                        catch { }
                    }

                    await _cryptoService.SetEncPrivateKeyAsync(tokenResponse.PrivateKey);
                }
                else if (tokenResponse.KeyConnectorUrl != null)
                {
                    // SSO Key Connector Onboarding
                    var password = await _cryptoFunctionService.RandomBytesAsync(64);

                    var k = await _cryptoService.MakeKeyAsync(Convert.ToBase64String(password), _tokenService.GetEmail(), tokenResponse.Kdf, tokenResponse.KdfIterations);

                    var keyConnectorRequest = new KeyConnectorUserKeyRequest(k.EncKeyB64);
                    await _cryptoService.SetKeyAsync(k);

                    var encKey = await _cryptoService.MakeEncKeyAsync(k);

                    await _cryptoService.SetEncKeyAsync(encKey.Item2.EncryptedString);

                    var keyPair = await _cryptoService.MakeKeyPairAsync();

                    try
                    {
                        await _apiService.PostUserKeyToKeyConnector(tokenResponse.KeyConnectorUrl, keyConnectorRequest);
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to reach Key Connector", e);
                    }

                    var keys = new KeysRequest
                    {
                        PublicKey           = keyPair.Item1,
                        EncryptedPrivateKey = keyPair.Item2.EncryptedString
                    };
                    var setPasswordRequest = new SetKeyConnectorKeyRequest(
                        encKey.Item2.EncryptedString, keys, tokenResponse.Kdf, tokenResponse.KdfIterations, orgId
                        );
                    await _apiService.PostSetKeyConnectorKey(setPasswordRequest);
                }
            }

            await _stateService.SetBiometricLockedAsync(false);

            _messagingService.Send("loggedIn");
            return(result);
        }