public ApiRequest PrepareApiRequest(IMessage request, byte[] transmissionKey, byte[] sessionToken = null) { if (transmissionKey == null) { transmissionKey = _transmissionKey; } var payload = new ApiRequestPayload { ApiVersion = 3, Payload = request.ToByteString() }; if (sessionToken != null) { payload.EncryptedSessionToken = ByteString.CopyFrom(sessionToken); } var encPayload = CryptoUtils.EncryptAesV2(payload.ToByteArray(), transmissionKey); var encKey = CryptoUtils.EncryptRsa(transmissionKey, KeeperSettings.KeeperPublicKeys[ServerKeyId]); return(new ApiRequest() { EncryptedTransmissionKey = ByteString.CopyFrom(encKey), PublicKeyId = ServerKeyId, Locale = Locale, EncryptedPayload = ByteString.CopyFrom(encPayload) }); }
public static async Task <NewUserMinimumParams> GetNewUserParams(this IKeeperEndpoint endpoint, string username) { var authRequest = new DomainPasswordRulesRequest { Username = username }; var payload = new ApiRequestPayload { Payload = ByteString.CopyFrom(authRequest.ToByteArray()) }; var rs = await endpoint.ExecuteRest("authentication/get_domain_password_rules", payload); return(NewUserMinimumParams.Parser.ParseFrom(rs)); }
/// <summary> /// Executes JSON request. /// </summary> /// <param name="endpoint">Keeper endpoint interface.</param> /// <param name="command">Keeper JSON command.</param> /// <param name="responseType">Keeper JSON response type.</param> /// <returns>Task returning Keeper JSON response.</returns> public static async Task <KeeperApiResponse> ExecuteV2Command(this IKeeperEndpoint endpoint, KeeperApiCommand command, Type responseType) { if (responseType == null) { responseType = typeof(KeeperApiResponse); } else if (!typeof(KeeperApiResponse).IsAssignableFrom(responseType)) { responseType = typeof(KeeperApiResponse); } command.locale = endpoint.Locale; command.clientVersion = endpoint.ClientVersion; byte[] rq; using (var ms = new MemoryStream()) { var cmdSerializer = new DataContractJsonSerializer(command.GetType(), JsonUtils.JsonSettings); cmdSerializer.WriteObject(ms, command); rq = ms.ToArray(); } var apiPayload = new ApiRequestPayload() { Payload = ByteString.CopyFrom(rq) }; #if DEBUG Debug.WriteLine("Request: " + Encoding.UTF8.GetString(rq)); #endif var rs = await endpoint.ExecuteRest("vault/execute_v2_command", apiPayload); #if DEBUG Debug.WriteLine("Response: " + Encoding.UTF8.GetString(rs)); #endif using (var ms = new MemoryStream(rs)) { var rsSerializer = new DataContractJsonSerializer(responseType, JsonUtils.JsonSettings); return((KeeperApiResponse)rsSerializer.ReadObject(ms)); } }
/// <summary> /// Executes Keeper Protobuf request. /// </summary> /// <param name="endpoint">Request endpoint.</param> /// <param name="request">Protobuf request.</param> /// <param name="responseType">Expected response type</param> /// <returns>Task returning Protobuf response.</returns> /// <seealso cref="IKeeperEndpoint.ExecuteRest"/> public async Task <IMessage> ExecuteAuthRest(string endpoint, IMessage request, Type responseType = null) { #if DEBUG Debug.WriteLine($"REST Request: endpoint \"{endpoint}\": {request}"); #endif var rq = new ApiRequestPayload { EncryptedSessionToken = ByteString.CopyFrom(authContext.SessionToken), ApiVersion = 3, }; if (request != null) { rq.Payload = request.ToByteString(); } var rsBytes = await Endpoint.ExecuteRest(endpoint, rq); this.ResetKeepAliveTimer(); if (responseType == null) { return(null); } var responseParser = responseType.GetProperty("Parser", BindingFlags.Static | BindingFlags.Public); if (responseParser == null) { throw new KeeperInvalidParameter("ExecuteAuthRest", "responseType", responseType.Name, "Google Protobuf class expected"); } var mp = (MessageParser)(responseParser.GetMethod.Invoke(null, null)); var response = mp.ParseFrom(rsBytes); #if DEBUG Debug.WriteLine($"REST response: endpoint \"{endpoint}\": {response}"); #endif return(response); }
public async Task <byte[]> ExecuteRest(string endpoint, ApiRequestPayload payload) { var builder = new UriBuilder(Server) { Path = "/api/rest/", Scheme = "https", Port = 443 }; var uri = new Uri(builder.Uri, endpoint); var keyId = ServerKeyId; payload.ApiVersion = 3; var attempt = 0; while (attempt < 3) { attempt++; var request = (HttpWebRequest)WebRequest.Create(uri); if (WebProxy != null) { request.Proxy = WebProxy; } request.UserAgent = "KeeperSDK.Net/" + ClientVersion; request.ContentType = "application/octet-stream"; request.Method = "POST"; var encPayload = CryptoUtils.EncryptAesV2(payload.ToByteArray(), _transmissionKey); var encKey = CryptoUtils.EncryptRsa(_transmissionKey, KeeperSettings.KeeperPublicKeys[keyId]); var apiRequest = new ApiRequest() { EncryptedTransmissionKey = ByteString.CopyFrom(encKey), PublicKeyId = keyId, Locale = Locale, EncryptedPayload = ByteString.CopyFrom(encPayload) }; HttpWebResponse response; try { using (var requestStream = request.GetRequestStream()) { var p = apiRequest.ToByteArray(); await requestStream.WriteAsync(p, 0, p.Length); } response = (HttpWebResponse)request.GetResponse(); } catch (WebException e) { response = (HttpWebResponse)e.Response; if (response == null) { throw; } if (response.StatusCode == HttpStatusCode.ProxyAuthenticationRequired) { throw; } } if (response.StatusCode == HttpStatusCode.OK) { SetConfigurationValid(keyId); if (response.ContentType == "application/octet-stream") { using (var ms = new MemoryStream()) using (var rss = response.GetResponseStream()) { await rss.CopyToAsync(ms); var bytes = ms.ToArray(); if (bytes.Length > 0) { bytes = CryptoUtils.DecryptAesV2(bytes, _transmissionKey); } return(bytes); } } return(null); } if (response.ContentType == "application/json") { using (var ms = new MemoryStream()) using (var rss = response.GetResponseStream()) { await rss.CopyToAsync(ms); await ms.FlushAsync(); #if DEBUG var jsonData = ms.ToArray(); Debug.WriteLine("Error Response: " + Encoding.UTF8.GetString(jsonData)); #endif ms.Seek(0, SeekOrigin.Begin); var serializer = new DataContractJsonSerializer(typeof(KeeperApiErrorResponse)); var keeperRs = serializer.ReadObject(ms) as KeeperApiErrorResponse; switch (keeperRs.Error) { case "key": if (KeeperSettings.KeeperPublicKeys.ContainsKey(keeperRs.KeyId)) { keyId = keeperRs.KeyId; continue; } break; case "region_redirect": throw new KeeperRegionRedirect(keeperRs.RegionHost); case "bad_request": case "device_not_registered": throw new KeeperInvalidDeviceToken(keeperRs.AdditionalInfo); case "session_token": case "auth_failed": throw new KeeperAuthFailed(); case "login_token_expired": throw new KeeperCanceled(); } throw new KeeperApiException(keeperRs.Error, keeperRs.Message); } } throw new Exception("Keeper Api Http error: " + response.StatusCode); } throw new Exception("Keeper Api error"); }
public async Task <byte[]> ExecuteRest(string endpoint, byte[] payload) { var builder = new UriBuilder(Server ?? "keepersecurity.com") { Path = "/api/rest/", Scheme = "https", Port = 443 }; var uri = new Uri(builder.Uri, endpoint); var apiPayload = new ApiRequestPayload() { Payload = ByteString.CopyFrom(payload) }; var attempt = 0; while (attempt < 3) { attempt++; var request = WebRequest.Create(uri); request.ContentType = "application/octet-stream"; request.Method = "POST"; var encPayload = CryptoUtils.EncryptAesV2(apiPayload.ToByteArray(), transmissionKey); var encKey = CryptoUtils.EncryptRsa(transmissionKey, KeeperSettings.KeeperPublicKeys[ServerKeyId]); var apiRequest = new ApiRequest() { EncryptedTransmissionKey = ByteString.CopyFrom(encKey), PublicKeyId = ServerKeyId, Locale = Locale, EncryptedPayload = ByteString.CopyFrom(encPayload) }; using (var requestStream = request.GetRequestStream()) { var p = apiRequest.ToByteArray(); await requestStream.WriteAsync(p, 0, p.Length); } HttpWebResponse response; try { response = (HttpWebResponse)request.GetResponse(); } catch (WebException e) { response = (HttpWebResponse)e.Response; } if (response.StatusCode == HttpStatusCode.OK && response.ContentType == "application/octet-stream") { using (var ms = new MemoryStream()) using (var rss = response.GetResponseStream()) { await rss.CopyToAsync(ms); var bytes = ms.ToArray(); return(CryptoUtils.DecryptAesV2(bytes, transmissionKey)); } } if (response.ContentType == "application/json") { var serializer = new DataContractJsonSerializer(typeof(KeeperApiErrorResponse)); using (var rss = response.GetResponseStream()) { var keeperRs = serializer.ReadObject(rss) as KeeperApiErrorResponse; switch (keeperRs.Error) { case "key": if (KeeperSettings.KeeperPublicKeys.ContainsKey(keeperRs.KeyId)) { ServerKeyId = keeperRs.KeyId; continue; } break; case "region_redirect": throw new KeeperRegionRedirect(keeperRs.RegionHost); case "bad_request": throw new KeeperInvalidDeviceToken(); } throw new KeeperApiException(keeperRs.resultCode, keeperRs.message); } } throw new Exception("Keeper Api Http error: " + response.StatusCode); } throw new Exception("Keeper Api error"); }
protected Task <byte[]> MockExecuteRest(string endpoint, ApiRequestPayload payload, IAuth auth) { if (auth.Endpoint.Server != DataVault.DefaultEnvironment) { return(Task.FromException <byte[]>(new KeeperRegionRedirect(DataVault.DefaultEnvironment))); } byte[] response = null; switch (endpoint) { case "authentication/register_device": { var device = new Device() { EncryptedDeviceToken = ByteString.CopyFrom(CryptoUtils.GetRandomBytes(64)), }; response = device.ToByteArray(); } break; case "authentication/start_login": { var lrs = new LoginResponse { EncryptedLoginToken = ByteString.CopyFrom(DataVault.EncryptedLoginToken), }; if (StopAtDeviceApproval) { lrs.LoginState = LoginState.DeviceApprovalRequired; } else if (StopAtTwoFactor) { lrs.LoginState = LoginState.Requires2Fa; lrs.Channels.Add(new TwoFactorChannelInfo { ChannelType = TwoFactorChannelType.TwoFaCtTotp, ChannelUid = ByteString.CopyFrom(CryptoUtils.GetRandomBytes(8)), ChannelName = "Mock", }); } else if (StopAtPassword) { lrs.LoginState = LoginState.RequiresAuthHash; lrs.Salt.Add(new Salt { Iterations = DataVault.UserIterations, Salt_ = ByteString.CopyFrom(DataVault.UserSalt), Name = "Mock", Uid = ByteString.CopyFrom(CryptoUtils.GetRandomBytes(8)), }); } else { lrs.LoginState = LoginState.LoggedIn; lrs.AccountUid = ByteString.CopyFrom(DataVault.AccountUid); lrs.PrimaryUsername = DataVault.UserName; lrs.CloneCode = ByteString.CopyFrom(CryptoUtils.GetRandomBytes(8)); lrs.EncryptedSessionToken = ByteString.CopyFrom(DataVault.SessionToken); var device = auth.Storage.Devices.List.FirstOrDefault(); var devicePrivateKey = CryptoUtils.LoadPrivateEcKey(device.DeviceKey); var devicePublicKey = CryptoUtils.GetPublicEcKey(devicePrivateKey); lrs.EncryptedDataKey = ByteString.CopyFrom(CryptoUtils.EncryptEc(DataVault.UserDataKey, devicePublicKey)); lrs.EncryptedDataKeyType = EncryptedDataKeyType.ByDevicePublicKey; } response = lrs.ToByteArray(); } break; case "authentication/validate_auth_hash": { var request = ValidateAuthHashRequest.Parser.ParseFrom(payload.Payload); var expectedPassword = CryptoUtils.DeriveV1KeyHash(DataVault.UserPassword, DataVault.UserSalt, DataVault.UserIterations); if (request.AuthResponse.SequenceEqual(expectedPassword)) { var lrs = new LoginResponse { LoginState = LoginState.LoggedIn, EncryptedLoginToken = ByteString.CopyFrom(DataVault.EncryptedLoginToken), AccountUid = ByteString.CopyFrom(DataVault.AccountUid), PrimaryUsername = DataVault.UserName, CloneCode = ByteString.CopyFrom(CryptoUtils.GetRandomBytes(8)), EncryptedSessionToken = ByteString.CopyFrom(DataVault.SessionToken), EncryptedDataKey = ByteString.CopyFrom(DataVault.EncryptionParams), EncryptedDataKeyType = EncryptedDataKeyType.ByPassword, }; response = lrs.ToByteArray(); } else { return(Task.FromException <byte[]>(new KeeperAuthFailed())); } } break; case "authentication/request_device_verification": StopAtDeviceApproval = false; response = new byte[0]; break; case "authentication/2fa_send_push": if (StopAtDeviceApproval) { StopAtDeviceApproval = false; } response = new byte[0]; break; case "authentication/2fa_validate": var tfvr = TwoFactorValidateRequest.Parser.ParseFrom(payload.Payload); if (tfvr.Value == DataVault.TwoFactorOneTimeToken) { StopAtTwoFactor = false; var tfars = new TwoFactorValidateResponse { EncryptedLoginToken = tfvr.EncryptedLoginToken }; response = tfars.ToByteArray(); } else { return(Task.FromException <byte[]>(new KeeperAuthFailed())); } break; case "vault/execute_v2_command": break; case "authentication/validate_device_verification_code": var vdvcr = ValidateDeviceVerificationCodeRequest.Parser.ParseFrom(payload.Payload); if (vdvcr.VerificationCode == DataVault.DeviceVerificationEmailCode) { StopAtDeviceApproval = false; response = new byte[0]; } else { return(Task.FromException <byte[]>(new KeeperAuthFailed())); } break; case "login/account_summary": { response = auth.ProcessAccountSummary().ToByteArray(); } break; } if (response != null) { return(Task.FromResult(response)); } return(Task.FromException <byte[]>(new KeeperCanceled())); }