private async void SetupOtpDeviceLink_Load(object sender, EventArgs e) { _loginRequestIdentifier = await GetLoginIdentifier(); if (_loginRequestIdentifier == null) { Invoke((MethodInvoker) delegate { MessageBox.Show(@"There was an unknown error registering mobile device with the server"); Close(); }); return; } var linkCode = new LinkCodeRegisterInitialOtpDevice(_serverAccount.HttpsEnabled, _serverAccount.ServerHost, _serverAccount.ServerPort, _serverAccount.ServerApiVersion, _loginRequestIdentifier, _serverAccount.EmailAddress, _cryptoKey.PublicKeyPemHash, false); var linkCodeString = linkCode.ToString(); Logger.Verbose("Attempting to link to second device with code: " + linkCodeString); // The -1 on the dimensions is due to an issue in Mono where the image won't show // unless it is smaller than the label (rather than the same size) var barcodeWriter = new BarcodeWriter { Format = BarcodeFormat.QR_CODE, Options = new ZXing.Common.EncodingOptions { Margin = 0, Height = lblQrCode.Height - 1, Width = lblQrCode.Height - 1 } }; ImageAnimator.StopAnimate(lblQrCode.Image, AnimateLoader); _loadingAnimationRunning = false; var barcodeBitmap = barcodeWriter.Write(linkCodeString); lblQrCode.Image = barcodeBitmap; _checkthread = new Thread(CheckLink); _checkthread.Start(); txtOtpDeviceLinkCode.Text = linkCodeString; }
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); }