void otpCopyToolStripItem_Click(object sender, EventArgs e) { PwEntry entry; if (this.GetSelectedSingleEntry(out entry)) { if (!entry.Strings.Exists(OtpAuthData.StringDictionaryKey)) { if (MessageBox.Show("Must configure TOTP on this entry. Do you want to do this now?", "Not Configured", MessageBoxButtons.YesNo) == DialogResult.Yes) { ShowOneTimePasswords form = new ShowOneTimePasswords(entry, host); form.ShowDialog(); } } else { var data = OtpAuthData.FromString(entry.Strings.Get(OtpAuthData.StringDictionaryKey).ReadString()); var totp = new Totp(data.Key, step: data.Step, mode: data.OtpHashMode, totpSize: data.Size); var text = totp.ComputeTotp().ToString().PadLeft(data.Size, '0'); if (ClipboardUtil.CopyAndMinimize(new KeePassLib.Security.ProtectedString(true, text), true, this.host.MainWindow, entry, this.host.Database)) { this.host.MainWindow.StartClipboardCountdown(); } } } }
private void AddEdit() { this.timerUpdateTotp.Enabled = false; this.labelRemaining.Text = "x"; this.labelOtp.Text = "xxxxxx"; this.totp = null; var addEditForm = new OtpInformation(this.host); addEditForm.Data = this.data; var result = addEditForm.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK) { this.data = addEditForm.Data; // set the data entry.Strings.Set(OtpAuthData.StringDictionaryKey, new ProtectedString(true, this.data.EncodedString)); entry.Touch(true, false); // indicate that a change was made, must save host.MainWindow.UpdateUI(false, null, true, host.Database.RootGroup, true, null, true); this.ShowCode(); } else if (this.data == null) { this.Close(); } else { this.ShowCode(); } }
void SprEngine_FilterCompile(object sender, SprEventArgs e) { if ((e.Context.Flags & SprCompileFlags.ExtActive) == SprCompileFlags.ExtActive) { if (e.Text.IndexOf(totpPlaceHolder, StringComparison.InvariantCultureIgnoreCase) >= 0) { if (e.Context.Entry.Strings.Exists(OtpAuthData.StringDictionaryKey)) { var data = OtpAuthData.FromString(e.Context.Entry.Strings.Get(OtpAuthData.StringDictionaryKey).ReadString()); var totp = new Totp(data.Key, step: data.Step, mode: data.OtpHashMode, totpSize: data.Size); var text = totp.ComputeTotp().ToString().PadLeft(data.Size, '0'); e.Text = StrUtil.ReplaceCaseInsensitive(e.Text, "{TOTP}", text); } } } }
private void FormWasShown() { if (!entry.Strings.Exists(OtpAuthData.StringDictionaryKey)) { this.AddEdit(); } else { try { this.data = OtpAuthData.FromString(entry.Strings.Get(OtpAuthData.StringDictionaryKey).ReadString()); ShowCode(); } catch { this.AddEdit(); } } }
public static OtpAuthData FromString(string data) { NameValueCollection parameters = ParseQueryString(data); if (parameters[keyParameter] == null) { throw new ArgumentException("Must have a key in the data"); } var otpData = new OtpAuthData(); otpData.Key = ProtectedKey.CreateProtectedKeyAndDestroyPlaintextKey(Base32.Decode(parameters[keyParameter])); if (parameters[typeParameter] != null) { otpData.Type = (OtpType)Enum.Parse(typeof(OtpType), parameters[typeParameter]); } if (parameters[otpHashModeParameter] != null) { otpData.OtpHashMode = (OtpHashMode)Enum.Parse(typeof(OtpHashMode), parameters[otpHashModeParameter]); } if (otpData.Type == OtpType.Totp) { otpData.Step = GetIntOrDefault(parameters, stepParameter, 30); } else if (otpData.Type == OtpType.Hotp) { otpData.Counter = GetIntOrDefault(parameters, counterParameter, 0); } otpData.Size = GetIntOrDefault(parameters, sizeParameter, 6); return(otpData); }
private void OtpInformation_FormClosing(object sender, FormClosingEventArgs e) { if (this.DialogResult == System.Windows.Forms.DialogResult.Cancel) { return; } try { if (string.IsNullOrEmpty(this.textBoxKey.Text)) { MessageBox.Show("A key must be set"); e.Cancel = true; return; } if (this.textBoxKey.Text.Length < 8) { MessageBox.Show("Key must be at least 8 characters. If you are provided with less data then pad it up to 8 characters with '='s"); e.Cancel = true; return; } // set the default settings int size = 6; int step = 30; OtpHashMode hashMode = OtpHashMode.Sha1; Key key = null; if (this.checkBoxCustomSettings.Checked) { size = (this.radioButtonEight.Checked) ? 8 : 6; if (int.TryParse(this.textBoxStep.Text, out step)) { if (step != 30) { if (step <= 0) { this.textBoxStep.Text = "30"; MessageBox.Show("The time step must be a non-zero positive integer. The standard value is 30. If you weren't specifically given an alternate value just use 30."); e.Cancel = true; return; } else if (MessageBox.Show("You have selected a non-standard time step. 30 is the standard recommended value. You should only proceed if you were specifically told to use this time step size. Do you wish to proceed?", "Non-standard time step size", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No) { e.Cancel = true; return; } } } else { this.textBoxStep.Text = "30"; MessageBox.Show("The time step must be a non-zero positive integer. The standard value is 30. If you weren't specifically given an alternate value just use 30."); e.Cancel = true; return; } // need to do encoding here key = ProtectedKey.CreateProtectedKeyAndDestroyPlaintextKey(Base32.Decode(this.textBoxKey.Text.Replace(" ", string.Empty).Replace("-", string.Empty))); } else { key = ProtectedKey.CreateProtectedKeyAndDestroyPlaintextKey(Base32.Decode(this.textBoxKey.Text.Replace(" ", string.Empty).Replace("-", string.Empty))); } // hashmode if (this.radioButtonSha1.Checked) { hashMode = OtpHashMode.Sha1; } else if (this.radioButtonSha256.Checked) { hashMode = OtpHashMode.Sha256; } else if (this.radioButtonSha512.Checked) { hashMode = OtpHashMode.Sha512; } this.Data = new OtpAuthData() { Key = key, Size = size, Step = step, OtpHashMode = hashMode }; } catch { e.Cancel = true; } }