/// <summary>Filters the list of recipients by showing only those with a user ID or key fingerprint that contains at /// least one of the given keyword strings. If the keywords array is null or contains no keywords, /// all keys are shown. /// </summary> public void FilterItems(string[] keywords) { if(keys == null) throw new InvalidOperationException("ShowKeyring has not been called."); if(keywords == null || keywords.Length == 0 || keywords.Length == 1 && string.IsNullOrEmpty(keywords[0])) { AddKeyItems(keys); return; } List<PrimaryKey> keysToShow = new List<PrimaryKey>(); foreach(PrimaryKey key in keys) { foreach(string keyword in keywords) { if(PGPUI.KeyMatchesKeyword(key, keyword)) { keysToShow.Add(key); break; } } } AddKeyItems(keysToShow.ToArray()); }
void btnDelete_Click(object sender, EventArgs e) { if(userIds.SelectedItems.Count != 0) { if(!EnsureNotAllUserIdsSelected("delete")) return; // inform the user that deleting published user IDs is pointless, and get confirmation bool onlyOne = userIds.SelectedItems.Count == 1; string deleting = onlyOne ? "\""+userIds.SelectedItems[0].Text+"\"" : "multiple user IDs"; string userId = (onlyOne ? "this user ID" : "these user IDs"); string s = (onlyOne ? null : "s"), them = (onlyOne ? "it" : "them"), they = (onlyOne ? "it" : "they"); if(MessageBox.Show("You are about to delete " + deleting + "! Note that you cannot retract a user ID once it "+ "has been distributed, so if this key (with " + userId + ") has ever been given to another "+ "person or uploaded to a public key server, you should revoke the user ID" + s + " instead "+ "of deleting " + them + ", because " + they + " would only be deleted from your machine, "+ "and could reappear in the future.\n\nAre you sure you want to delete " + userId + "?", "Delete user IDs?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { PGPUI.DoWithErrorHandling("deleting a user ID", delegate { pgp.DeleteAttributes(GetSelectedAttributes()); }); ReloadKey(); } } }
void btnAddPhotoId_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "Image files (*.jpg;*.png;*.gif;*.bmp;*.tif;*.jpeg;*.tiff)|"+ "*.jpg;*.png;*.gif;*.bmp;*.tif;*.jpeg;*.tiff|All files (*.*)|*.*"; ofd.Title = "Select the image file for your photo ID"; ofd.SupportMultiDottedExtensions = true; if(ofd.ShowDialog() == DialogResult.OK) { NewPhotoIdForm form = new NewPhotoIdForm(); try { form.Initialize(ofd.FileName); } catch(Exception ex) { if(ex is System.IO.IOException || ex is System.ArgumentException) { MessageBox.Show("The selected file is not a valid image, or no longer exists.", "Not an image", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { throw ex; } } if(form.ShowDialog() == DialogResult.OK) { PGPUI.DoWithErrorHandling("adding the photo", delegate { pgp.AddPhoto(key, form.Bitmap, null); }); ReloadKey(); } } }
/// <summary>Initializes this form with the list of attributes to be revoked.</summary> public void Initialize(UserAttribute[] attrs) { if(attrs == null) throw new ArgumentNullException(); if(attrs.Length == 0) throw new ArgumentException("No attributes were given."); ids.Items.Clear(); foreach(UserAttribute attr in attrs) ids.Items.Add(PGPUI.GetAttributeName(attr)); }
void btnGenerate_Click(object sender, EventArgs e) { string realName = txtName.Text.Trim(), email = txtEmail.Text.Trim(), comment = txtComment.Text.Trim(); if(!PGPUI.ValidateUserId(realName, email, comment) || !PGPUI.ValidateAndCheckPasswords(txtPass1, txtPass2) || !ValidateKeyLength(keyType, keyLength, "primary key") || !ValidateKeyLength(subkeyType, subkeyLength, "subkey")) { return; } KeyTypeAndCapability primaryType = ((KeyTypeItem)keyType.SelectedItem).Value; NewKeyOptions options = new NewKeyOptions(); options.Comment = comment; options.Email = email; options.KeyCapabilities = primaryType.Capabilities; options.KeyExpiration = keyExpiration.Enabled ? keyExpiration.Value : (DateTime?)null; options.KeyLength = GetSelectedKeyLength(keyLength); options.Keyring = keyring; options.KeyType = primaryType.Type; options.Password = txtPass1.GetText(); options.RealName = realName; if(subkeyType.SelectedIndex == 0) { options.SubkeyType = KeyType.None; } else { KeyTypeAndCapability subType = ((KeyTypeItem)subkeyType.SelectedItem).Value; options.SubkeyCapabilities = subType.Capabilities; options.SubkeyExpiration = subkeyExpiration.Enabled ? subkeyExpiration.Value : (DateTime?)null; options.SubkeyLength = GetSelectedKeyLength(subkeyLength); options.SubkeyType = subType.Type; } // disable the UI controls while key generation is ongoing btnGenerate.Enabled = grpPrimary.Enabled = grpPassword.Enabled = grpSubkey.Enabled = grpUser.Enabled = false; btnCancel.Text = "&Cancel"; // turn the "Close" button into a "Cancel" button progressBar.Style = ProgressBarStyle.Marquee; // start up the "progress" bar // and start generating the key thread = new Thread(delegate() { try { PrimaryKey newKey = pgp.CreateKey(options); Invoke((ThreadStart)delegate { GenerationSucceeded(newKey); }); } catch(ThreadAbortException) { } catch(Exception ex) { Invoke((ThreadStart)delegate { GenerationFailed(ex); }); } }); thread.Start(); }
/// <summary>Creates a <see cref="PrimaryKeyItem"/> to represent the <see cref="PrimaryKey"/> from the search /// result. /// </summary> protected virtual PrimaryKeyItem CreateResultItem(PrimaryKey key) { PrimaryKeyItem item = new PrimaryKeyItem(key, PGPUI.GetKeyName(key)); item.SubItems.Add(key.CreationTime.ToShortDateString()); item.SubItems.Add(key.ShortKeyId); item.SubItems.Add(key.Revoked ? "Revoked" : key.Expired ? "Expired" : "Valid"); if(key.Revoked || key.Expired) item.ForeColor = SystemColors.GrayText; return item; }
/// <summary>Called when an import has finished, whether successfully or not.</summary> void ImportFinished(ImportedKey[] results) { TaskFinished(); if(results != null) { if(ImportCompleted != null) ImportCompleted(this, results); PGPUI.ShowImportResults(results); } }
void btnAddUserId_Click(object sender, EventArgs e) { UserIdForm form = new UserIdForm(); if(form.ShowDialog() == DialogResult.OK) { PGPUI.DoWithErrorHandling("adding the user ID", delegate { pgp.AddUserId(key, form.RealName, form.Email, form.Comment, form.Preferences); }); ReloadKey(); } }
/// <include file="documentation.xml" path="/UI/Common/OnKeyDown/*"/> protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); if(!e.Handled && PGPUI.IsCloseKey(e)) { Close(); e.Handled = true; } }
/// <include file="documentation.xml" path="/UI/Common/OnKeyDown/*"/> protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); if(!e.Handled && PGPUI.IsCloseKey(e)) // let the form be closed by pressing escape { Close(); e.Handled = true; } }
/// <summary>Initializes a new <see cref="KeyServerSearchForm"/> with the <see cref="PGPSystem"/> that will be used /// to search for keys. Keys selected by the user will be added to the given keyring. /// </summary> public KeyServerSearchForm(PGPSystem pgp, Keyring importKeyring) { InitializeComponent(); keyservers.Items.Clear(); keyservers.Items.AddRange(PGPUI.GetDefaultKeyServers()); keyservers.SelectedIndex = 0; this.pgp = pgp; this.keyring = importKeyring; }
/// <summary>Given two <see cref="SecureTextBox"/> controls containing passwords, checks that the passwords match. /// Message boxes will be displayed to the user if any problems are found with the passwords. True is returned if /// the passwords should be used, and false if not. /// </summary> public static bool ValidatePasswords(SecureTextBox pass1, SecureTextBox pass2) { if(!PGPUI.ArePasswordsEqual(pass1, pass2)) { MessageBox.Show("The passwords you have entered do not match.", "Password mismatch", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } return true; }
/// <summary>Initializes this form with the subkeys to revoke.</summary> public void Initialize(Subkey[] subkeys) { if(subkeys == null) throw new ArgumentNullException(); keyList.Items.Clear(); foreach(Subkey key in subkeys) keyList.Items.Add(PGPUI.GetKeyName(key)); btnOK.Enabled = rbDirect.Enabled = subkeys.Length != 0; if(rbDirect.Enabled) rbDirect.Checked = true; rbIndirect.Enabled = revokingKeys.Enabled = false; }
/// <summary>Initializes a new <see cref="KeyServerForm"/>.</summary> public KeyServerForm() { InitializeComponent(); keyservers.Items.AddRange(PGPUI.GetDefaultKeyServers()); keyservers.SelectedIndex = 0; // select the first keyserver by default // keep track of the margin around the help label so we can recreate it topSpace = lblHelp.Top; bottomSpace = Height - lblHelp.Bottom; horizontalSpace = lblHelp.Left; }
/// <summary>Called if a search fails with an exception.</summary> void SearchFailed(Exception ex) { bool throwError = !searchStartedFromUI; // save this because it'll be clobbered by SearchFinished SearchFinished(); if(!(ex is ThreadAbortException)) { if(throwError) throw ex; else PGPUI.ShowErrorDialog("searching", ex); } }
void btnRevoke_Click(object sender, EventArgs e) { if(subkeys.SelectedItems.Count != 0) { Subkey[] selectedKeys = GetSelectedKeys(); KeyRevocationForm form = new KeyRevocationForm(selectedKeys); if(form.ShowDialog() == DialogResult.OK) { PGPUI.DoWithErrorHandling("revoking a subkey", delegate { pgp.RevokeSubkeys(form.Reason, selectedKeys); }); ReloadKey(); } } }
void btnBrowse_Click(object sender, EventArgs e) { string defaultFilename = PGPUI.MakeSafeFilename("revoke " + PGPUI.GetKeyName(keyToRevoke) + ".txt"); SaveFileDialog sfd = new SaveFileDialog(); sfd.DefaultExt = ".txt"; sfd.FileName = defaultFilename; sfd.Filter = "Text Files (*.txt)|*.txt|ASCII Files (*.asc)|*.asc|All Files (*.*)|*.*"; sfd.OverwritePrompt = true; sfd.Title = "Save Revocation Certificate"; sfd.SupportMultiDottedExtensions = true; if(sfd.ShowDialog() == DialogResult.OK) txtFile.Text = sfd.FileName; }
void btnRevoke_Click(object sender, EventArgs e) { if(userIds.SelectedItems.Count != 0) { if(!EnsureNotAllUserIdsSelected("revoke")) return; UserAttribute[] attrs = GetSelectedAttributes(); UserRevocationForm form = new UserRevocationForm(attrs); if(form.ShowDialog() == DialogResult.OK) { PGPUI.DoWithErrorHandling("revoking a user ID", delegate { pgp.RevokeAttributes(form.Reason, attrs); }); ReloadKey(); } } }
/// <summary>Given a name, optional email address, and optional comment, determines whether they constitute a valid /// user ID. Message boxes may be displayed to the user if any problems are found with the user ID. True is returned /// if the values should be used, and false if not. /// </summary> public static bool ValidateUserId(string realName, string email, string comment) { if(string.IsNullOrEmpty(realName)) { MessageBox.Show("You must enter your name.", "Name required", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } else if(!string.IsNullOrEmpty(email) && !PGPUI.IsValidEmail(email)) { MessageBox.Show(email + " is not a valid email address.", "Invalid email", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } return true; }
/// <summary>Initializes this form with the given designated revoker key, and a list of keys owned by the user that /// can be selected to be revocable by the revoker key. /// </summary> public void Initialize(PrimaryKey revokerKey, PrimaryKey[] ownedKeys) { if(revokerKey == null || ownedKeys == null) throw new ArgumentNullException(); lblRevokingKey.Text = "You are making this key a designated revoker:\n" + PGPUI.GetKeyName(revokerKey); this.ownedKeys.Items.Clear(); foreach(PrimaryKey key in ownedKeys) { if(key == null) throw new ArgumentException("A key was null."); this.ownedKeys.Items.Add(new KeyItem(key)); } btnOK.Enabled = this.ownedKeys.Items.Count != 0; if(this.ownedKeys.Items.Count != 0) this.ownedKeys.SelectedIndex = 0; }
void btnAdd_Click(object sender, EventArgs e) { NewSubkeyForm form = new NewSubkeyForm(pgp); if(form.ShowDialog() == DialogResult.OK) { ProgressForm progress = new ProgressForm("Generating Subkey", "Please wait while the subkey is generated. This may take several minutes. Actively typing and performing "+ "disk-intensive operations can help speed up the process.", delegate { pgp.AddSubkey(key, form.KeyType, form.Capabilities, form.KeyLength, form.Expiration); }); if(progress.ShowDialog() == DialogResult.Abort && progress.Exception != null) { PGPUI.ShowErrorDialog("creating the subkey", progress.Exception); } ReloadKey(); } }
/// <include file="documentation.xml" path="/UI/ListBase/CreateSignatureItem/*"/> protected virtual KeySignatureItem CreateSignatureItem(KeySignature sig) { if(sig == null) throw new ArgumentNullException(); string name = string.IsNullOrEmpty(sig.SignerName) ? "(User ID not found)" : sig.SignerName; if(sig.Revocation && sig.SelfSignature) name += " (self revocation)"; else if(sig.SelfSignature) name += " (self signature)"; else if(sig.Revocation) name += " (revocation)"; KeySignatureItem item = new KeySignatureItem(sig, name); item.SubItems.Add(sig.ShortKeyId); item.SubItems.Add((sig.Exportable ? "Exportable " : "Local ") + PGPUI.GetSignatureDescription(sig.Type)); item.SubItems.Add(sig.Expired ? "Expired" : sig.IsValid ? "Valid" : sig.IsInvalid ? "Invalid" : sig.ErrorOccurred ? "Error" : "Unverified"); item.SubItems.Add(sig.CreationTime.ToShortDateString()); return item; }
/// <summary>Reloads the key and redisplays its attributes and user IDs.</summary> void ReloadKey() { if(key != null) { key = pgp.RefreshKey(key, ListOptions.RetrieveAttributes | ListOptions.RetrieveSecretKeys); if(key == null) { foreach(Control control in Controls) { if(control != lblDescription) control.Enabled = false; } lblDescription.Text = "The key you were editing no longer exists."; } else { userIds.Items.Clear(); foreach(UserId id in key.UserIds) { AttributeItem item = new AttributeItem(id, PGPUI.GetAttributeName(id)); if(id.Revoked) item.Text += " (revoked)"; item.ImageIndex = UserIdIcon; SetFont(item); userIds.Items.Add(item); } foreach(UserAttribute attr in key.Attributes) { bool isPhoto = attr is UserImage; AttributeItem item = new AttributeItem(attr, PGPUI.GetAttributeName(attr)); if(attr.Revoked) item.Text += " (revoked)"; item.ImageIndex = isPhoto ? PhotoIdIcon : UnknownIcon; SetFont(item); userIds.Items.Add(item); } } } }
/// <summary>Initializes this form with the given key pair.</summary> public void Initialize(PrimaryKey key) { if(key == null) throw new ArgumentNullException(); txtPrimaryId.Text = key.PrimaryUserId.Name; txtKeyId.Text = key.ShortKeyId + (key.KeyId.Length > 8 ? " (long ID: " + key.KeyId + ")" : null); txtKeyType.Text = (key.HasSecretKey ? "public key" : "public and secret key pair"); txtKeyValidity.Text = PGPUI.GetKeyValidityDescription(key); txtOwnerTrust.Text = PGPUI.GetTrustDescription(key.OwnerTrust); txtFingerprint.Text = key.Fingerprint; List<string> capabilities = new List<string>(); if(key.HasCapabilities(KeyCapabilities.Authenticate)) capabilities.Add("authenticate"); if(key.HasCapabilities(KeyCapabilities.Certify)) capabilities.Add("certify"); if(key.HasCapabilities(KeyCapabilities.Encrypt)) capabilities.Add("encrypt"); if(key.HasCapabilities(KeyCapabilities.Sign)) capabilities.Add("sign"); txtCapabilities.Text = capabilities.Count == 0 ? "none" : string.Join(", ", capabilities.ToArray()); keyList.Items.Clear(); keyList.AddKey(key); foreach(Subkey subkey in key.Subkeys) keyList.AddKey(subkey); }
void btnBrowse_Click(object sender, EventArgs e) { string suffix; if(options.GetItemChecked(0) && options.GetItemChecked(1)) suffix = "pub-sec"; else if(options.GetItemChecked(1)) suffix = "sec"; else suffix = "pub"; string ext = options.GetItemChecked(2) ? ".pgp" : ".txt"; string defaultFilename = PGPUI.MakeSafeFilename((keyList.Items.Count == 1 ? keyList.Items[0].ToString() : "Exported keys") + "." + suffix + ext); SaveFileDialog sfd = new SaveFileDialog(); sfd.DefaultExt = ".txt"; sfd.FileName = defaultFilename; sfd.Filter = "Text Files (*.txt)|*.txt|ASCII Files (*.asc)|*.asc|PGP Files (*.pgp)|*.pgp|All Files (*.*)|*.*"; sfd.FilterIndex = options.GetItemChecked(2) ? 3 : 1; sfd.OverwritePrompt = true; sfd.Title = "Save Exported Keys"; sfd.SupportMultiDottedExtensions = true; if(sfd.ShowDialog() == DialogResult.OK) txtFile.Text = sfd.FileName; }
void btnOK_Click(object sender, EventArgs e) { if(PGPUI.ValidateUserId(RealName, Email, Comment)) DialogResult = DialogResult.OK; }
/// <summary>Initializes this form with the public key whose signatures will be displayed.</summary> public void Initialize(PrimaryKey publicKey) { if(publicKey == null) throw new ArgumentNullException(); Text = lblDescription.Text = "Key Signatures for " + PGPUI.GetKeyName(publicKey); sigList.Initialize(publicKey); }
/// <summary>Given a <see cref="Key"/>, gets a string that describes the validity of a key.</summary> public static string GetKeyValidityDescription(Key key) { if(key == null) throw new ArgumentNullException(); return key.Revoked ? "revoked" : key.Expired ? "expired" : PGPUI.GetTrustDescription(key.CalculatedTrust); }
/// <summary>Creates the <see cref="PrimaryKeyItem"/> used to display the given key.</summary> protected virtual PrimaryKeyItem CreatePrimaryKeyItem(PrimaryKey key) { if(key == null) throw new ArgumentNullException(); return new PrimaryKeyItem(key, PGPUI.GetKeyName(key)); }
/// <summary>Initializes a new <see cref="KeyItem"/> with the given key.</summary> public KeyItem(PrimaryKey key) : base(key, PGPUI.GetKeyName(key)) { }