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 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"); }