/// <summary> /// Registers a new client with the server and completes the link with another client. /// </summary> /// <param name="model"></param> /// <param name="newLinkIdentifier"></param> /// <returns></returns> public bool CompleteNewLink(AccountModel model, string newLinkIdentifier) { var serverAccountSettings = model.ServerAccountSettings.Query().First(); var cryptoKeyId = serverAccountSettings.ApiCryptoKeyId; var cryptoKey = model.CryptoKeys.Query().First(r => r.Id == cryptoKeyId); var apiClient = new ApiClient( serverAccountSettings.HttpsEnabled, serverAccountSettings.Host, serverAccountSettings.Port, serverAccountSettings.ApiVersion, serverAccountSettings.ApiKey, cryptoKey.PrivateKeyPem); var completeLinkRequest = new ServerAPIRequests.CompleteLink { LinkIdentifier = newLinkIdentifier }; completeLinkRequest.GetResponse(apiClient); var request = new ServerAPIRequests.GetLinkedDevice(); var linkedDeviceResponse = request.GetResponse(apiClient); var linkedDeviceCryptoKey = model.CryptoKeys.Query() .FirstOrDefault(r => r.PublicKeyPemHash == HashUtil.Sha256(linkedDeviceResponse.PublicKeyPem)); if (linkedDeviceCryptoKey == null) { var newLinkedClientCryptoKeyId = model.CryptoKeys.Create( new CryptoKey { PublicKeyPem = linkedDeviceResponse.PublicKeyPem, PublicKeyPemHash = HashUtil.Sha256(linkedDeviceResponse.PublicKeyPem) }); linkedDeviceCryptoKey = model.CryptoKeys.Query().First(r => r.Id == newLinkedClientCryptoKeyId); } model.Links.Create(new Link { Identifier = newLinkIdentifier, //LinkedClientCryptoKeyId = linkedDeviceCryptoKeyId.Id }); model.ServerAccountSettings.Update(serverAccountSettings.Id, new ServerAccountSetting { LinkedDeviceCryptoKeyId = linkedDeviceCryptoKey.Id }); if (_mainForm.InvokeRequired) { _mainForm.Invoke((MethodInvoker) delegate { _mainForm.UpdateForm(); }); } else { _mainForm.UpdateForm(); } return(true); }
public bool RegisterInitialOtpDevice(string linkCodeString) { var linkCode = new LinkCodeRegisterInitialOtpDevice(linkCodeString); var newKeyPair = AsymmetricCryptoUtil.GenerateKeyPair(); var apiClient = new ApiClient( linkCode.ServerHttps, linkCode.ServerHost, linkCode.ServerPort, linkCode.ServerApiVersion); var request = new ServerAPIRequestsUnauthenticated.RegisterSecondDevice { LoginRequestIdentifier = linkCode.LoginIdentifier, PublicKeyPem = newKeyPair.PublicPem, DeviceLabel = "My Test Device", DeviceType = "phone", DeviceSubtype = "testdevice" }; var response = request.GetResponse(apiClient); var apiClientAuthenticated = new ApiClient( linkCode.ServerHttps, linkCode.ServerHost, linkCode.ServerPort, linkCode.ServerApiVersion, response.ApiKey, newKeyPair.PrivatePem); var totpcode = new TimeBasedOtpGenerator(new Key(response.Secret), response.Digits, new SHA1HMACAlgorithm()) .GenerateOtp(DateTime.UtcNow); try { var confirmRequest = new ServerAPIRequests.ConfirmSecondDevice { OtpCode = totpcode }; confirmRequest.GetResponse(apiClientAuthenticated); } catch (RequestException) { MessageBox.Show(@"Unable to validate the device. Please try again."); return(false); } var serverInfo = apiClientAuthenticated.GetServerInfo(new GetServerInfoRequest()); var newServerId = AppModel.ServerAccounts.Create(new AppModels.ServerAccount { ServerIdentifier = serverInfo.ServerIdentifier }); var model = AccountModel.GetModel(newServerId); var newOtpAccountId = model.OtpAccounts.Create(new OtpAccount { Type = response.Type, Label = response.Label, Issuer = response.Issuer, Secret = response.Secret, Algorithm = response.Algorithm, Digits = response.Digits, Counter = response.Counter, Period = response.Period }); var cryptoKeyId = model.CryptoKeys.Create(new CryptoKey { OwnKey = true, Trust = true, PrivateKeyPem = newKeyPair.PrivatePem, PublicKeyPem = newKeyPair.PublicPem, PublicKeyPemHash = HashUtil.Sha256(newKeyPair.PublicPem) }); var serverAccountSettingsId = model.ServerAccountSettings.Create(new ServerAccountSetting { Identifier = serverInfo.ServerIdentifier, Label = serverInfo.ServerLabel, HttpsEnabled = linkCode.ServerHttps, Host = linkCode.ServerHost, Port = linkCode.ServerPort, ApiVersion = linkCode.ServerApiVersion, UserIdentifier = response.UserIdentifier, DeviceIdentifier = response.DeviceIdentifier, OtpAccountId = newOtpAccountId, ApiKey = response.ApiKey, EmailAddress = linkCode.EmailAddress, ApiCryptoKeyId = cryptoKeyId }); var linkedDeviceRequest = new ServerAPIRequests.GetLinkedDevice(); ServerAPIRequests.GetLinkedDevice.ResponseParams linkedDeviceResponse; linkedDeviceResponse = linkedDeviceRequest.GetResponse(apiClientAuthenticated); if (linkCode.InitiatingDevicePublicKeyPem != HashUtil.Sha256(linkedDeviceResponse.PublicKeyPem)) { MessageBox.Show(@"Unable to verify device keys. You will need to do this manually from the desktop app."); } else { var linkedDeviceCryptoKeyId = model.CryptoKeys.Create(new CryptoKey { Trust = true, PublicKeyPem = linkedDeviceResponse.PublicKeyPem, PublicKeyPemHash = HashUtil.Sha256(linkedDeviceResponse.PublicKeyPem) }); model.ServerAccountSettings.Update(serverAccountSettingsId, new ServerAccountSetting { LinkedDeviceCryptoKeyId = linkedDeviceCryptoKeyId }); } _syncAccounts.Add(newServerId, new SyncAccounts(this, model)); _syncAccounts[newServerId].Start(); _mainForm.UpdateForm(); return(true); }