Merge with default Redesign_Ribbon
authorThomas
Tue, 22 May 2018 11:35:06 +0200
branchRedesign_Ribbon
changeset 2206d0173d827aa2
parent 2183 74999a6fa16a
parent 2204 94aaeb734ef2
child 2207 191d9997af5e
Merge with default
CryptableMailItem.cs
FPPMessage.cs
MsgProcessor.cs
PEPMessage.cs
PEPSettings.cs
Properties/Resources.Designer.cs
Properties/Resources.resx
ThisAddIn.cs
UI/FormControlPreviewMessage.xaml.cs
UI/HandshakeDialog.xaml.cs
UI/KeySyncWizard.xaml.cs
     1.1 --- a/CryptableMailItem.cs	Thu May 10 12:18:14 2018 +0200
     1.2 +++ b/CryptableMailItem.cs	Tue May 22 11:35:06 2018 +0200
     1.3 @@ -97,12 +97,6 @@
     1.4          public delegate void OriginallyEncryptedStatusUpdateHandler(object sender, EventArgs e);
     1.5          public event OriginallyEncryptedStatusUpdateHandler OriginallyEncryptedStatusUpdated;
     1.6  
     1.7 -        /// <summary>
     1.8 -        /// Event handler for when a sync message is being detected during decryption.
     1.9 -        /// </summary>
    1.10 -        public delegate void SyncMessageReceivedHandler(object sender, CryptableMailItem.SyncMessageEventArgs e);
    1.11 -        public static event SyncMessageReceivedHandler SyncMessageReceived;
    1.12 -
    1.13          private pEpRating            _LastProcessedRating;
    1.14          private Globals.ReturnStatus _LastProcessedStatus;
    1.15  
    1.16 @@ -1227,9 +1221,18 @@
    1.17                          // Wait for the other thread to finish
    1.18                          if (isAlreadyBeingDecrypted)
    1.19                          {
    1.20 -                            Log.Verbose("ProcessAndGetRating: Waiting for other decryption thread to finish. " + entryId);
    1.21 -                            Thread.Sleep(sleepTime);
    1.22 -                            curWaitTime += sleepTime;
    1.23 +                            // Do not process multiple times if it is an automatic message
    1.24 +                            if (this.internalMailItem.GetIsAutoConsume())
    1.25 +                            {
    1.26 +                                curWaitTime = maxWaitTime + 1;
    1.27 +                                Log.Verbose("ProcessAndGetRating: Setting timeout for AutoConsume message.");
    1.28 +                            }
    1.29 +                            else
    1.30 +                            {
    1.31 +                                Log.Verbose("ProcessAndGetRating: Waiting for other decryption thread to finish. " + entryId);
    1.32 +                                Thread.Sleep(sleepTime);
    1.33 +                                curWaitTime += sleepTime;
    1.34 +                            }
    1.35                          }
    1.36                      }
    1.37                      while ((isAlreadyBeingDecrypted) && (curWaitTime < maxWaitTime));
    1.38 @@ -1443,18 +1446,20 @@
    1.39                      // Process mail item
    1.40                      sts1 = PEPMessage.Create(this.internalMailItem, out message);
    1.41  
    1.42 -                    // Block while KeySyncWizard is open and Trustwords haven't been accepted
    1.43 -                    while ((KeySyncWizard.Wizard?.State == KeySyncWizard.WizardState.Step2) &&
    1.44 -                            (message.Direction == pEpMsgDirection.pEpDirIncoming) &&
    1.45 -                            (message.To?.Count == 1) &&
    1.46 -                            (message.From?.EqualsByAddress(message.To[0]) == true))
    1.47 +                    // If Key Import Wizard is open, add mail to list to process later
    1.48 +                    if ((KeySyncWizard.Wizard?.IsVisible == true) &&
    1.49 +                        (message.Direction == pEpMsgDirection.pEpDirIncoming) &&
    1.50 +                        (message.To?.Count == 1) &&
    1.51 +                        (message.From?.EqualsByAddress(message.To[0]) == true))
    1.52                      {
    1.53 -                        Log.Verbose("ProcessAndGetRating: KeySyncWizard in Step 2. Blocking decryption.");
    1.54 -                        Thread.Sleep(100);
    1.55 +                        KeySyncWizard.Wizard?.AddToReceivedSyncMessages(message);
    1.56                      }
    1.57  
    1.58 +                    // Define decryption flags
    1.59 +                    decryptionFlags = IsSecurelyStored ? pEpDecryptFlags.pEpDecryptFlagUntrustedServer : pEpDecryptFlags.pEpDecryptFlagsNone;
    1.60 +
    1.61                      // Process
    1.62 -                    status = msgProcessor.ProcessMessage(message,
    1.63 +                    status = msgProcessor.ProcessMessage(ref message,
    1.64                                                           sts1,
    1.65                                                           this.internalMailItem.GetIsInSecureStore(),
    1.66                                                           this.internalMailItem.GetIsInSentFolder(),
    1.67 @@ -1462,7 +1467,7 @@
    1.68                                                           out mirror,
    1.69                                                           out processedMessage,
    1.70                                                           out processedRating,
    1.71 -                                                         out decryptionFlags);
    1.72 +                                                         ref decryptionFlags);
    1.73  
    1.74                      if (status == Globals.ReturnStatus.Success)
    1.75                      {
    1.76 @@ -1491,9 +1496,6 @@
    1.77                          }
    1.78                          else
    1.79                          {
    1.80 -                            // Check for sync message
    1.81 -                            this.CheckForSyncMessage((processedRating == pEpRating.pEpRatingUnencrypted) ? message : processedMessage, decryptionFlags);
    1.82 -
    1.83                              // Save processed message data to Outlook
    1.84                              if (processedMessage != null)
    1.85                              {
    1.86 @@ -1519,6 +1521,22 @@
    1.87  
    1.88                                      mailItem = mirrorMailItem;
    1.89  
    1.90 +                                    /* If we have extra keys and are on an untrusted server, reencrypt message
    1.91 +                                     * for myself and the extra keys.
    1.92 +                                     */ 
    1.93 +                                    bool saveInternalMailItem = false;
    1.94 +                                    if (decryptionFlags.HasFlag(pEpDecryptFlags.pEpDecryptFlagSrcModified))
    1.95 +                                    {
    1.96 +                                        if (message.ApplyTo(this.internalMailItem, false, false, true, false) == Globals.ReturnStatus.Success)
    1.97 +                                        {
    1.98 +                                            saveInternalMailItem = true;
    1.99 +                                        }
   1.100 +                                        else
   1.101 +                                        {
   1.102 +                                            Log.Error("ProcessAndGetRating: Error reencrypting with extra keys.");
   1.103 +                                        }
   1.104 +                                    }
   1.105 +
   1.106                                      /* OUT - 283 Remove attachment icon for messages on untrusted servers 
   1.107                                       * in case decrypted mail has no attachments.
   1.108                                       * This is needed for all Exchange stores and IMAP stores on Outlook 2010.
   1.109 @@ -1546,7 +1564,7 @@
   1.110                                                  attachment = null;
   1.111                                              }
   1.112  
   1.113 -                                            this.internalMailItem.Save();
   1.114 +                                            saveInternalMailItem = true;
   1.115                                          }
   1.116                                          catch (Exception ex)
   1.117                                          {
   1.118 @@ -1558,6 +1576,19 @@
   1.119                                              attachment = null;
   1.120                                          }
   1.121                                      }
   1.122 +
   1.123 +                                    // Save mail item again if needed
   1.124 +                                    if (saveInternalMailItem)
   1.125 +                                    {
   1.126 +                                        try
   1.127 +                                        {
   1.128 +                                            this.internalMailItem.Save();
   1.129 +                                        }
   1.130 +                                        catch (Exception ex)
   1.131 +                                        {
   1.132 +                                            Log.Error("ProcessAndGetRating: Error saving internal mail item. " + ex.ToString());
   1.133 +                                        }
   1.134 +                                    }
   1.135                                  }
   1.136                                  else
   1.137                                  {
   1.138 @@ -1839,85 +1870,6 @@
   1.139           *************************************************************/
   1.140  
   1.141          /// <summary>
   1.142 -        /// Checks if the key sync wizard is open or the message is a sync message.
   1.143 -        /// If this is true, the message will get processed further, either raising
   1.144 -        /// the respective event or opening the wizard.
   1.145 -        /// </summary>
   1.146 -        /// <param name="message">The message to check.</param>
   1.147 -        /// <param name="flags">The decrypt flags.</param>
   1.148 -        private void CheckForSyncMessage(PEPMessage message, pEpDecryptFlags flags)
   1.149 -        {
   1.150 -            try
   1.151 -            {
   1.152 -                /* To determine whether the processed message is a sync message:
   1.153 -                 * 1. Is incoming (do not process sent messages)
   1.154 -                 * 2. Has the KeyImport header (in case of pEp sync) and the header is not
   1.155 -                 *    the own fingerprint.
   1.156 -                 * - or -
   1.157 -                 * 3. a. The WizardType is PGP
   1.158 -                 *    b. The message has one To recipient that is also the From recipient
   1.159 -                 *    c. The From recipient is an own identity (seems actually unnecessary)
   1.160 -                 */
   1.161 -                if ((KeySyncWizard.Wizard?.Type == KeySyncWizard.WizardType.PGP) ||
   1.162 -                    (message?.KeyImport?.Equals(KeySyncWizard.Wizard?.Myself?.Fingerprint) == false))
   1.163 -                {
   1.164 -                    if ((message.To.Count == 1) &&
   1.165 -                        (message.To[0].EqualsByAddress(message.From)) &&
   1.166 -                        (PEPIdentity.GetIsOwnIdentity(message.From.Address)))
   1.167 -                    {
   1.168 -                        Log.Verbose("CheckForSyncMessage: Sync message found.");
   1.169 -
   1.170 -                        if ((KeySyncWizard.Wizard?.Type != KeySyncWizard.WizardType.PGP) &&
   1.171 -                            (KeySyncWizard.Wizard?.IsVisible == false) &&
   1.172 -                            (message.Rating < pEpRating.pEpRatingTrusted))
   1.173 -                        {
   1.174 -                            Log.Verbose("CheckForSyncMessage: Wizard not open yet.");
   1.175 -
   1.176 -                            // Get own identity
   1.177 -                            PEPIdentity myself = null;
   1.178 -                            try
   1.179 -                            {
   1.180 -                                pEpIdentity _myself = message.To[0].ToCOMType();
   1.181 -                                myself = new PEPIdentity(ThisAddIn.PEPEngine.Myself(_myself));
   1.182 -                            }
   1.183 -                            catch (Exception ex)
   1.184 -                            {
   1.185 -                                myself = null;
   1.186 -                                Log.Verbose("CheckForSyncMessage: Error getting own identity. " + ex.ToString());
   1.187 -                            }
   1.188 -
   1.189 -                            // Only open if not sent to myself. Check again if not open
   1.190 -                            if ((myself?.Fingerprint?.Equals(message?.KeyImport) == false) &&
   1.191 -                                (KeySyncWizard.Wizard?.IsVisible == false))
   1.192 -                            {
   1.193 -                                // Marshall to main thread and create new wizard
   1.194 -                                KeySyncWizard.Wizard?.Dispatcher?.Invoke(new Action(() =>
   1.195 -                                {
   1.196 -                                    KeySyncWizard.Wizard = new KeySyncWizard(KeySyncWizard.WizardType.pEp, false, message.To[0], message.KeyImport);
   1.197 -                                    KeySyncWizard.Wizard.Show();
   1.198 -                                    Log.Verbose("CheckForSyncMessage: Wizard opened.");
   1.199 -                                }));
   1.200 -                            }
   1.201 -                        }
   1.202 -                        else
   1.203 -                        {
   1.204 -                            Log.Verbose("CheckForSyncMessage: Wizard already open or message rating is trusted. Invoking sync message received event.");
   1.205 -                            CryptableMailItem.SyncMessageReceived?.Invoke(this, new SyncMessageEventArgs(message, flags));
   1.206 -                        }
   1.207 -                    }
   1.208 -                    else
   1.209 -                    {
   1.210 -                        Log.Warning("CheckForSyncMessage: PGP Wizard open or message with KeyImport header, but message doesn't meet formal criteria.");
   1.211 -                    }
   1.212 -                }
   1.213 -            }
   1.214 -            catch (Exception ex)
   1.215 -            {
   1.216 -                Log.Error("CheckForSyncMessage: Error detecting if sync message. " + ex.ToString());
   1.217 -            }
   1.218 -        }
   1.219 -
   1.220 -        /// <summary>
   1.221          /// Releases all resources and disconnects internal events.
   1.222          /// The internal mail item will NOT be released -- this is managed externally.
   1.223          /// </summary>
   1.224 @@ -2168,27 +2120,6 @@
   1.225          }
   1.226  
   1.227          /// <summary>
   1.228 -        /// Class used to store the arguments in the SyncMessageReceived event.
   1.229 -        /// </summary>
   1.230 -        internal class SyncMessageEventArgs : EventArgs
   1.231 -        {
   1.232 -            public PEPMessage Message = null;
   1.233 -            public pEpDecryptFlags Flags = pEpDecryptFlags.pEpDecryptFlagsNone;
   1.234 -
   1.235 -            /// <summary>
   1.236 -            /// Constructs a new SyncMessageEventArgs with the given arguments.
   1.237 -            /// </summary>
   1.238 -            /// <param name="message">The message that has been received.</param>
   1.239 -            /// <param name="flags">The decryption flags of the received message.</param>
   1.240 -            public SyncMessageEventArgs(PEPMessage message,
   1.241 -                                        pEpDecryptFlags flags)
   1.242 -            {
   1.243 -                this.Message = message;
   1.244 -                this.Flags = flags;
   1.245 -            }
   1.246 -        }
   1.247 -
   1.248 -        /// <summary>
   1.249          /// Class used to store an entry in the encrypted conversation cache.
   1.250          /// This will identify the original parent encrypted mail item.
   1.251          /// </summary>
     2.1 --- a/FPPMessage.cs	Thu May 10 12:18:14 2018 +0200
     2.2 +++ b/FPPMessage.cs	Tue May 22 11:35:06 2018 +0200
     2.3 @@ -20,13 +20,24 @@
     2.4      {       
     2.5          public const string PEP_FPP_MESSAGE_BODY_PLAIN                  = "This message is protected by p≡p. \n\nTo read this message, you can either download the free p≡p Reader here: " +
     2.6                                                                            Globals.PEP_WEBSITE_READER_LINK + " \n\nTo read and send protected messages yourself, you can get your copy of p≡p here: " +
     2.7 -                                                                          Globals.PEP_WEBSITE_UPGRADE_LINK;
     2.8 +                                                                          Globals.PEP_WEBSITE_UPGRADE_LINK +
     2.9 +                                                                          "\n\nThis message can only be opened with p≡p for Outlook or p≡p Reader for Outlook.";
    2.10          public const string PEP_FPP_MESSAGE_BODY_HTML                   = "This message is protected by <a style=\"color:#03AA4B; text-decoration: none\" href=\"" + Globals.PEP_WEBSITE_LINK + "\">p≡p</a>. <br><br>To read this message, you can either download the free " +
    2.11                                                                            "<a style=\"color:#03AA4B; text-decoration: none\" href=\"" + Globals.PEP_WEBSITE_READER_LINK + "\">p≡p Reader</a> or, " +
    2.12                                                                            "to read and send protected messages yourself, you can get your copy of <a style=\"color:#03AA4B; text-decoration: none\" href=\"" +
    2.13 -                                                                          Globals.PEP_WEBSITE_UPGRADE_LINK + "\">p≡p here</a>.";
    2.14 -        public const string PEP_FPP_MESSAGE_BODY_PLAIN_PEP_INSTALLED    = "This message is protected by p≡p. \n\nTo read this message please click the Privacy Status button and follow the instructions.";
    2.15 -        public const string PEP_FPP_MESSAGE_BODY_HTML_PEP_INSTALLED     = "This message is protected by <a style=\"color:#03AA4B; text-decoration: none\" href=\"" + Globals.PEP_WEBSITE_LINK + "\">p≡p</a>. <br><br>To read this message please click the Privacy Status button and follow the instructions.";
    2.16 +                                                                          Globals.PEP_WEBSITE_UPGRADE_LINK + "\">p≡p here</a>." +
    2.17 +                                                                          "<br><br>This message can only be opened with p≡p for Outlook or p≡p Reader for Outlook.";
    2.18 +        public const string PEP_FPP_MESSAGE_BODY_PLAIN_PEP_INSTALLED    = "This message is protected by p≡p. \n\nTo read this message please do the following:" +
    2.19 +                                                                          "\n\n1. Click the Privacy Status button on the bottom of this message to open the Handshake dialog." +
    2.20 +                                                                          "\n2. Shortly after you opened the Handshake dialog on your computer, the same dialog will show up on the screen of the sender of the message as well (depending on the setup it might take 2-3 minutes). Contact the sender through another communication channel (e.g.phone call)." +
    2.21 +                                                                          "\n3. Compare the Trustwords with your communication partner. If the Trustwords match, confirm the Trustwords by clicking the green button." +
    2.22 +                                                                          "\n4. Shortly after, the protected message will automatically decrypt and you can read the message.";
    2.23 +        public const string PEP_FPP_MESSAGE_BODY_HTML_PEP_INSTALLED     = "<!DOCTYPE html><html><head><meta http-equiv='Content-Type' content='text/html;charset=UTF-8'></head><body>" +
    2.24 +                                                                          "This message is protected by <a style=\"color:#03AA4B; text-decoration: none\" href=\"" + Globals.PEP_WEBSITE_LINK + "\">p≡p</a>. <br><br>To read this message please do the following:" +
    2.25 +                                                                          "<br><br>1. Click the Privacy Status button on the bottom of this message to open the Handshake dialog." +
    2.26 +                                                                          "<br>2. Shortly after you opened the Handshake dialog on your computer, the same dialog will show up on the screen of the sender of the message as well (depending on the setup it might take 2-3 minutes). Contact the sender through another communication channel (e.g.phone call)." +
    2.27 +                                                                          "<br>3. Compare the Trustwords with your communication partner. If the Trustwords match, confirm the Trustwords by clicking the green button." +
    2.28 +                                                                          "<br>4. Shortly after, the protected message will automatically decrypt and you can read the message.</body></html>";
    2.29          public const string PEP_FPP_ATTACHMENT_FILE_NAME                = "ignore_this_attachment.pEp";
    2.30          public const string PEP_FPP_ATTACHMENT_MIME_TYPE                = "application/pEp.forceProtected";
    2.31  
    2.32 @@ -190,11 +201,12 @@
    2.33                  PEPMessage processedMessage;
    2.34                  pEpRating processedRating;
    2.35                  string[] keyList;
    2.36 -                pEpDecryptFlags flags;
    2.37 +                pEpDecryptFlags flags = pEpDecryptFlags.pEpDecryptFlagsNone;
    2.38  
    2.39                  // Decrypt incoming message
    2.40                  MsgProcessor msgProcessor = new MsgProcessor();
    2.41 -                if (msgProcessor.Decrypt(this.CurrentMessage, out processedMessage, out keyList, out flags, out processedRating) == false)
    2.42 +                PEPMessage message = this.CurrentMessage;
    2.43 +                if (msgProcessor.Decrypt(ref message, out processedMessage, out keyList, ref flags, out processedRating) == false)
    2.44                  {
    2.45                      Log.Error("FPPMessage.ProcessIncoming: Error decrypting incoming message.");
    2.46                      return Globals.ReturnStatus.Failure;
    2.47 @@ -222,6 +234,12 @@
    2.48                  else
    2.49                  {
    2.50                      Log.Error("FPPMessage.ProcessIncoming: Task result is failure.");
    2.51 +
    2.52 +                    // Decrement decryption counter if necessary
    2.53 +                    if (manuallyTriggered == false)
    2.54 +                    {
    2.55 +                        ThisAddIn.DecryptionStack.DecrementDecryptionCounter();
    2.56 +                    }
    2.57                  }
    2.58              }, TaskScheduler.FromCurrentSynchronizationContext());
    2.59  
     3.1 --- a/MsgProcessor.cs	Thu May 10 12:18:14 2018 +0200
     3.2 +++ b/MsgProcessor.cs	Tue May 22 11:35:06 2018 +0200
     3.3 @@ -14,14 +14,12 @@
     3.4      /// <summary>
     3.5      /// Class containing processing methods for PEPMessages.
     3.6      /// </summary>
     3.7 -    internal class MsgProcessor : IDisposable
     3.8 +    internal class MsgProcessor
     3.9      {
    3.10 -        public delegate void ProcessingCompletedHandler(object sender, ProcessingCompletedEventArgs e);
    3.11 -
    3.12          /// <summary>
    3.13          /// Event when processing is completed.
    3.14 -        /// WARNING: The calling thread is a background worker.
    3.15          /// </summary>
    3.16 +        public delegate void ProcessingCompletedHandler(object sender, ProcessingCompletedEventArgs e);
    3.17          public event ProcessingCompletedHandler ProcessingCompleted;
    3.18  
    3.19          /// <summary>
    3.20 @@ -58,13 +56,6 @@
    3.21          {           
    3.22          }
    3.23  
    3.24 -        /// <summary>
    3.25 -        /// Implementing IDisposable
    3.26 -        /// </summary>
    3.27 -        public void Dispose()
    3.28 -        {           
    3.29 -        }
    3.30 -
    3.31          /**************************************************************
    3.32           * 
    3.33           * Methods
    3.34 @@ -173,17 +164,20 @@
    3.35                  }
    3.36                  else
    3.37                  {
    3.38 -                    // Block while KeySyncWizard is open and Trustwords haven't been accepted
    3.39 -                    while ((KeySyncWizard.Wizard?.State == KeySyncWizard.WizardState.Step2) &&
    3.40 -                            (msgContainer?.Message?.Direction == pEpMsgDirection.pEpDirIncoming) &&
    3.41 -                            (msgContainer?.Message?.To?.Count == 1) &&
    3.42 -                            (msgContainer?.Message?.From?.EqualsByAddress(msgContainer.Message.To[0]) == true))
    3.43 +                    // If Key Import Wizard is open, add mail to list to process later
    3.44 +                    if ((KeySyncWizard.Wizard?.IsVisible == true) &&
    3.45 +                        (msgContainer?.Message?.Direction == pEpMsgDirection.pEpDirIncoming) &&
    3.46 +                        (msgContainer?.Message?.To?.Count == 1) &&
    3.47 +                        (msgContainer?.Message?.From?.EqualsByAddress(msgContainer?.Message?.To[0]) == true))
    3.48                      {
    3.49 -                        Log.Verbose("Process: KeySyncWizard in Step 2. Blocking decryption.");
    3.50 -                        Thread.Sleep(100);
    3.51 +                        KeySyncWizard.Wizard?.AddToReceivedSyncMessages(msgContainer?.Message);
    3.52                      }
    3.53  
    3.54 -                    sts = this.ProcessMessage(msgContainer.Message,
    3.55 +                    // Define decryption flags
    3.56 +                    decryptionFlags = msgContainer.IsInSecureStore ? pEpDecryptFlags.pEpDecryptFlagUntrustedServer : pEpDecryptFlags.pEpDecryptFlagsNone;
    3.57 +                    PEPMessage message = msgContainer.Message;
    3.58 +
    3.59 +                    sts = this.ProcessMessage(ref message,
    3.60                                                msgContainer.MessageCreationStatus,
    3.61                                                msgContainer.IsInSecureStore,
    3.62                                                msgContainer.IsInSentFolder,
    3.63 @@ -191,7 +185,7 @@
    3.64                                                out mirrorMessage,
    3.65                                                out processedMessage,
    3.66                                                out processedRating,
    3.67 -                                              out decryptionFlags);
    3.68 +                                              ref decryptionFlags);
    3.69  
    3.70                      if ((decryptionFlags == pEpDecryptFlags.pEpDecryptFlagConsume) ||
    3.71                          (decryptionFlags == pEpDecryptFlags.pEpDecryptFlagIgnore))
    3.72 @@ -202,7 +196,7 @@
    3.73                      else
    3.74                      {
    3.75                          processedMessageContainer.DecryptionFlags = decryptionFlags;
    3.76 -                        processedMessageContainer.Message = processedMessage;
    3.77 +                        processedMessageContainer.Message = (decryptionFlags.HasFlag(pEpDecryptFlags.pEpDecryptFlagSrcModified)) ? message : processedMessage;
    3.78  
    3.79                          if (processedMessage != null)
    3.80                          {
    3.81 @@ -273,9 +267,6 @@
    3.82                      // Complete message processing
    3.83                      if (msgContainer.Error == null)
    3.84                      {
    3.85 -                        // Check for sync messages
    3.86 -                        this.CheckForSyncMessage(msgContainer.Message, msgContainer.DecryptionFlags);
    3.87 -
    3.88                          // If Force Protection Message, process accordingly
    3.89                          if (string.IsNullOrEmpty(msgContainer.Message?.ForceProtectionId) == false)
    3.90                          {
    3.91 @@ -405,7 +396,7 @@
    3.92          /// </summary>
    3.93          /// <param name="message">The message to check.</param>
    3.94          /// <param name="flags">The decrypt flags.</param>
    3.95 -        private void CheckForSyncMessage(PEPMessage message, pEpDecryptFlags flags)
    3.96 +        private void CheckForSyncMessage(PEPMessage message, ref pEpDecryptFlags flags)
    3.97          {
    3.98              try
    3.99              {
   3.100 @@ -464,6 +455,14 @@
   3.101                              Log.Verbose("CheckForSyncMessage: Wizard already open or message rating is trusted. Invoking sync message received event.");
   3.102                              MsgProcessor.SyncMessageReceived?.Invoke(this, new SyncMessageEventArgs(message, flags));
   3.103                          }
   3.104 +
   3.105 +                        // Delete message if necessary
   3.106 +                        if ((KeySyncWizard.Wizard?.Type == KeySyncWizard.WizardType.pEp) &&
   3.107 +                            (string.IsNullOrEmpty(message?.KeyImport) == false) &&
   3.108 +                            (KeySyncWizard.Wizard?.Myself?.Fingerprint?.Equals(message?.KeyImport) == false))
   3.109 +                        {
   3.110 +                            flags |= pEpDecryptFlags.pEpDecryptFlagConsume;
   3.111 +                        }
   3.112                      }
   3.113                      else
   3.114                      {
   3.115 @@ -477,7 +476,6 @@
   3.116              }
   3.117          }
   3.118  
   3.119 -
   3.120          /// <summary>
   3.121          /// Processes the given message including any decryption where necessary.
   3.122          /// This will then return the latest pEp rating for the message.
   3.123 @@ -509,7 +507,8 @@
   3.124          ///         |     |      |-- Sent folder        => No decryption needed 
   3.125          ///         |     |      |-- Not in Sent folder => Decrypt for message flags
   3.126          /// 
   3.127 -        /// <param name="message">The original message to process.</param>
   3.128 +        /// <param name="message">The original message to process. Can be returned modified (reencrypted). This will be
   3.129 +        /// signalled by the pEpDecryptFlagSrcModified flag.</param>
   3.130          /// <param name="messageCreationStatus">The return status after creating the message.</param>
   3.131          /// <param name="mirror">The existing mirror for the original message (if any).</param>
   3.132          /// <param name="isInSecureStore">Whether the message being processed is in a secure (untrusted) store.</param>
   3.133 @@ -520,9 +519,9 @@
   3.134          /// <param name="outProcessedMessage">The processed message. This will contain any updated data for either 
   3.135          /// the original message or the mirror. Use the 'outIsMirror' pararameter to determine which.</param>
   3.136          /// <param name="outProcessedRating">The processed rating of the message.</param>
   3.137 -        /// <param name="outDecryptionFlags">The output flags after decrypting the message (if it was decrypted).</param>
   3.138 +        /// <param name="decryptionFlags">The output flags after decrypting the message (if it was decrypted).</param>
   3.139          /// <returns>The status of the method.</returns>
   3.140 -        public Globals.ReturnStatus ProcessMessage(PEPMessage message,
   3.141 +        public Globals.ReturnStatus ProcessMessage(ref PEPMessage message,
   3.142                                                     Globals.ReturnStatus messageCreationStatus,
   3.143                                                     bool isInSecureStore,
   3.144                                                     bool isInSentFolder,
   3.145 @@ -530,12 +529,11 @@
   3.146                                                     out PEPMessage outMirror,
   3.147                                                     out PEPMessage outProcessedMessage,
   3.148                                                     out pEpRating outProcessedRating,
   3.149 -                                                   out pEpDecryptFlags outDecryptionFlags)
   3.150 +                                                   ref pEpDecryptFlags decryptionFlags)
   3.151          {
   3.152              bool success = true;
   3.153              bool sentItem = false;
   3.154              string[] decryptionKeyList;
   3.155 -            pEpDecryptFlags decryptionFlags = pEpDecryptFlags.pEpDecryptFlagsNone;
   3.156              PEPMessage processedMessage = null;
   3.157              PEPMessage mirror = null;
   3.158              pEpRating processedRating = pEpRating.pEpRatingUndefined;
   3.159 @@ -569,10 +567,10 @@
   3.160                                  Log.Verbose("ProcessMessage: Secure message");
   3.161  
   3.162                                  // Decrypt message
   3.163 -                                success = this.Decrypt(message,
   3.164 +                                success = this.Decrypt(ref message,
   3.165                                                         out processedMessage,
   3.166                                                         out decryptionKeyList,
   3.167 -                                                       out decryptionFlags,
   3.168 +                                                       ref decryptionFlags,
   3.169                                                         out decryptionRating);
   3.170  
   3.171                                  if (success == false)
   3.172 @@ -607,10 +605,10 @@
   3.173                                  Log.Verbose("ProcessMessage: In secure store or never unprotected");
   3.174  
   3.175                                  // Decrypt message
   3.176 -                                success = this.Decrypt(message,
   3.177 +                                success = this.Decrypt(ref message,
   3.178                                                         out processedMessage,
   3.179                                                         out decryptionKeyList,
   3.180 -                                                       out decryptionFlags,
   3.181 +                                                       ref decryptionFlags,
   3.182                                                         out decryptionRating);
   3.183  
   3.184                                  if (success)
   3.185 @@ -632,10 +630,10 @@
   3.186                                  Log.Verbose("ProcessMessage: Unsecure (trusted) store");
   3.187  
   3.188                                  // Decrypt message
   3.189 -                                success = this.Decrypt(message,
   3.190 +                                success = this.Decrypt(ref message,
   3.191                                                         out processedMessage,
   3.192                                                         out decryptionKeyList,
   3.193 -                                                       out decryptionFlags,
   3.194 +                                                       ref decryptionFlags,
   3.195                                                         out decryptionRating);
   3.196  
   3.197                                  if (success)
   3.198 @@ -673,10 +671,10 @@
   3.199                                   * The processed message itself can be ignored.
   3.200                                  */
   3.201                                  PEPMessage outMessage;
   3.202 -                                this.Decrypt(message,
   3.203 +                                this.Decrypt(ref message,
   3.204                                               out outMessage,
   3.205                                               out decryptionKeyList,
   3.206 -                                             out decryptionFlags);
   3.207 +                                             ref decryptionFlags);
   3.208                              }
   3.209  
   3.210                              /* Check all unsecure messages that are not sent to myself
   3.211 @@ -684,7 +682,7 @@
   3.212                               * Although this is also done in the engine during decryption,
   3.213                               * it seems safer to only apply the round-trip Outlook mail item
   3.214                               * => PEPMessage => Outlook mail item if really needed.
   3.215 -                                 */
   3.216 +                             */
   3.217                              bool keyFound = false;
   3.218                              bool sentToMyself = false;
   3.219  
   3.220 @@ -745,7 +743,6 @@
   3.221              outMirror = mirror;
   3.222              outProcessedMessage = processedMessage;
   3.223              outProcessedRating = processedRating;
   3.224 -            outDecryptionFlags = decryptionFlags;
   3.225  
   3.226              return status;
   3.227          }
   3.228 @@ -840,14 +837,6 @@
   3.229  
   3.230              Log.Verbose("ProcessSentMessage: Started");
   3.231  
   3.232 -            // Check if we have an extra key for sync messages and add it
   3.233 -            if (string.IsNullOrEmpty(KeySyncWizard.Wizard?.Partner?.Fingerprint) == false)
   3.234 -            {
   3.235 -                List<string> eKeys = extraKeys?.ToList<string>() ?? new List<string>();
   3.236 -                eKeys.Add(KeySyncWizard.Wizard.Partner.Fingerprint);
   3.237 -                extraKeys = eKeys.ToArray<string>();
   3.238 -            }
   3.239 -
   3.240              // Force the working message to outgoing direction.
   3.241              // This protects mostly for outgoing rating calculation which requires it.
   3.242              // However, if the message is ever incoming direction here, a failure occured elsewhere.
   3.243 @@ -1214,6 +1203,19 @@
   3.244  
   3.245          /// <summary>
   3.246          /// Decrypts the given pEp message.
   3.247 +        /// This is a wrapper for special cases where we don't need the actual result.
   3.248 +        /// </summary>
   3.249 +        /// <param name="sourceMessage">The message to decrypt.</param>
   3.250 +        /// <returns>True if decryption was considered successful, otherwise false.</returns>
   3.251 +        public bool Decrypt(PEPMessage sourceMessage)
   3.252 +        {
   3.253 +            PEPMessage outMessage;
   3.254 +
   3.255 +            return this.Decrypt(sourceMessage, out outMessage);
   3.256 +        }
   3.257 +
   3.258 +        /// <summary>
   3.259 +        /// Decrypts the given pEp message.
   3.260          /// This is a wrapper for special cases where we don't need to take care of
   3.261          /// rating, key list or flags.
   3.262          /// </summary>
   3.263 @@ -1224,10 +1226,10 @@
   3.264                              out PEPMessage decryptedMessage)
   3.265          {
   3.266              string[] keyList;
   3.267 -            pEpDecryptFlags flags;
   3.268 +            pEpDecryptFlags flags = pEpDecryptFlags.pEpDecryptFlagsNone;
   3.269              pEpRating rating;
   3.270  
   3.271 -            return this.Decrypt(sourceMessage, out decryptedMessage, out keyList, out flags, out rating);
   3.272 +            return this.Decrypt(ref sourceMessage, out decryptedMessage, out keyList, ref flags, out rating);
   3.273          }
   3.274  
   3.275          /// <summary>
   3.276 @@ -1240,13 +1242,13 @@
   3.277          /// <param name="flags">Decryption flags by the engine.</param>
   3.278          /// <param name="rating">The output pEp rating after decryption.</param>
   3.279          /// <returns>True if decryption was considered successful, otherwise false.</returns>
   3.280 -        public bool Decrypt(PEPMessage sourceMessage,
   3.281 +        public bool Decrypt(ref PEPMessage sourceMessage,
   3.282                              out PEPMessage destMessage,
   3.283                              out string[] keyList,
   3.284 -                            out pEpDecryptFlags flags,
   3.285 +                            ref pEpDecryptFlags flags,
   3.286                              out pEpRating rating)
   3.287          {
   3.288 -            rating = this.Decrypt(sourceMessage, out destMessage, out keyList, out flags);
   3.289 +            rating = this.Decrypt(ref sourceMessage, out destMessage, out keyList, ref flags);
   3.290  
   3.291              if ((rating == pEpRating.pEpRatingB0rken) ||
   3.292                  (rating == pEpRating.pEpRatingUndefined) ||
   3.293 @@ -1269,18 +1271,17 @@
   3.294          /// <param name="keyList">The output keylist used to decrypt.</param>
   3.295          /// <param name="flags">Decryption flags by the engine.</param>
   3.296          /// <returns>The pEp rating after decryption.</returns>
   3.297 -        public pEpRating Decrypt(PEPMessage sourceMessage,
   3.298 +        public pEpRating Decrypt(ref PEPMessage sourceMessage,
   3.299                                   out PEPMessage destMessage,
   3.300                                   out string[] keyList,
   3.301 -                                 out pEpDecryptFlags flags)
   3.302 +                                 ref pEpDecryptFlags flags)
   3.303          {
   3.304              bool success = false;
   3.305 -            TextMessage src;
   3.306 +            TextMessage src = new TextMessage();
   3.307              TextMessage dst = new TextMessage();
   3.308              string[] dstKeyList = Globals.ThisAddIn.Settings.ExtraKeys ?? new string[0];
   3.309              pEpRating rating = pEpRating.pEpRatingCannotDecrypt;
   3.310              Globals.ReturnStatus sts;
   3.311 -            flags = pEpDecryptFlags.pEpDecryptFlagsNone;
   3.312  
   3.313              Log.Verbose("Decrypt started.");
   3.314              Log.SensitiveData("Decrypt: Decrypting " + sourceMessage?.Id);
   3.315 @@ -1291,7 +1292,7 @@
   3.316                  try
   3.317                  {
   3.318                      src = sourceMessage.ToCOMType();
   3.319 -                    rating = ThisAddIn.PEPEngine.DecryptMessage(src, out dst, ref dstKeyList, ref flags);
   3.320 +                    rating = ThisAddIn.PEPEngine.DecryptMessage(ref src, out dst, ref dstKeyList, ref flags);
   3.321                      success = true;
   3.322                  }
   3.323                  catch (COMException ex)
   3.324 @@ -1316,12 +1317,24 @@
   3.325                  // Copy over lost properties
   3.326                  destMessage.SetNonEnginePropertiesFrom(sourceMessage);
   3.327                  keyList = dstKeyList;
   3.328 +
   3.329 +                // Replace original if needed
   3.330 +                if (flags.HasFlag(pEpDecryptFlags.pEpDecryptFlagSrcModified))
   3.331 +                {
   3.332 +                    PEPMessage reencryptedMessage;
   3.333 +                    sts = PEPMessage.Create(src, out reencryptedMessage);
   3.334 +                    reencryptedMessage.SetNonEnginePropertiesFrom(sourceMessage);
   3.335 +                    sourceMessage = reencryptedMessage;
   3.336 +                }
   3.337              }
   3.338              else
   3.339              {
   3.340                  destMessage = null;
   3.341                  keyList = new string[0];
   3.342 -            }            
   3.343 +            }
   3.344 +
   3.345 +            // Check for sync message
   3.346 +            this.CheckForSyncMessage((rating == pEpRating.pEpRatingUnencrypted) ? sourceMessage : destMessage, ref flags);
   3.347  
   3.348              Log.SensitiveData("Decrypt: Complete. " + sourceMessage?.Id);
   3.349  
     4.1 --- a/PEPMessage.cs	Thu May 10 12:18:14 2018 +0200
     4.2 +++ b/PEPMessage.cs	Tue May 22 11:35:06 2018 +0200
     4.3 @@ -1549,14 +1549,19 @@
     4.4          /// Important: Setting this to true for outgoing messages can cause problems with Exchange accounts.</param>
     4.5          /// <param name="setRecipients">Whether to set the message recipients manually. This should normally be set to true
     4.6          /// for all common messages and makes only sense to be omitted in special cases like a FPP reply message.</param>
     4.7 +        /// <param name="convertToPGPMIMEAttachment">Whether to convert the message into a PGP/MIME attachment if needed.
     4.8 +        /// The default behaviour is to convert if the message is PGP/MIME encrypted, which is needed for all outgoing messages
     4.9 +        /// in order for Outlook to send the message correctly. For special cases like when using EncryptForSelf, we might not 
    4.10 +        /// want ot do that, so the parameter can be set to false.</param>
    4.11          /// <returns>The status of the method.</returns>
    4.12          public Globals.ReturnStatus ApplyTo(Outlook.MailItem omi,
    4.13                                              bool setInternalHeaderFields,
    4.14                                              bool setSender,
    4.15 -                                            bool setRecipients = true)
    4.16 +                                            bool setRecipients = true,
    4.17 +                                            bool? convertToPGPMIMEAttachment = null)
    4.18          {
    4.19              bool fromRecipientRemoved = false;
    4.20 -            bool isPGPMIMEMsg = this.IsPGPMIMEEncrypted;
    4.21 +            bool isPGPMIMEMsg = convertToPGPMIMEAttachment ?? this.IsPGPMIMEEncrypted;
    4.22              byte[] bytes;
    4.23              Outlook.Attachments attachments = null;
    4.24              Outlook.Recipient newRecipient = null;
     5.1 --- a/PEPSettings.cs	Thu May 10 12:18:14 2018 +0200
     5.2 +++ b/PEPSettings.cs	Tue May 22 11:35:06 2018 +0200
     5.3 @@ -1866,7 +1866,6 @@
     5.4              protected string        _MirrorStoreId;
     5.5              protected string        _SentFolderEntryId;
     5.6              protected string        _SmtpAddress;
     5.7 -            protected string        _StoreId;
     5.8              protected string        _Type;
     5.9              protected string        _UserName;
    5.10  
     6.1 --- a/Properties/Resources.Designer.cs	Thu May 10 12:18:14 2018 +0200
     6.2 +++ b/Properties/Resources.Designer.cs	Tue May 22 11:35:06 2018 +0200
     6.3 @@ -740,6 +740,24 @@
     6.4          }
     6.5          
     6.6          /// <summary>
     6.7 +        ///   Looks up a localized string similar to Back.
     6.8 +        /// </summary>
     6.9 +        public static string KeySyncWizard_BackButtonText {
    6.10 +            get {
    6.11 +                return ResourceManager.GetString("KeySyncWizard_BackButtonText", resourceCulture);
    6.12 +            }
    6.13 +        }
    6.14 +        
    6.15 +        /// <summary>
    6.16 +        ///   Looks up a localized string similar to An error occured. Your key could not be imported correctly. Please try again..
    6.17 +        /// </summary>
    6.18 +        public static string KeySyncWizard_ErrorExplanationText {
    6.19 +            get {
    6.20 +                return ResourceManager.GetString("KeySyncWizard_ErrorExplanationText", resourceCulture);
    6.21 +            }
    6.22 +        }
    6.23 +        
    6.24 +        /// <summary>
    6.25          ///   Looks up a localized string similar to Error.
    6.26          /// </summary>
    6.27          public static string KeySyncWizard_ErrorText {
    6.28 @@ -749,6 +767,15 @@
    6.29          }
    6.30          
    6.31          /// <summary>
    6.32 +        ///   Looks up a localized string similar to Export my private key to the other device.
    6.33 +        /// </summary>
    6.34 +        public static string KeySyncWizard_ExportOwnPrivateKey {
    6.35 +            get {
    6.36 +                return ResourceManager.GetString("KeySyncWizard_ExportOwnPrivateKey", resourceCulture);
    6.37 +            }
    6.38 +        }
    6.39 +        
    6.40 +        /// <summary>
    6.41          ///   Looks up a localized string similar to Finish.
    6.42          /// </summary>
    6.43          public static string KeySyncWizard_Finish {
    6.44 @@ -767,6 +794,89 @@
    6.45          }
    6.46          
    6.47          /// <summary>
    6.48 +        ///   Looks up a localized string similar to The key import process has been initialized. Please make sure to have the device up and running from which you want to import the key..
    6.49 +        /// </summary>
    6.50 +        public static string KeySyncWizard_PEPStep1ExplanationText {
    6.51 +            get {
    6.52 +                return ResourceManager.GetString("KeySyncWizard_PEPStep1ExplanationText", resourceCulture);
    6.53 +            }
    6.54 +        }
    6.55 +        
    6.56 +        /// <summary>
    6.57 +        ///   Looks up a localized string similar to If you initiated a key import for the following account, please click Start.
    6.58 +        ///
    6.59 +        ///If this was not you, please cancel..
    6.60 +        /// </summary>
    6.61 +        public static string KeySyncWizard_PEPStep1NonInitiatorExplanationText {
    6.62 +            get {
    6.63 +                return ResourceManager.GetString("KeySyncWizard_PEPStep1NonInitiatorExplanationText", resourceCulture);
    6.64 +            }
    6.65 +        }
    6.66 +        
    6.67 +        /// <summary>
    6.68 +        ///   Looks up a localized string similar to Please compare the following Trustwords with the ones on your other device and confirm if they match..
    6.69 +        /// </summary>
    6.70 +        public static string KeySyncWizard_PEPStep2ExplanationText {
    6.71 +            get {
    6.72 +                return ResourceManager.GetString("KeySyncWizard_PEPStep2ExplanationText", resourceCulture);
    6.73 +            }
    6.74 +        }
    6.75 +        
    6.76 +        /// <summary>
    6.77 +        ///   Looks up a localized string similar to Importing key....
    6.78 +        /// </summary>
    6.79 +        public static string KeySyncWizard_PEPStep3ExplanationText {
    6.80 +            get {
    6.81 +                return ResourceManager.GetString("KeySyncWizard_PEPStep3ExplanationText", resourceCulture);
    6.82 +            }
    6.83 +        }
    6.84 +        
    6.85 +        /// <summary>
    6.86 +        ///   Looks up a localized string similar to Key import successful!.
    6.87 +        /// </summary>
    6.88 +        public static string KeySyncWizard_PEPStep4ExplanationText {
    6.89 +            get {
    6.90 +                return ResourceManager.GetString("KeySyncWizard_PEPStep4ExplanationText", resourceCulture);
    6.91 +            }
    6.92 +        }
    6.93 +        
    6.94 +        /// <summary>
    6.95 +        ///   Looks up a localized string similar to Key successfully exported!.
    6.96 +        /// </summary>
    6.97 +        public static string KeySyncWizard_PEPSuccessExport {
    6.98 +            get {
    6.99 +                return ResourceManager.GetString("KeySyncWizard_PEPSuccessExport", resourceCulture);
   6.100 +            }
   6.101 +        }
   6.102 +        
   6.103 +        /// <summary>
   6.104 +        ///   Looks up a localized string similar to Key successfully imported!.
   6.105 +        /// </summary>
   6.106 +        public static string KeySyncWizard_PEPSuccessImport {
   6.107 +            get {
   6.108 +                return ResourceManager.GetString("KeySyncWizard_PEPSuccessImport", resourceCulture);
   6.109 +            }
   6.110 +        }
   6.111 +        
   6.112 +        /// <summary>
   6.113 +        ///   Looks up a localized string similar to The key from your other device will now also be used to decrypt messages..
   6.114 +        /// </summary>
   6.115 +        public static string KeySyncWizard_PEPSuccessOtherKeyUsed {
   6.116 +            get {
   6.117 +                return ResourceManager.GetString("KeySyncWizard_PEPSuccessOtherKeyUsed", resourceCulture);
   6.118 +            }
   6.119 +        }
   6.120 +        
   6.121 +        /// <summary>
   6.122 +        ///   Looks up a localized string similar to The key from your other device will now be used as your default private key..
   6.123 +        /// </summary>
   6.124 +        public static string KeySyncWizard_PEPSuccessOtherKeyUsedAsDefault {
   6.125 +            get {
   6.126 +                return ResourceManager.GetString("KeySyncWizard_PEPSuccessOtherKeyUsedAsDefault", resourceCulture);
   6.127 +            }
   6.128 +        }
   6.129 +        
   6.130 +        /// <summary>
   6.131          ///   Looks up a localized string similar to To proceed with the Key Import, please import the attached public p≡p key and reply with a message that:  
   6.132          ///
   6.133          ///1. has your public PGP key attached and
   6.134 @@ -788,98 +898,56 @@
   6.135          }
   6.136          
   6.137          /// <summary>
   6.138 -        ///   Looks up a localized string similar to The key import process has been initialized. Please make sure to have the device up and running from which you want to import the key..
   6.139 +        ///   Looks up a localized string similar to A message with your public p≡p key has been sent to yourself. Please open this message on your PGP device and import your public p≡p key into your keychain..
   6.140          /// </summary>
   6.141 -        public static string KeySyncWizard_Step1PEPExplanationText {
   6.142 +        public static string KeySyncWizard_PGPStep1ExplanationText {
   6.143              get {
   6.144 -                return ResourceManager.GetString("KeySyncWizard_Step1PEPExplanationText", resourceCulture);
   6.145 +                return ResourceManager.GetString("KeySyncWizard_PGPStep1ExplanationText", resourceCulture);
   6.146              }
   6.147          }
   6.148          
   6.149          /// <summary>
   6.150 -        ///   Looks up a localized string similar to Please import your public p≡p key on your PGP device and reply with a message that:  
   6.151 -        ///
   6.152 -        ///1. has your public PGP key attached and
   6.153 -        ///2. is encrypted with the p≡p key you just imported.
   6.154 +        ///   Looks up a localized string similar to In your PGP device, create an answer message to the one you received from p≡p and attach your public PGP key..
   6.155          /// </summary>
   6.156 -        public static string KeySyncWizard_Step1PGPExplanationText {
   6.157 +        public static string KeySyncWizard_PGPStep2ExplanationText {
   6.158              get {
   6.159 -                return ResourceManager.GetString("KeySyncWizard_Step1PGPExplanationText", resourceCulture);
   6.160 +                return ResourceManager.GetString("KeySyncWizard_PGPStep2ExplanationText", resourceCulture);
   6.161              }
   6.162          }
   6.163          
   6.164          /// <summary>
   6.165 -        ///   Looks up a localized string similar to A message with your public key has been sent to yourself..
   6.166 +        ///   Looks up a localized string similar to Encrypt the answer message with the public p≡p key you just imported and send it..
   6.167          /// </summary>
   6.168 -        public static string KeySyncWizard_Step1PGPSubtitleText {
   6.169 +        public static string KeySyncWizard_PGPStep3ExplanationText {
   6.170              get {
   6.171 -                return ResourceManager.GetString("KeySyncWizard_Step1PGPSubtitleText", resourceCulture);
   6.172 -            }
   6.173 -        }
   6.174 -        
   6.175 -        /// <summary>
   6.176 -        ///   Looks up a localized string similar to Please compare the following Trustwords with the ones on your other device and confirm if they match..
   6.177 -        /// </summary>
   6.178 -        public static string KeySyncWizard_Step2PEPExplanationText {
   6.179 -            get {
   6.180 -                return ResourceManager.GetString("KeySyncWizard_Step2PEPExplanationText", resourceCulture);
   6.181 +                return ResourceManager.GetString("KeySyncWizard_PGPStep3ExplanationText", resourceCulture);
   6.182              }
   6.183          }
   6.184          
   6.185          /// <summary>
   6.186          ///   Looks up a localized string similar to Please compare the PGP fingerprints of the below keys with the ones on your PGP device and confirm if they match..
   6.187          /// </summary>
   6.188 -        public static string KeySyncWizard_Step2PGPExplanationText {
   6.189 +        public static string KeySyncWizard_PGPStep5ExplanationText {
   6.190              get {
   6.191 -                return ResourceManager.GetString("KeySyncWizard_Step2PGPExplanationText", resourceCulture);
   6.192 +                return ResourceManager.GetString("KeySyncWizard_PGPStep5ExplanationText", resourceCulture);
   6.193              }
   6.194          }
   6.195          
   6.196          /// <summary>
   6.197 -        ///   Looks up a localized string similar to Importing key....
   6.198 +        ///   Looks up a localized string similar to In your PGP device, create another answer message to the one you received from p≡p. This time, please attach your private PGP key..
   6.199          /// </summary>
   6.200 -        public static string KeySyncWizard_Step3PEPExplanationText {
   6.201 +        public static string KeySyncWizard_PGPStep6ExplanationText {
   6.202              get {
   6.203 -                return ResourceManager.GetString("KeySyncWizard_Step3PEPExplanationText", resourceCulture);
   6.204 +                return ResourceManager.GetString("KeySyncWizard_PGPStep6ExplanationText", resourceCulture);
   6.205              }
   6.206          }
   6.207          
   6.208          /// <summary>
   6.209 -        ///   Looks up a localized string similar to Please send now another reply message that:  
   6.210 -        ///
   6.211 -        ///1. has your private PGP key attached and
   6.212 -        ///2. is encrypted with the p≡p key you just imported.
   6.213 +        ///   Looks up a localized string similar to Encrypt the answer message again with the public p≡p key and send it..
   6.214          /// </summary>
   6.215 -        public static string KeySyncWizard_Step3PGPExplanationText {
   6.216 +        public static string KeySyncWizard_PGPStep7ExplanationText {
   6.217              get {
   6.218 -                return ResourceManager.GetString("KeySyncWizard_Step3PGPExplanationText", resourceCulture);
   6.219 -            }
   6.220 -        }
   6.221 -        
   6.222 -        /// <summary>
   6.223 -        ///   Looks up a localized string similar to An error occured. Your key could not be imported correctly. Please try again..
   6.224 -        /// </summary>
   6.225 -        public static string KeySyncWizard_Step4ErrorExplanationText {
   6.226 -            get {
   6.227 -                return ResourceManager.GetString("KeySyncWizard_Step4ErrorExplanationText", resourceCulture);
   6.228 -            }
   6.229 -        }
   6.230 -        
   6.231 -        /// <summary>
   6.232 -        ///   Looks up a localized string similar to The key from your other device will now be used as your default private key..
   6.233 -        /// </summary>
   6.234 -        public static string KeySyncWizard_Step4PEPSuccessInitiatorExplanationText {
   6.235 -            get {
   6.236 -                return ResourceManager.GetString("KeySyncWizard_Step4PEPSuccessInitiatorExplanationText", resourceCulture);
   6.237 -            }
   6.238 -        }
   6.239 -        
   6.240 -        /// <summary>
   6.241 -        ///   Looks up a localized string similar to The key from the other device can now be used to decrypt messages..
   6.242 -        /// </summary>
   6.243 -        public static string KeySyncWizard_Step4PEPSuccessNonInitiatorExplanationText {
   6.244 -            get {
   6.245 -                return ResourceManager.GetString("KeySyncWizard_Step4PEPSuccessNonInitiatorExplanationText", resourceCulture);
   6.246 +                return ResourceManager.GetString("KeySyncWizard_PGPStep7ExplanationText", resourceCulture);
   6.247              }
   6.248          }
   6.249          
   6.250 @@ -888,9 +956,27 @@
   6.251          ///
   6.252          ///Your private PGP key has been successfully imported and will now be used as default p≡p key..
   6.253          /// </summary>
   6.254 -        public static string KeySyncWizard_Step4SuccessExplanationText {
   6.255 +        public static string KeySyncWizard_PGPSuccessExplanationText {
   6.256              get {
   6.257 -                return ResourceManager.GetString("KeySyncWizard_Step4SuccessExplanationText", resourceCulture);
   6.258 +                return ResourceManager.GetString("KeySyncWizard_PGPSuccessExplanationText", resourceCulture);
   6.259 +            }
   6.260 +        }
   6.261 +        
   6.262 +        /// <summary>
   6.263 +        ///   Looks up a localized string similar to Use the imported key as default key.
   6.264 +        /// </summary>
   6.265 +        public static string KeySyncWizard_SetImportedKeyAsDefault {
   6.266 +            get {
   6.267 +                return ResourceManager.GetString("KeySyncWizard_SetImportedKeyAsDefault", resourceCulture);
   6.268 +            }
   6.269 +        }
   6.270 +        
   6.271 +        /// <summary>
   6.272 +        ///   Looks up a localized string similar to Start.
   6.273 +        /// </summary>
   6.274 +        public static string KeySyncWizard_Start {
   6.275 +            get {
   6.276 +                return ResourceManager.GetString("KeySyncWizard_Start", resourceCulture);
   6.277              }
   6.278          }
   6.279          
     7.1 --- a/Properties/Resources.de.resx	Thu May 10 12:18:14 2018 +0200
     7.2 +++ b/Properties/Resources.de.resx	Tue May 22 11:35:06 2018 +0200
     7.3 @@ -651,7 +651,7 @@
     7.4      <value>Die Mailgröße überschreitet die zulässige Größenbeschränkung für die Verschlüsselung.</value>
     7.5    </data>
     7.6    <data name="Handshake_WrongFingerprint" xml:space="preserve">
     7.7 -    <value>Falscher Fingerprint</value>
     7.8 +    <value>Falscher Fingerabdruck</value>
     7.9    </data>
    7.10    <data name="Handshake_TrustwordsExpanderTooltipFull" xml:space="preserve">
    7.11      <value>Vollversion der Trustwords anzeigen</value>
    7.12 @@ -722,22 +722,16 @@
    7.13    <data name="KeySyncWizard_Finish" xml:space="preserve">
    7.14      <value>Fertig stellen</value>
    7.15    </data>
    7.16 -  <data name="KeySyncWizard_Step1PGPExplanationText" xml:space="preserve">
    7.17 -    <value>Bitte importieren Sie Ihren öffentlichen p≡p-Schlüssel auf Ihrem PGP-Gerät und senden Sie eine Antwortnachricht:  
    7.18 -
    7.19 -1. an die Sie Ihren öffentlichen PGP-Schlüssel anhängen und
    7.20 -2. die Sie mit dem gerade importierten p≡p-Schlüssel verschlüsseln</value>
    7.21 +  <data name="KeySyncWizard_PGPStep1ExplanationText" xml:space="preserve">
    7.22 +    <value>Eine Nachricht mit Ihrem öffentlichen p≡p-Schlüssel wurde an Sie selbst versendet. Bitte öffnen Sie die Nachricht auf Ihrem PGP-Gerät und importieren Sie den Schlüssel in Ihren PGP-Schlüsselring.</value>
    7.23    </data>
    7.24 -  <data name="KeySyncWizard_Step2PGPExplanationText" xml:space="preserve">
    7.25 -    <value>Bitte vergleichen Sie die PGP-Fingerabdrücke Ihrer beiden Schlüssel mit denjenigen auf Ihrem PGP-Gerät und bestätigen Sie, wenn sie übereinstimmen.</value>
    7.26 +  <data name="KeySyncWizard_PGPStep2ExplanationText" xml:space="preserve">
    7.27 +    <value>Erstellen Sie auf Ihrem PGP-Gerät eine Antwortnachricht auf die Nachricht, die Sie von p≡p erhalten haben und hängen Sie Ihren öffentlichen PGP-Schlüssel an.</value>
    7.28    </data>
    7.29 -  <data name="KeySyncWizard_Step3PGPExplanationText" xml:space="preserve">
    7.30 -    <value>Senden Sie nun bitte eine weitere Antwortnachricht:  
    7.31 -
    7.32 -1. an die Sie Ihren privaten PGP-Schlüssel anhängen und 
    7.33 -2. die Sie mit dem gerade importierten p≡p-Schlüssel verschlüsseln </value>
    7.34 +  <data name="KeySyncWizard_PGPStep3ExplanationText" xml:space="preserve">
    7.35 +    <value>Verschlüsseln Sie die Antwortnachricht mit dem öffentlichen p≡p-Schlüssel, den Sie gerade importiert haben und versenden Sie sie.</value>
    7.36    </data>
    7.37 -  <data name="KeySyncWizard_Step4SuccessExplanationText" xml:space="preserve">
    7.38 +  <data name="KeySyncWizard_PGPSuccessExplanationText" xml:space="preserve">
    7.39      <value>Schlüsselimport erfolgreich
    7.40  
    7.41  Ihr privater PGP-Schlüssel wurde erfolgreich importiert und wird nun standardmäßig auch als p≡p-Schlüssel verwendet.</value>
    7.42 @@ -745,23 +739,23 @@
    7.43    <data name="KeySyncWizard_WindowTitle" xml:space="preserve">
    7.44      <value>Schlüsselimport</value>
    7.45    </data>
    7.46 -  <data name="KeySyncWizard_Step1PEPExplanationText" xml:space="preserve">
    7.47 +  <data name="KeySyncWizard_PEPStep1ExplanationText" xml:space="preserve">
    7.48      <value>Der Schlüsselimportprozess wurde gestartet. Bitte stellen Sie sicher, dass Ihr anderes Gerät, von dem Sie Ihren Schlüssel importieren möchten, eingeschaltet ist.</value>
    7.49    </data>
    7.50 -  <data name="KeySyncWizard_Step2PEPExplanationText" xml:space="preserve">
    7.51 +  <data name="KeySyncWizard_PEPStep2ExplanationText" xml:space="preserve">
    7.52      <value>Bitte vergleichen Sie die folgenden Trustwords mit denjenigen auf Ihrem anderen Gerät und bestätigen Sie sie, wenn sie übereinstimmen.</value>
    7.53    </data>
    7.54    <data name="KeySyncWizard_WaitingForResponseText" xml:space="preserve">
    7.55      <value>Es wird auf eine Antwort vom anderen Gerät gewartet...</value>
    7.56    </data>
    7.57 -  <data name="KeySyncWizard_Step4PEPSuccessInitiatorExplanationText" xml:space="preserve">
    7.58 -    <value>Der Schlüssel von Ihrem anderen Gerät wird nun standardmäßig verwendet.</value>
    7.59 +  <data name="KeySyncWizard_PEPSuccessImport" xml:space="preserve">
    7.60 +    <value>Schlüsselimport erfolgreich!</value>
    7.61    </data>
    7.62 -  <data name="KeySyncWizard_Step4ErrorExplanationText" xml:space="preserve">
    7.63 +  <data name="KeySyncWizard_ErrorExplanationText" xml:space="preserve">
    7.64      <value>Es ist ein Fehler aufgetreten. Ihr Schlüssel konnte nicht importiert werden. Bitte versuchen Sie es erneut.</value>
    7.65    </data>
    7.66 -  <data name="KeySyncWizard_Step4PEPSuccessNonInitiatorExplanationText" xml:space="preserve">
    7.67 -    <value>Der Schlüssel des anderen Geräts kann nun zum Entschlüsseln von Nachrichten verwendet werden.</value>
    7.68 +  <data name="KeySyncWizard_PEPSuccessExport" xml:space="preserve">
    7.69 +    <value>Schlüsselexport erfolgreich!</value>
    7.70    </data>
    7.71    <data name="KeySyncWizard_SuccessText" xml:space="preserve">
    7.72      <value>Schlüsselimport erfolgreich!</value>
    7.73 @@ -769,7 +763,7 @@
    7.74    <data name="KeySyncWizard_ErrorText" xml:space="preserve">
    7.75      <value>Fehler</value>
    7.76    </data>
    7.77 -  <data name="KeySyncWizard_Step3PEPExplanationText" xml:space="preserve">
    7.78 +  <data name="KeySyncWizard_PEPStep3ExplanationText" xml:space="preserve">
    7.79      <value>Schlüssel wird importiert...</value>
    7.80    </data>
    7.81    <data name="StoreContextMenu_OpenPGPKeyImportWizard" xml:space="preserve">
    7.82 @@ -781,9 +775,6 @@
    7.83    <data name="StoreContextMenu_KeyImportText" xml:space="preserve">
    7.84      <value>Schlüsselimport</value>
    7.85    </data>
    7.86 -  <data name="KeySyncWizard_Step1PGPSubtitleText" xml:space="preserve">
    7.87 -    <value>Eine Nachricht mit Ihrem öffentlichen Schlüssel wurde an Sie selbst versendet.</value>
    7.88 -  </data>
    7.89    <data name="KeySyncWizard_PGPInitialMessageBody" xml:space="preserve">
    7.90      <value>Um mit dem Schlüsselimport fortzufahren, importieren Sie bitte den angehängten öffentlichen p≡p-Schlüssel und senden Sie eine Antwortnachricht:  
    7.91  
    7.92 @@ -793,4 +784,39 @@
    7.93    <data name="KeySyncWizard_PGPInitialMessageSubject" xml:space="preserve">
    7.94      <value>p≡p-Schlüsselimport</value>
    7.95    </data>
    7.96 +  <data name="KeySyncWizard_Start" xml:space="preserve">
    7.97 +    <value>Start</value>
    7.98 +  </data>
    7.99 +  <data name="KeySyncWizard_PEPStep1NonInitiatorExplanationText" xml:space="preserve">
   7.100 +    <value>Wenn Sie einen Schlüsselimport von einem anderen Gerät gestartet haben, klicken Sie bitte auf Start.
   7.101 +
   7.102 +Andernfalls klicken Sie bitte auf Abbrechen.</value>
   7.103 +  </data>
   7.104 +  <data name="KeySyncWizard_PGPStep5ExplanationText" xml:space="preserve">
   7.105 +    <value>Bitte vergleichen Sie die PGP-Fingerabdrücke Ihrer beiden Schlüssel mit denjenigen auf Ihrem PGP-Gerät und bestätigen Sie, wenn sie übereinstimmen.</value>
   7.106 +  </data>
   7.107 +  <data name="KeySyncWizard_PGPStep6ExplanationText" xml:space="preserve">
   7.108 +    <value>Erstellen Sie auf Ihrem PGP-Gerät eine neue Antwortnachricht auf die Nachricht, die Sie von p≡p erhalten haben. Hängen Sie nun bitte Ihren privaten PGP-Schlüssel an.</value>
   7.109 +  </data>
   7.110 +  <data name="KeySyncWizard_PGPStep7ExplanationText" xml:space="preserve">
   7.111 +    <value>Verschlüsseln Sie die Antwortnachricht nun wieder mit dem öffentlichen p≡p-Schlüssel und versenden Sie sie.</value>
   7.112 +  </data>
   7.113 +  <data name="KeySyncWizard_BackButtonText" xml:space="preserve">
   7.114 +    <value>Zurück</value>
   7.115 +  </data>
   7.116 +  <data name="KeySyncWizard_PEPStep4ExplanationText" xml:space="preserve">
   7.117 +    <value>Schlüsselimport erfolgreich!</value>
   7.118 +  </data>
   7.119 +  <data name="KeySyncWizard_ExportOwnPrivateKey" xml:space="preserve">
   7.120 +    <value>Meinen privaten Schlüssel auf das andere Gerät exportieren</value>
   7.121 +  </data>
   7.122 +  <data name="KeySyncWizard_SetImportedKeyAsDefault" xml:space="preserve">
   7.123 +    <value>Den importierten Schlüssel standardmäßig verwenden</value>
   7.124 +  </data>
   7.125 +  <data name="KeySyncWizard_PEPSuccessOtherKeyUsed" xml:space="preserve">
   7.126 +    <value>Der Schlüssel von Ihrem anderen Gerät kann nun ebenfalls zum Entschlüsseln verwendet werden.</value>
   7.127 +  </data>
   7.128 +  <data name="KeySyncWizard_PEPSuccessOtherKeyUsedAsDefault" xml:space="preserve">
   7.129 +    <value>Der Schlüssel von Ihrem anderen Gerät wird nun standardmäßig verwendet.</value>
   7.130 +  </data>
   7.131  </root>
   7.132 \ No newline at end of file
     8.1 --- a/Properties/Resources.resx	Thu May 10 12:18:14 2018 +0200
     8.2 +++ b/Properties/Resources.resx	Tue May 22 11:35:06 2018 +0200
     8.3 @@ -820,22 +820,16 @@
     8.4    <data name="KeySyncWizard_Finish" xml:space="preserve">
     8.5      <value>Finish</value>
     8.6    </data>
     8.7 -  <data name="KeySyncWizard_Step1PGPExplanationText" xml:space="preserve">
     8.8 -    <value>Please import your public p≡p key on your PGP device and reply with a message that:  
     8.9 -
    8.10 -1. has your public PGP key attached and
    8.11 -2. is encrypted with the p≡p key you just imported</value>
    8.12 +  <data name="KeySyncWizard_PGPStep1ExplanationText" xml:space="preserve">
    8.13 +    <value>A message with your public p≡p key has been sent to yourself. Please open this message on your PGP device and import your public p≡p key into your keychain.</value>
    8.14    </data>
    8.15 -  <data name="KeySyncWizard_Step2PGPExplanationText" xml:space="preserve">
    8.16 -    <value>Please compare the PGP fingerprints of the below keys with the ones on your PGP device and confirm if they match.</value>
    8.17 +  <data name="KeySyncWizard_PGPStep2ExplanationText" xml:space="preserve">
    8.18 +    <value>In your PGP device, create an answer message to the one you received from p≡p and attach your public PGP key.</value>
    8.19    </data>
    8.20 -  <data name="KeySyncWizard_Step3PGPExplanationText" xml:space="preserve">
    8.21 -    <value>Please send now another reply message that:  
    8.22 -
    8.23 -1. has your private PGP key attached and
    8.24 -2. is encrypted with the p≡p key you just imported</value>
    8.25 +  <data name="KeySyncWizard_PGPStep3ExplanationText" xml:space="preserve">
    8.26 +    <value>Encrypt the answer message with the public p≡p key you just imported and send it.</value>
    8.27    </data>
    8.28 -  <data name="KeySyncWizard_Step4SuccessExplanationText" xml:space="preserve">
    8.29 +  <data name="KeySyncWizard_PGPSuccessExplanationText" xml:space="preserve">
    8.30      <value>Key successfully imported
    8.31  
    8.32  Your private PGP key has been successfully imported and will now be used as default p≡p key.</value>
    8.33 @@ -843,10 +837,10 @@
    8.34    <data name="KeySyncWizard_WindowTitle" xml:space="preserve">
    8.35      <value>Key Import</value>
    8.36    </data>
    8.37 -  <data name="KeySyncWizard_Step1PEPExplanationText" xml:space="preserve">
    8.38 +  <data name="KeySyncWizard_PEPStep1ExplanationText" xml:space="preserve">
    8.39      <value>The key import process has been initialized. Please make sure to have the device up and running from which you want to import the key.</value>
    8.40    </data>
    8.41 -  <data name="KeySyncWizard_Step2PEPExplanationText" xml:space="preserve">
    8.42 +  <data name="KeySyncWizard_PEPStep2ExplanationText" xml:space="preserve">
    8.43      <value>Please compare the following Trustwords with the ones on your other device and confirm if they match.</value>
    8.44    </data>
    8.45    <data name="KeySyncWizard_WaitingForResponseText" xml:space="preserve">
    8.46 @@ -855,14 +849,14 @@
    8.47    <data name="KeySyncWizard_Next" xml:space="preserve">
    8.48      <value>Next</value>
    8.49    </data>
    8.50 -  <data name="KeySyncWizard_Step4PEPSuccessInitiatorExplanationText" xml:space="preserve">
    8.51 -    <value>The key from your other device will now be used as your default private key.</value>
    8.52 +  <data name="KeySyncWizard_PEPSuccessImport" xml:space="preserve">
    8.53 +    <value>Key successfully imported!</value>
    8.54    </data>
    8.55 -  <data name="KeySyncWizard_Step4ErrorExplanationText" xml:space="preserve">
    8.56 +  <data name="KeySyncWizard_ErrorExplanationText" xml:space="preserve">
    8.57      <value>An error occured. Your key could not be imported correctly. Please try again.</value>
    8.58    </data>
    8.59 -  <data name="KeySyncWizard_Step4PEPSuccessNonInitiatorExplanationText" xml:space="preserve">
    8.60 -    <value>The key from the other device can now be used to decrypt messages.</value>
    8.61 +  <data name="KeySyncWizard_PEPSuccessExport" xml:space="preserve">
    8.62 +    <value>Key successfully exported!</value>
    8.63    </data>
    8.64    <data name="KeySyncWizard_SuccessText" xml:space="preserve">
    8.65      <value>Key import successful!</value>
    8.66 @@ -870,7 +864,7 @@
    8.67    <data name="KeySyncWizard_ErrorText" xml:space="preserve">
    8.68      <value>Error</value>
    8.69    </data>
    8.70 -  <data name="KeySyncWizard_Step3PEPExplanationText" xml:space="preserve">
    8.71 +  <data name="KeySyncWizard_PEPStep3ExplanationText" xml:space="preserve">
    8.72      <value>Importing key...</value>
    8.73    </data>
    8.74    <data name="StoreContextMenu_OpenPGPKeyImportWizard" xml:space="preserve">
    8.75 @@ -885,9 +879,6 @@
    8.76    <data name="ImageLogoIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
    8.77      <value>..\resources\imagelogoicon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
    8.78    </data>
    8.79 -  <data name="KeySyncWizard_Step1PGPSubtitleText" xml:space="preserve">
    8.80 -    <value>A message with your public key has been sent to yourself.</value>
    8.81 -  </data>
    8.82    <data name="KeySyncWizard_PGPInitialMessageBody" xml:space="preserve">
    8.83      <value>To proceed with the Key Import, please import the attached public p≡p key and reply with a message that:  
    8.84  
    8.85 @@ -897,4 +888,39 @@
    8.86    <data name="KeySyncWizard_PGPInitialMessageSubject" xml:space="preserve">
    8.87      <value>p≡p Key Import</value>
    8.88    </data>
    8.89 +  <data name="KeySyncWizard_Start" xml:space="preserve">
    8.90 +    <value>Start</value>
    8.91 +  </data>
    8.92 +  <data name="KeySyncWizard_PEPStep1NonInitiatorExplanationText" xml:space="preserve">
    8.93 +    <value>If you initiated a key import for the following account, please click Start.
    8.94 +
    8.95 +If this was not you, please cancel.</value>
    8.96 +  </data>
    8.97 +  <data name="KeySyncWizard_PGPStep5ExplanationText" xml:space="preserve">
    8.98 +    <value>Please compare the PGP fingerprints of the below keys with the ones on your PGP device and confirm if they match.</value>
    8.99 +  </data>
   8.100 +  <data name="KeySyncWizard_PGPStep6ExplanationText" xml:space="preserve">
   8.101 +    <value>In your PGP device, create another answer message to the one you received from p≡p. This time, please attach your private PGP key.</value>
   8.102 +  </data>
   8.103 +  <data name="KeySyncWizard_PGPStep7ExplanationText" xml:space="preserve">
   8.104 +    <value>Encrypt the answer message again with the public p≡p key and send it.</value>
   8.105 +  </data>
   8.106 +  <data name="KeySyncWizard_BackButtonText" xml:space="preserve">
   8.107 +    <value>Back</value>
   8.108 +  </data>
   8.109 +  <data name="KeySyncWizard_PEPStep4ExplanationText" xml:space="preserve">
   8.110 +    <value>Key import successful!</value>
   8.111 +  </data>
   8.112 +  <data name="KeySyncWizard_ExportOwnPrivateKey" xml:space="preserve">
   8.113 +    <value>Export my private key to the other device</value>
   8.114 +  </data>
   8.115 +  <data name="KeySyncWizard_SetImportedKeyAsDefault" xml:space="preserve">
   8.116 +    <value>Use the imported key as default key</value>
   8.117 +  </data>
   8.118 +  <data name="KeySyncWizard_PEPSuccessOtherKeyUsedAsDefault" xml:space="preserve">
   8.119 +    <value>The key from your other device will now be used as your default private key.</value>
   8.120 +  </data>
   8.121 +  <data name="KeySyncWizard_PEPSuccessOtherKeyUsed" xml:space="preserve">
   8.122 +    <value>The key from your other device will now also be used to decrypt messages.</value>
   8.123 +  </data>
   8.124  </root>
   8.125 \ No newline at end of file
     9.1 --- a/ThisAddIn.cs	Thu May 10 12:18:14 2018 +0200
     9.2 +++ b/ThisAddIn.cs	Tue May 22 11:35:06 2018 +0200
     9.3 @@ -741,10 +741,12 @@
     9.4          /// <param name="validateSendingAccount">Validates that the SendingAccount matches the From identity of the given message.
     9.5          /// This can catch situations (and throw exceptions) where the default account would be used instead.</param>
     9.6          /// <param name="processMessage">Whether or not to process this message through the pEp engine.</param>
     9.7 +        /// <param name="setKeyImportHeader">Whether or not to process this message through the pEp engine.</param>
     9.8          internal void CreateAndSendMessage(PEPMessage message,
     9.9                                             bool deleteAfterSend,
    9.10                                             bool validateSendingAccount,
    9.11 -                                           bool processMessage = false)
    9.12 +                                           bool processMessage = false,
    9.13 +                                           bool setKeyImportHeader = false)
    9.14          {
    9.15              Outlook.MailItem newItem;
    9.16              Globals.ReturnStatus sts;
    9.17 @@ -777,10 +779,31 @@
    9.18                      MapiHelper.SetProperty(newItem, MapiProperty.PidLidUseTnef, false);
    9.19  
    9.20                      // If ForceUnencrypted property is set, add it to mail item
    9.21 +                    bool save = false;
    9.22                      if (message.ForceUnencrypted)
    9.23                      {
    9.24                          newItem.SetPEPProperty(MailItemExtensions.PEPProperty.ForceUnencrypted, true);
    9.25 -                        newItem.Save();
    9.26 +                        save = true;
    9.27 +                    }
    9.28 +
    9.29 +                    // Set KeyImport header if necessary
    9.30 +                    if (setKeyImportHeader)
    9.31 +                    {
    9.32 +                        newItem.SetPEPProperty(MailItemExtensions.PEPProperty.KeyImport, message.KeyImport);
    9.33 +                        save = true;
    9.34 +                    }
    9.35 +
    9.36 +                    // Save if necessary
    9.37 +                    if (save)
    9.38 +                    {
    9.39 +                        try
    9.40 +                        {
    9.41 +                            newItem.Save();
    9.42 +                        }
    9.43 +                        catch (Exception ex)
    9.44 +                        {
    9.45 +                            Log.Error("CreateAndSendMessage: Error saving new item. " + ex.ToString());
    9.46 +                        }
    9.47                      }
    9.48  
    9.49                      /* Send
    10.1 --- a/UI/FormControlPreviewMessage.xaml.cs	Thu May 10 12:18:14 2018 +0200
    10.2 +++ b/UI/FormControlPreviewMessage.xaml.cs	Tue May 22 11:35:06 2018 +0200
    10.3 @@ -178,7 +178,14 @@
    10.4                      {
    10.5                          Regex r = new Regex("<head(.*?)>", RegexOptions.IgnoreCase);
    10.6                          Match m2 = r.Match(htmlString);
    10.7 -                        htmlString = r.Replace(htmlString, m2.Value + "<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>", 1);
    10.8 +                        if (string.IsNullOrEmpty(m2.Value))
    10.9 +                        {
   10.10 +                            htmlString = "<head><meta http-equiv='Content-Type' content='text/html;charset=UTF-8'></head>" + htmlString;
   10.11 +                        }
   10.12 +                        else
   10.13 +                        {
   10.14 +                            htmlString = r.Replace(htmlString, m2.Value + "<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>", 1);
   10.15 +                        }
   10.16                      }
   10.17                      else
   10.18                      {
    11.1 --- a/UI/HandshakeDialog.xaml.cs	Thu May 10 12:18:14 2018 +0200
    11.2 +++ b/UI/HandshakeDialog.xaml.cs	Tue May 22 11:35:06 2018 +0200
    11.3 @@ -4,7 +4,6 @@
    11.4  using System.Collections.ObjectModel;
    11.5  using System.ComponentModel;
    11.6  using System.Linq;
    11.7 -using System.Runtime.InteropServices;
    11.8  using System.Windows;
    11.9  using System.Windows.Controls;
   11.10  using System.Windows.Input;
    12.1 --- a/UI/HandshakeItemsControl.xaml	Thu May 10 12:18:14 2018 +0200
    12.2 +++ b/UI/HandshakeItemsControl.xaml	Tue May 22 11:35:06 2018 +0200
    12.3 @@ -201,7 +201,8 @@
    12.4                                    SelectedValuePath="Key"
    12.5                                    SelectedValue="{Binding Path=TrustwordsCulture, Mode=TwoWay}"
    12.6                                    IsEnabled="{Binding Path=ActiveTab, Converter={StaticResource IsActiveTabToBool}, ConverterParameter=Trustwords}"
    12.7 -                                  Foreground="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Converter={StaticResource IsEnabledToColor}}" />
    12.8 +                                  Foreground="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Converter={StaticResource IsEnabledToColor}}"
    12.9 +                                  Visibility="{Binding Path=Mode, Converter={StaticResource IsNotSyncModeToVisibility}}" />
   12.10                      </StackPanel>
   12.11  
   12.12                      <!-- Trustwords -->
    13.1 --- a/UI/HandshakeItemsControl.xaml.cs	Thu May 10 12:18:14 2018 +0200
    13.2 +++ b/UI/HandshakeItemsControl.xaml.cs	Tue May 22 11:35:06 2018 +0200
    13.3 @@ -127,5 +127,15 @@
    13.4                  handshakeItem.AreTrustwordsExpanded = ((sender as Expander)?.IsExpanded == true);
    13.5              }
    13.6          }
    13.7 +
    13.8 +        /// <summary>
    13.9 +        /// Raises the property changed event, if possible, with the given arguments.
   13.10 +        /// </summary>
   13.11 +        /// <param name="propertyName">The name of the property that changed.</param>
   13.12 +        private void RaisePropertyChangedEvent(string propertyName)
   13.13 +        {
   13.14 +            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   13.15 +            return;
   13.16 +        }
   13.17      }
   13.18  }
    14.1 --- a/UI/KeySyncWizard.xaml	Thu May 10 12:18:14 2018 +0200
    14.2 +++ b/UI/KeySyncWizard.xaml	Tue May 22 11:35:06 2018 +0200
    14.3 @@ -23,94 +23,92 @@
    14.4          <ResourceDictionary>
    14.5              <!-- Converters -->
    14.6              <BooleanToVisibilityConverter x:Key="BoolToVisibility" />
    14.7 -            <local:InvertBoolConverter x:Key="InvertBool" />
    14.8 -            <local:ValueConverterGroup x:Key="IsWizardStateToVisibility">
    14.9 -                <local:IsWizardStateConverter />
   14.10 -                <BooleanToVisibilityConverter />
   14.11 -            </local:ValueConverterGroup>
   14.12 -            <local:ValueConverterGroup x:Key="IsNotWizardStateToVisibility">
   14.13 -                <local:IsWizardStateConverter />
   14.14 +            <local:MultiBooleanToVisibilityConverter x:Key="MultiBooleanToVisibility" />
   14.15 +            <local:ValueConverterGroup x:Key="IsStringNotNullOrEmptyToVisibility">
   14.16 +                <local:IsStringEmptyConverter />
   14.17                  <local:InvertBoolConverter />
   14.18                  <BooleanToVisibilityConverter />
   14.19              </local:ValueConverterGroup>
   14.20 -            <local:ValueConverterGroup x:Key="IsNotWizardStateToBool">
   14.21 -                <local:IsWizardStateConverter />
   14.22 -                <local:InvertBoolConverter />
   14.23 -            </local:ValueConverterGroup>
   14.24 +            <local:IsWizardTypeConverter x:Key="IsWizardType" />
   14.25 +
   14.26 +            <!--Dictionary-->
   14.27 +            <ResourceDictionary.MergedDictionaries>
   14.28 +                <ResourceDictionary Source="pack://application:,,,/pEp;component/Resources/Dictionary.xaml" />
   14.29 +            </ResourceDictionary.MergedDictionaries>
   14.30          </ResourceDictionary>
   14.31      </Window.Resources>
   14.32  
   14.33 -    <!--The window content-->
   14.34 -    <StackPanel Width="470">
   14.35 -
   14.36 -        <!--Title section-->
   14.37 -        <Grid Background="White"
   14.38 -              Margin="0">
   14.39 -            <Grid.ColumnDefinitions>
   14.40 -                <ColumnDefinition Width="*" />
   14.41 -                <ColumnDefinition Width="Auto" />
   14.42 -            </Grid.ColumnDefinitions>
   14.43 -            <StackPanel Grid.Column="0">
   14.44 -                <TextBlock Margin="20,10,10,10"
   14.45 -                       Text="{Binding Path=TitleText}"
   14.46 -                       FontWeight="Bold" 
   14.47 -                       VerticalAlignment="Center"/>
   14.48 -                <TextBlock Margin="20,10,10,10"
   14.49 -                           Text="{Binding Path=SubtitleText}"
   14.50 -                           TextWrapping="Wrap"
   14.51 -                           VerticalAlignment="Center" />
   14.52 -            </StackPanel>
   14.53 -            <Image Grid.Column="1"
   14.54 -                   Stretch="Uniform"
   14.55 -                   Height="40"
   14.56 -                   VerticalAlignment="Center"
   14.57 -                   HorizontalAlignment="Right"
   14.58 -                   Margin="20,10"
   14.59 -                   Source="pack://application:,,,/pEp;component/Resources/ImageLogoMedium.png">
   14.60 -            </Image>
   14.61 -        </Grid>
   14.62 -
   14.63 -        <Separator Margin="0,0,0,20"
   14.64 -                   Background="LightGray" />
   14.65 +    <StackPanel Margin="10"
   14.66 +                Width="470">
   14.67  
   14.68          <!--Information section-->
   14.69 -        <TextBlock Text="{Binding Path=ExplanationText}"
   14.70 +        <TextBlock Text="{Binding Path=CurrentState.TitleText}"
   14.71                     TextWrapping="Wrap"
   14.72 -                   Margin="20,10" />
   14.73 +                   Margin="5,5,5,15" />
   14.74 +
   14.75 +        <!--User name section-->
   14.76 +        <TextBlock Text="{Binding Path=CurrentState.UserText}"
   14.77 +                   Padding="10"
   14.78 +                   MinHeight="80"
   14.79 +                   Background="White"
   14.80 +                   FontWeight="DemiBold"
   14.81 +                   Visibility="{Binding Path=CurrentState.IsUserTextVisible, Converter={StaticResource BoolToVisibility}}" />
   14.82  
   14.83          <!--Identities section-->
   14.84 -        <local:HandshakeItemsControl Margin="10,0"
   14.85 -                                     ItemsSource="{Binding Path=Items}"
   14.86 -                                     Visibility="{Binding Path=State, Converter={StaticResource IsWizardStateToVisibility}, ConverterParameter=Step2}" />
   14.87 +        <StackPanel Visibility="{Binding Path=CurrentState.AreTrustwordsVisible, Converter={StaticResource BoolToVisibility}}">
   14.88 +            <local:HandshakeItemsControl ItemsSource="{Binding Path=Items}" />
   14.89 +            <StackPanel Orientation="Horizontal"
   14.90 +                        Margin="5,10,5,0"
   14.91 +                        Visibility="{Binding Path=IsInitiator, Converter={StaticResource BoolToVisibility}}">
   14.92 +                <CheckBox VerticalAlignment="Center"
   14.93 +                          IsChecked="{Binding Path=SetImportedKeyAsDefault}" />
   14.94 +                <Label Content="{x:Static p:Resources.KeySyncWizard_SetImportedKeyAsDefault}"
   14.95 +                       MouseUp="LabelSetImportedKeyAsDefault_MouseUp"/>
   14.96 +            </StackPanel>
   14.97 +            <StackPanel Orientation="Horizontal"
   14.98 +                        Margin="5,0,5,5">
   14.99 +                <StackPanel.Visibility>
  14.100 +                    <MultiBinding Converter="{StaticResource MultiBooleanToVisibility}">
  14.101 +                        <Binding Path="IsInitiator" />
  14.102 +                        <Binding Path="Type" Converter="{StaticResource IsWizardType}" ConverterParameter="pEp" />
  14.103 +                    </MultiBinding>
  14.104 +                </StackPanel.Visibility>
  14.105 +                <CheckBox VerticalAlignment="Center"
  14.106 +                          IsChecked="{Binding Path=ExportPrivateKey}" />
  14.107 +                <Label Content="{x:Static p:Resources.KeySyncWizard_ExportOwnPrivateKey}" 
  14.108 +                       MouseUp="LabelExportPrivateKey_MouseUp"/>
  14.109 +            </StackPanel>
  14.110 +        </StackPanel>
  14.111  
  14.112 -        <Separator Margin="10,20,10,0" 
  14.113 -                   Background="LightGray"/>
  14.114 +        <!--Subtitle section-->
  14.115 +        <TextBlock Text="{Binding Path=CurrentState.SubtitleText}"
  14.116 +                   TextWrapping="Wrap"
  14.117 +                   Margin="5,15"
  14.118 +                   Visibility="{Binding Path=CurrentState.SubtitleText, Converter={StaticResource IsStringNotNullOrEmptyToVisibility}}" />
  14.119  
  14.120          <!--Buttons section-->
  14.121 -        <Grid>
  14.122 -            <Grid.ColumnDefinitions>
  14.123 -                <ColumnDefinition Width="*" />
  14.124 -                <ColumnDefinition Width="Auto" />
  14.125 -            </Grid.ColumnDefinitions>
  14.126 -            <StackPanel Grid.Column="1"
  14.127 -                        Margin="10"
  14.128 -                        Orientation="Horizontal">
  14.129 -                <Button x:Name="OKNextButton"
  14.130 -                        Margin="5"
  14.131 -                        Padding="5,2"
  14.132 -                        MinWidth="70"
  14.133 -                        IsEnabled="{Binding Path=State, Converter={StaticResource IsNotWizardStateToBool}, ConverterParameter=Step1|Step3}"
  14.134 -                        Click="OKNextButton_Click"
  14.135 -                        Content="{Binding Path=NextButtonText}" />
  14.136 -                <Button x:Name="CancelButton"
  14.137 -                        Margin="5"
  14.138 -                        Padding="5,2"
  14.139 -                        MinWidth="70"
  14.140 -                        Click="CancelButton_Click"
  14.141 -                        Visibility="{Binding Path=State, Converter={StaticResource IsNotWizardStateToVisibility}, ConverterParameter=Step4}"
  14.142 -                        Content="{x:Static p:Resources.Options_CancelText}" />
  14.143 -            </StackPanel>
  14.144 -        </Grid>
  14.145 +        <StackPanel Margin="0,10"
  14.146 +                    Orientation="Horizontal"
  14.147 +                    HorizontalAlignment="Right">
  14.148 +            <Button x:Name="BackButton"
  14.149 +                    Style="{StaticResource StyleCancelButton}"
  14.150 +                    Margin="0,5,5,5"
  14.151 +                    Click="BackButton_Click"
  14.152 +                    Content="{x:Static p:Resources.KeySyncWizard_BackButtonText}"
  14.153 +                    Visibility="{Binding Path=CurrentState.IsBackButtonVisible, Converter={StaticResource BoolToVisibility}}" />
  14.154 +            <Button x:Name="AcceptButton"
  14.155 +                    Style="{StaticResource StyleConfirmButton}"
  14.156 +                    Margin="5"
  14.157 +                    Click="AcceptButton_Click"
  14.158 +                    Content="{Binding Path=CurrentState.AcceptButtonText}"
  14.159 +                    Visibility="{Binding Path=CurrentState.IsAcceptButtonVisible, Converter={StaticResource BoolToVisibility}}" />
  14.160 +            <Button x:Name="CancelButton"
  14.161 +                    Margin="5,5,0,5"
  14.162 +                    Style="{StaticResource StyleWrongButton}"
  14.163 +                    Click="CancelButton_Click"
  14.164 +                    Content="{Binding Path=CurrentState.CancelButtonText}"
  14.165 +                    Visibility="{Binding Path=CurrentState.IsCancelButtonVisible, Converter={StaticResource BoolToVisibility}}" />
  14.166 +        </StackPanel>
  14.167      </StackPanel>
  14.168  </Window>
  14.169  
    15.1 --- a/UI/KeySyncWizard.xaml.cs	Thu May 10 12:18:14 2018 +0200
    15.2 +++ b/UI/KeySyncWizard.xaml.cs	Tue May 22 11:35:06 2018 +0200
    15.3 @@ -3,7 +3,10 @@
    15.4  using System.Collections.Generic;
    15.5  using System.Collections.ObjectModel;
    15.6  using System.ComponentModel;
    15.7 +using System.Threading.Tasks;
    15.8  using System.Windows;
    15.9 +using System.Windows.Input;
   15.10 +using System.Windows.Threading;
   15.11  using Outlook = Microsoft.Office.Interop.Outlook;
   15.12  
   15.13  namespace pEp.UI
   15.14 @@ -15,8 +18,23 @@
   15.15                                             INotifyPropertyChanged,
   15.16                                             Interfaces.IReset
   15.17      {
   15.18 -        public const string PEP_PGP_SYNC_MESSAGE_SUBJECT    = "p≡p Key Import";
   15.19 -        public const string PEP_PGP_SYNC_MESSAGE_BODY       = "";
   15.20 +        /// <summary>
   15.21 +        /// Defines the step this wizard is currently in.
   15.22 +        /// </summary>
   15.23 +        public enum Steps
   15.24 +        {
   15.25 +            Undefined,
   15.26 +            Success,
   15.27 +            Error,
   15.28 +            Step1,
   15.29 +            Step2,
   15.30 +            Step3,
   15.31 +            Step4,
   15.32 +            Step5,
   15.33 +            Step6,
   15.34 +            Step7,
   15.35 +            Step8
   15.36 +        }
   15.37  
   15.38          /// <summary>
   15.39          /// The message types for sync messages.
   15.40 @@ -40,66 +58,33 @@
   15.41          }
   15.42  
   15.43          /// <summary>
   15.44 -        /// Defines the state (step) this wizard is currently in.
   15.45 -        /// </summary>
   15.46 -        public enum WizardState
   15.47 -        {
   15.48 -            /// <summary>
   15.49 -            /// Undefined state. Should never occur.
   15.50 -            /// </summary>
   15.51 -            Undefined,
   15.52 -
   15.53 -            /// <summary>
   15.54 -            /// First state on the side of the device that initiated
   15.55 -            /// the process. Will send a first message and wait for
   15.56 -            /// an answer message from the other device.
   15.57 -            /// </summary>
   15.58 -            Step1,
   15.59 -
   15.60 -            /// <summary>
   15.61 -            /// Showing the Trustwords dialog, waiting for user input.
   15.62 -            /// </summary>
   15.63 -            Step2,
   15.64 -
   15.65 -            /// <summary>
   15.66 -            /// Trustwords are accepted, the private key is being sent.
   15.67 -            /// Waiting for key from other device.
   15.68 -            /// </summary>
   15.69 -            Step3,
   15.70 -
   15.71 -            /// <summary>
   15.72 -            /// Process has finished (successfully or not).
   15.73 -            /// </summary>
   15.74 -            Step4
   15.75 -        }
   15.76 -
   15.77 -        /// <summary>
   15.78          /// Event raised when a property is changed on a component.
   15.79          /// </summary>
   15.80          public event PropertyChangedEventHandler PropertyChanged;
   15.81  
   15.82 -        private string                                  _ExplanationText;
   15.83 +        private WizardState                             _CurrentState;
   15.84 +        private bool                                    _ExportPrivateKey;
   15.85 +        private bool                                    _IsInitiator;
   15.86          private ObservableCollection<HandshakeItem>     _Items;
   15.87          private PEPIdentity                             _Myself;
   15.88 -        private string                                  _NextButtonText;
   15.89          private PEPIdentity                             _Partner;
   15.90 -        private WizardState                             _State;
   15.91 -        private string                                  _SubtitleText;
   15.92 -        private bool                                    _Success;
   15.93 -        private string                                  _TitleText;
   15.94 +        private Steps                                   _Step;
   15.95 +        private bool                                    _SetImportedKeyAsDefault;
   15.96          private WizardType                              _Type;
   15.97  
   15.98 +        private bool                                    privateKeyImported = false;
   15.99 +        private List<MessageTypes>                      sentMessages                = new List<MessageTypes>();
  15.100 +        private List<PEPMessage>                        receivedSyncMessages        = new List<PEPMessage>();
  15.101 +        private List<WizardState>                       states = new List<WizardState>();
  15.102 +        private object                                  mutexReceivedSyncMessages   = new object();
  15.103 +
  15.104          public static KeySyncWizard                     Wizard = null;
  15.105  
  15.106 -        private bool                                    isInitiator         = false;
  15.107 -        private List<MessageTypes>                      sentMessages = new List<MessageTypes>();
  15.108 -
  15.109          /// <summary>
  15.110          /// Default constructor
  15.111          /// </summary>
  15.112          public KeySyncWizard()
  15.113 -        {
  15.114 -        }
  15.115 +        { }
  15.116  
  15.117          /// <summary>
  15.118          /// Constructor to create a new key sync wizard.
  15.119 @@ -118,58 +103,26 @@
  15.120                  KeySyncWizard.Wizard.Close();
  15.121              }
  15.122  
  15.123 +            // Reset all values
  15.124 +            this.Reset();
  15.125 +
  15.126              // Initialize the window
  15.127              InitializeComponent();
  15.128  
  15.129              // Set current wizard
  15.130              KeySyncWizard.Wizard = this;
  15.131  
  15.132 -            // Reset all values
  15.133 -            this.Reset();
  15.134 -
  15.135              // Initialize the wizard
  15.136 -            this.InitializeWizard(type, myself, partnerFpr);
  15.137 -
  15.138 -            // Set if wizard is the one that has started the sync process
  15.139 -            this.isInitiator = isInitiator;
  15.140 +            this.InitializeWizard(isInitiator, type, myself, partnerFpr);
  15.141  
  15.142              // Attach event handler for new sync messages
  15.143              MsgProcessor.SyncMessageReceived += KeySyncWizard_SyncMessageReceived;
  15.144  
  15.145 -            // Either send initial or answer message
  15.146 -            if (isInitiator)
  15.147 +            // Send initial message if necessary
  15.148 +            if (this.IsInitiator)
  15.149              {
  15.150 -                // Send initial message
  15.151                  this.SendSyncMessage(MessageTypes.InitialMessage);
  15.152              }
  15.153 -            else
  15.154 -            {
  15.155 -                try
  15.156 -                {
  15.157 -                    // Update own identity
  15.158 -                    this.Myself = new PEPIdentity(ThisAddIn.PEPEngine.Myself(this.Myself.ToCOMType()));
  15.159 -
  15.160 -                    // Create handshake item
  15.161 -                    if (this.CreateHandshakeItem())
  15.162 -                    {
  15.163 -                        // Send answer message with pub key
  15.164 -                        this.SendSyncMessage(MessageTypes.PublicKeyMessage);
  15.165 -
  15.166 -                        // Go to next step
  15.167 -                        this.GoToNextStep();
  15.168 -                    }
  15.169 -                    else
  15.170 -                    {
  15.171 -                        Log.Error("KeySyncWizard: Error creating handshake item.");
  15.172 -                        this.GoToLastStep(false);
  15.173 -                    }
  15.174 -                }
  15.175 -                catch (Exception ex)
  15.176 -                {
  15.177 -                    Log.Error("KeySyncWizard: Error updating Myself. " + ex.ToString());
  15.178 -                    this.GoToLastStep(false);
  15.179 -                }
  15.180 -            }
  15.181          }
  15.182  
  15.183          #region Property Accessors
  15.184 @@ -180,15 +133,42 @@
  15.185           *************************************************************/
  15.186  
  15.187          /// <summary>
  15.188 -        /// Gets or sets the explanatory text in the wizard.
  15.189 +        /// Gets or sets the Items collection.
  15.190          /// </summary>
  15.191 -        public string ExplanationText
  15.192 +        public WizardState CurrentState
  15.193          {
  15.194 -            get { return this._ExplanationText; }
  15.195 +            get { return this._CurrentState; }
  15.196              set
  15.197              {
  15.198 -                this._ExplanationText = value;
  15.199 -                this.RaisePropertyChangedEvent(nameof(this.ExplanationText));
  15.200 +                this._CurrentState = value;
  15.201 +                this.RaisePropertyChangedEvent(nameof(this.CurrentState));
  15.202 +            }
  15.203 +        }
  15.204 +
  15.205 +        /// <summary>
  15.206 +        /// Gets or sets whether to export the private key.
  15.207 +        /// </summary>
  15.208 +        public bool ExportPrivateKey
  15.209 +        {
  15.210 +            get { return this._ExportPrivateKey; }
  15.211 +            set
  15.212 +            {
  15.213 +                this._ExportPrivateKey = value;
  15.214 +                this.RaisePropertyChangedEvent(nameof(this.ExportPrivateKey));
  15.215 +            }
  15.216 +        }
  15.217 +
  15.218 +        /// <summary>
  15.219 +        /// Gets or sets whether this wizard is the one that
  15.220 +        /// initiated the Key Import process.
  15.221 +        /// </summary>
  15.222 +        public bool IsInitiator
  15.223 +        {
  15.224 +            get { return this._IsInitiator; }
  15.225 +            set
  15.226 +            {
  15.227 +                this._IsInitiator = value;
  15.228 +                this.RaisePropertyChangedEvent(nameof(this.IsInitiator));
  15.229              }
  15.230          }
  15.231  
  15.232 @@ -219,19 +199,6 @@
  15.233          }
  15.234  
  15.235          /// <summary>
  15.236 -        /// Gets or sets the Next/Finish button's text.
  15.237 -        /// </summary>
  15.238 -        public string NextButtonText
  15.239 -        {
  15.240 -            get { return this._NextButtonText; }
  15.241 -            set
  15.242 -            {
  15.243 -                this._NextButtonText = value;
  15.244 -                this.RaisePropertyChangedEvent(nameof(this.NextButtonText));
  15.245 -            }
  15.246 -        }
  15.247 -
  15.248 -        /// <summary>
  15.249          /// Gets or sets the sync partner.
  15.250          /// </summary>
  15.251          public PEPIdentity Partner
  15.252 @@ -245,54 +212,28 @@
  15.253          }
  15.254  
  15.255          /// <summary>
  15.256 -        /// Gets or sets the wizard state.
  15.257 +        /// Gets or sets the current wizard step.
  15.258          /// </summary>
  15.259 -        public WizardState State
  15.260 +        public Steps Step
  15.261          {
  15.262 -            get { return this._State; }
  15.263 +            get { return this._Step; }
  15.264              set
  15.265              {
  15.266 -                this._State = value;
  15.267 -                this.RaisePropertyChangedEvent(nameof(this.State));
  15.268 +                this._Step = value;
  15.269 +                this.RaisePropertyChangedEvent(nameof(this.Step));
  15.270              }
  15.271          }
  15.272  
  15.273          /// <summary>
  15.274 -        /// Gets or sets the subtitle text in the wizard.
  15.275 +        /// Gets or sets whether to use the imported key as default key.
  15.276          /// </summary>
  15.277 -        public string SubtitleText
  15.278 +        public bool SetImportedKeyAsDefault
  15.279          {
  15.280 -            get { return this._SubtitleText; }
  15.281 +            get { return this._SetImportedKeyAsDefault; }
  15.282              set
  15.283              {
  15.284 -                this._SubtitleText = value;
  15.285 -                this.RaisePropertyChangedEvent(nameof(this.SubtitleText));
  15.286 -            }
  15.287 -        }
  15.288 -
  15.289 -        /// <summary>
  15.290 -        /// Gets or sets the success state.
  15.291 -        /// </summary>
  15.292 -        public bool Success
  15.293 -        {
  15.294 -            get { return this._Success; }
  15.295 -            set
  15.296 -            {
  15.297 -                this._Success = value;
  15.298 -                this.RaisePropertyChangedEvent(nameof(this.Success));
  15.299 -            }
  15.300 -        }
  15.301 -
  15.302 -        /// <summary>
  15.303 -        /// Gets or sets the title text in the wizard.
  15.304 -        /// </summary>
  15.305 -        public string TitleText
  15.306 -        {
  15.307 -            get { return this._TitleText; }
  15.308 -            set
  15.309 -            {
  15.310 -                this._TitleText = value;
  15.311 -                this.RaisePropertyChangedEvent(nameof(this.TitleText));
  15.312 +                this._SetImportedKeyAsDefault = value;
  15.313 +                this.RaisePropertyChangedEvent(nameof(this.SetImportedKeyAsDefault));
  15.314              }
  15.315          }
  15.316  
  15.317 @@ -309,6 +250,35 @@
  15.318              }
  15.319          }
  15.320  
  15.321 +        /// <summary>
  15.322 +        /// Gets the user name to display in the dialog.
  15.323 +        /// </summary>
  15.324 +        public string UserName
  15.325 +        {
  15.326 +            get
  15.327 +            {
  15.328 +                string userName = string.Empty;
  15.329 +
  15.330 +                // Try to get user name in format "name (address)"
  15.331 +                if (string.IsNullOrEmpty(this.Myself?.UserName) == false)
  15.332 +                {
  15.333 +                    userName = this.Myself.UserName;
  15.334 +
  15.335 +                    if (string.IsNullOrEmpty(this.Myself?.Address) == false)
  15.336 +                    {
  15.337 +                        userName += " (" + this.Myself.Address + ")";
  15.338 +                    }
  15.339 +                }
  15.340 +                // If we have no user name, just display address
  15.341 +                else if (string.IsNullOrEmpty(this.Myself?.Address) == false)
  15.342 +                {
  15.343 +                    userName = this.Myself.Address;
  15.344 +                }
  15.345 +
  15.346 +                return userName;
  15.347 +            }
  15.348 +        }
  15.349 +
  15.350          #endregion
  15.351  
  15.352          #region Event handlers
  15.353 @@ -318,39 +288,195 @@
  15.354           * 
  15.355           *************************************************************/
  15.356  
  15.357 +        /// <summary>
  15.358 +        /// Event handler for when the OK/Next button is clicked.
  15.359 +        /// </summary>
  15.360 +        private void AcceptButton_Click(object sender, RoutedEventArgs e)
  15.361 +        {
  15.362 +            this.CurrentState.AcceptButtonClick();
  15.363 +        }
  15.364 +
  15.365 +        /// <summary>
  15.366 +        /// Event handler for when the Back button is clicked.
  15.367 +        /// </summary>
  15.368 +        private void BackButton_Click(object sender, RoutedEventArgs e)
  15.369 +        {
  15.370 +            this.CurrentState.BackButtonClick();
  15.371 +        }
  15.372 +
  15.373 +        /// <summary>
  15.374 +        /// Event handler for when the Cancel button is clicked.
  15.375 +        /// </summary>
  15.376          private void CancelButton_Click(object sender, RoutedEventArgs e)
  15.377          {
  15.378 -            this.Close();
  15.379 +            this.CurrentState.CancelButtonClick();
  15.380          }
  15.381  
  15.382 -        private void OKNextButton_Click(object sender, RoutedEventArgs e)
  15.383 +        /// <summary>
  15.384 +        /// Event handler for when a sync message arrives while the wizard is open and in progress.
  15.385 +        /// </summary>
  15.386 +        private void KeySyncWizard_SyncMessageReceived(object sender, MsgProcessor.SyncMessageEventArgs e)
  15.387          {
  15.388 -            // Navigation logic
  15.389 -            switch (this.State)
  15.390 +            // Ignore outgoing messages
  15.391 +            if (e.Message?.Direction == pEpMsgDirection.pEpDirIncoming)
  15.392              {
  15.393 -                case WizardState.Step2:
  15.394 +                try
  15.395 +                {
  15.396 +                    // Waiting for message with public key from other device
  15.397 +                    if (((this.Type == WizardType.pEp) && (this.Step == Steps.Step1)) ||
  15.398 +                        ((this.Type == WizardType.PGP) && (this.Step == Steps.Step4)))
  15.399                      {
  15.400 -                        // User accepts the fingerprint. Make channel green.
  15.401 -                        this.TrustKey();
  15.402 +                        string partnerFpr = null;
  15.403 +
  15.404 +                        // Make sure the channel is not already trusted (either attack or re-processing)
  15.405 +                        if (e.Message?.Rating >= pEpRating.pEpRatingTrusted)
  15.406 +                        {
  15.407 +                            Log.Warning("KeySyncWizard_SyncMessageReceived: Sync message for already trusted channel received.");
  15.408 +                            return;
  15.409 +                        }
  15.410 +
  15.411 +                        // In case of pEp sync, use header
  15.412 +                        if (this.Type == WizardType.pEp)
  15.413 +                        {
  15.414 +                            // Public key message received. Show trustwords.
  15.415 +                            partnerFpr = e.Message?.KeyImport;
  15.416 +
  15.417 +                            Log.Verbose("KeySyncWizard_SyncMessageReceived: pEp import, partner fingerprint is " + partnerFpr);
  15.418 +
  15.419 +                            // Doublecheck that it's not the own key
  15.420 +                            if (this.Myself?.Fingerprint?.Equals(partnerFpr) == true)
  15.421 +                            {
  15.422 +                                partnerFpr = null;
  15.423 +                            }
  15.424 +                        }
  15.425 +                        else if (this.Type == WizardType.PGP)
  15.426 +                        {
  15.427 +                            // In case of PGP import, use key list
  15.428 +                            string[] keys = e.Message?.KeyList?.Split(',');
  15.429 +                            for (int i = 0; i < keys?.Length; i++)
  15.430 +                            {
  15.431 +                                if (keys[i]?.Equals(this.Myself?.Fingerprint) == false)
  15.432 +                                {
  15.433 +                                    partnerFpr = keys[i];
  15.434 +                                    Log.Verbose("KeySyncWizard_SyncMessageReceived: PGP import, partner fingerprint is " + partnerFpr ?? "null");
  15.435 +                                    break;
  15.436 +                                }
  15.437 +                            }
  15.438 +                        }
  15.439 +                        else
  15.440 +                        {
  15.441 +                            Log.Error("KeySyncWizard_SyncMessageReceived: WizardType unknown.");
  15.442 +                        }
  15.443 +
  15.444 +                        // If we have a valid fingerprint, show Trustwords
  15.445 +                        if ((this.IsInitiator) &&
  15.446 +                            (string.IsNullOrEmpty(partnerFpr) == false))
  15.447 +                        {
  15.448 +                            // Set the partner's fingerprint
  15.449 +                            this.Partner.Fingerprint = partnerFpr;
  15.450 +
  15.451 +                            // Marshall to main thread
  15.452 +                            this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
  15.453 +                            {
  15.454 +                                // Create the handshake item 
  15.455 +                                if (this.CreateHandshakeItem())
  15.456 +                                {
  15.457 +                                    this.GoToNextStep();
  15.458 +                                }
  15.459 +                                else
  15.460 +                                {
  15.461 +                                    Log.Error("KeySyncWizard_SyncMessageReceived: Error creating handshake item.");
  15.462 +                                    this.GoToLastStep(false);
  15.463 +                                }
  15.464 +                            }));
  15.465 +                        }
  15.466 +                        else
  15.467 +                        {
  15.468 +                            Log.Error("KeySyncWizard_SyncMessageReceived: Partner fingerprint is null.");
  15.469 +                        }
  15.470                      }
  15.471 -                    break;
  15.472 -                /* 'Step 1' and 'Step 3' are not clickable. 
  15.473 -                 * 'Step 4' finishes the process. 
  15.474 -                 * 'Undefined' means an error occured.
  15.475 -                 */
  15.476 -                case WizardState.Step1:
  15.477 -                case WizardState.Step3:
  15.478 -                case WizardState.Step4:
  15.479 -                case WizardState.Undefined:
  15.480 -                default:
  15.481 +                    // Waiting for private key message
  15.482 +                    else if (((this.Type == WizardType.pEp) && (this.Step == Steps.Step3)) ||
  15.483 +                             ((this.Type == WizardType.PGP) && (this.Step == Steps.Step8)))
  15.484                      {
  15.485 -                        this.Close();
  15.486 +                        /* Finish the process under the following conditions:
  15.487 +                         *  1. PGP key import + own private key flag
  15.488 +                         *  2. pEp key import +
  15.489 +                         *      a. initiator wizard + own private key flag + partner fpr in key import header
  15.490 +                         *      b. not initiator wizard + trusted message + partner fpr in key import header
  15.491 +                         */
  15.492 +                        bool hasDecryptFlagOwnPrivateKey = e.Flags.HasFlag(pEpDecryptFlags.pEpDecryptFlagOwnPrivateKey);
  15.493 +                        if (((this.Type == WizardType.PGP) && (hasDecryptFlagOwnPrivateKey)) ||
  15.494 +                            ((this.IsInitiator) && (e.Message.KeyImport?.Equals(this.Partner?.Fingerprint) == true) && (hasDecryptFlagOwnPrivateKey)) ||
  15.495 +                            ((this.IsInitiator == false) && (e.Message.KeyImport?.Equals(this.Partner?.Fingerprint) == true) && (e.Message.Rating >= pEpRating.pEpRatingTrusted)))
  15.496 +                        {
  15.497 +                            // Set flag
  15.498 +                            this.privateKeyImported = hasDecryptFlagOwnPrivateKey;
  15.499 +
  15.500 +                            // Marshall to main thread
  15.501 +                            this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
  15.502 +                            {
  15.503 +                                // Set private key as default if needed
  15.504 +                                bool success = false;
  15.505 +                                if ((this.IsInitiator) &&
  15.506 +                                    (this.SetImportedKeyAsDefault))
  15.507 +                                {
  15.508 +                                    try
  15.509 +                                    {
  15.510 +                                        pEpIdentity partner = this.Partner.ToCOMType();
  15.511 +                                        ThisAddIn.PEPEngine.SetOwnKey(partner, partner.fpr);
  15.512 +                                        success = true;
  15.513 +                                    }
  15.514 +                                    catch (Exception ex)
  15.515 +                                    {
  15.516 +                                        success = false;
  15.517 +                                        Log.Error("AcceptButtonClick: Error setting own key. " + ex.ToString());
  15.518 +                                    }
  15.519 +                                }
  15.520 +                                else
  15.521 +                                {
  15.522 +                                    success = true;
  15.523 +                                }
  15.524 +
  15.525 +                                this.GoToLastStep(success);
  15.526 +
  15.527 +                            }));
  15.528 +                        }
  15.529 +                        else
  15.530 +                        {
  15.531 +                            Log.Verbose("KeySyncWizard_SyncMessageReceived: Message not processed. Steps: Step 3. Own private key flag is " +
  15.532 +                                        e.Flags.HasFlag(pEpDecryptFlags.pEpDecryptFlagOwnPrivateKey).ToString() + ". Rating is " +
  15.533 +                                        Enum.GetName(typeof(pEpRating), e.Message?.Rating ?? pEpRating.pEpRatingUndefined) + ". KeyImport is " +
  15.534 +                                        e.Message?.KeyImport ?? "null");
  15.535 +                        }
  15.536                      }
  15.537 -                    break;
  15.538 +                }
  15.539 +                catch (Exception ex)
  15.540 +                {
  15.541 +                    Log.Error("KeySyncWizard_SyncMessageReceived: Error processing sync message. " + ex.ToString());
  15.542 +                }
  15.543              }
  15.544          }
  15.545  
  15.546          /// <summary>
  15.547 +        /// Event handler for when the label next to the Export Private Key checkbox
  15.548 +        /// is clicked.
  15.549 +        /// </summary>
  15.550 +        private void LabelExportPrivateKey_MouseUp(object sender, MouseButtonEventArgs e)
  15.551 +        {
  15.552 +            this.ExportPrivateKey = (this.ExportPrivateKey == false);
  15.553 +        }
  15.554 +
  15.555 +        /// <summary>
  15.556 +        /// Event handler for when the label next to the Set Imported Key As Default checkbox
  15.557 +        /// is clicked.
  15.558 +        /// </summary>
  15.559 +        private void LabelSetImportedKeyAsDefault_MouseUp(object sender, MouseButtonEventArgs e)
  15.560 +        {
  15.561 +            this.SetImportedKeyAsDefault = (this.SetImportedKeyAsDefault == false);
  15.562 +        }
  15.563 +
  15.564 +        /// <summary>
  15.565          /// Raises the property changed event, if possible, with the given arguments.
  15.566          /// </summary>
  15.567          /// <param name="propertyName">The name of the property that changed.</param>
  15.568 @@ -361,127 +487,40 @@
  15.569          }
  15.570  
  15.571          /// <summary>
  15.572 -        /// Event handler for when a sync message arrives while the wizard is open and in progress.
  15.573 +        /// Shows the handshake window
  15.574          /// </summary>
  15.575 -        private void KeySyncWizard_SyncMessageReceived(object sender, MsgProcessor.SyncMessageEventArgs e)
  15.576 +        private bool ShowHandshake()
  15.577          {
  15.578 -            // Ignore outgoing messages
  15.579 -            if (e.Message?.Direction == pEpMsgDirection.pEpDirIncoming)
  15.580 +            bool success = false;
  15.581 +
  15.582 +            try
  15.583              {
  15.584 -                try
  15.585 +                // Update own identity if necessary
  15.586 +                if (string.IsNullOrEmpty(this.Myself?.Fingerprint))
  15.587                  {
  15.588 -                    switch (this.State)
  15.589 -                    {
  15.590 -                        // Step 1: get partner fingerprint and show Trustwords
  15.591 -                        case WizardState.Step1:
  15.592 -                            {
  15.593 -                                string partnerFpr = null;
  15.594 +                    this.Myself = new PEPIdentity(ThisAddIn.PEPEngine.Myself(this.Myself.ToCOMType()));
  15.595 +                }
  15.596  
  15.597 -                                // Make sure the channel is not already trusted (either attack or re-processing)
  15.598 -                                if (e.Message?.Rating >= pEpRating.pEpRatingTrusted)
  15.599 -                                {
  15.600 -                                    Log.Warning("KeySyncWizard_SyncMessageReceived: Sync message for already trusted channel received.");
  15.601 -                                    return;
  15.602 -                                }
  15.603 +                // Create handshake item
  15.604 +                if (this.CreateHandshakeItem())
  15.605 +                {
  15.606 +                    // Set success flag
  15.607 +                    success = true;
  15.608  
  15.609 -                                // In case of pEp sync, use header
  15.610 -                                if (this.Type == WizardType.pEp)
  15.611 -                                {
  15.612 -                                    // Public key message received. Show trustwords.
  15.613 -                                    partnerFpr = e.Message?.KeyImport;
  15.614 -
  15.615 -                                    Log.Verbose("KeySyncWizard_SyncMessageReceived: pEp import, partner fingerprint is " + partnerFpr);
  15.616 -
  15.617 -                                    // Doublecheck that it's not the own key
  15.618 -                                    if (this.Myself?.Fingerprint?.Equals(partnerFpr) == true)
  15.619 -                                    {
  15.620 -                                        partnerFpr = null;
  15.621 -                                    }
  15.622 -                                }
  15.623 -                                else if (this.Type == WizardType.PGP)
  15.624 -                                {
  15.625 -                                    // In case of PGP import, use key list
  15.626 -                                    string[] keys = e.Message?.KeyList?.Split(',');
  15.627 -                                    for (int i = 0; i < keys?.Length; i++)
  15.628 -                                    {
  15.629 -                                        if (keys[i]?.Equals(this.Myself?.Fingerprint) == false)
  15.630 -                                        {
  15.631 -                                            partnerFpr = keys[i];
  15.632 -                                            Log.Verbose("KeySyncWizard_SyncMessageReceived: PGP import, partner fingerprint is " + partnerFpr ?? "null");
  15.633 -                                            break;
  15.634 -                                        }
  15.635 -                                    }
  15.636 -                                }
  15.637 -                                else
  15.638 -                                {
  15.639 -                                    Log.Error("KeySyncWizard_SyncMessageReceived: WizardType unknown.");
  15.640 -                                }
  15.641 -
  15.642 -                                // If we have a valid fingerprint, show Trustwords
  15.643 -                                if (string.IsNullOrEmpty(partnerFpr) == false)
  15.644 -                                {
  15.645 -                                    // Set the partner's fingerprint
  15.646 -                                    this.Partner.Fingerprint = partnerFpr;
  15.647 -
  15.648 -                                    // Marshall to main thread
  15.649 -                                    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() =>
  15.650 -                                    {
  15.651 -                                        // Create the handshake item 
  15.652 -                                        if (this.CreateHandshakeItem())
  15.653 -                                        {
  15.654 -                                            this.GoToNextStep();
  15.655 -                                        }
  15.656 -                                        else
  15.657 -                                        {
  15.658 -                                            Log.Error("KeySyncWizard_SyncMessageReceived: Error creating handshake item.");
  15.659 -                                            this.GoToLastStep(false);
  15.660 -                                        }
  15.661 -                                    }));
  15.662 -                                }
  15.663 -                                else
  15.664 -                                {
  15.665 -                                    Log.Error("KeySyncWizard_SyncMessageReceived: Partner fingerprint is null.");
  15.666 -                                }
  15.667 -                            }
  15.668 -                            break;
  15.669 -                        case WizardState.Step2:
  15.670 -                            {
  15.671 -                                Log.Verbose("KeySyncWizard_SyncMessageReceived: Nothing done. WizardState is Step 2.");
  15.672 -                            }
  15.673 -                            break;
  15.674 -                        case WizardState.Step3:
  15.675 -                            {
  15.676 -                                /* Finish the process if a private key has been imported and the message
  15.677 -                                 * is at least trusted.
  15.678 -                                 * For pEp key import, check also that we don't import our own key.
  15.679 -                                 */ 
  15.680 -                                if ((e.Flags.HasFlag(pEpDecryptFlags.pEpDecryptFlagOwnPrivateKey)) &&
  15.681 -                                    (e.Message.Rating >= pEpRating.pEpRatingTrusted) &&
  15.682 -                                    ((e.Message.KeyImport?.Equals(this.Partner?.Fingerprint) == true) ||
  15.683 -                                     (this.Type == WizardType.PGP)))
  15.684 -                                {
  15.685 -                                    this.CompleteWizard();
  15.686 -                                }
  15.687 -                                else
  15.688 -                                {
  15.689 -                                    Log.Verbose("KeySyncWizard_SyncMessageReceived: Message not processed. WizardState: Step 3. Own private key flag is " +
  15.690 -                                                e.Flags.HasFlag(pEpDecryptFlags.pEpDecryptFlagOwnPrivateKey).ToString() + ". Rating is " +
  15.691 -                                                Enum.GetName(typeof(pEpRating), e.Message?.Rating ?? pEpRating.pEpRatingUndefined) + ". KeyImport is " +
  15.692 -                                                e.Message?.KeyImport ?? "null");
  15.693 -                                }
  15.694 -                            }
  15.695 -                            break;
  15.696 -                        case WizardState.Step4:
  15.697 -                        case WizardState.Undefined:
  15.698 -                        default:
  15.699 -                            break;
  15.700 -                    }
  15.701 +                    // Send answer message with pub key
  15.702 +                    this.SendSyncMessage(MessageTypes.PublicKeyMessage);
  15.703                  }
  15.704 -                catch (Exception ex)
  15.705 +                else
  15.706                  {
  15.707 -                    Log.Error("KeySyncWizard_SyncMessageReceived: Error processing sync message. " + ex.ToString());
  15.708 +                    Log.Error("KeySyncWizard: Error creating handshake item.");
  15.709                  }
  15.710              }
  15.711 +            catch (Exception ex)
  15.712 +            {
  15.713 +                Log.Error("KeySyncWizard: Error updating Myself. " + ex.ToString());
  15.714 +            }
  15.715 +
  15.716 +            return success;
  15.717          }
  15.718  
  15.719          /// <summary>
  15.720 @@ -506,18 +545,71 @@
  15.721           *************************************************************/
  15.722  
  15.723          /// <summary>
  15.724 +        /// Adds the given PEPMessage to the list of received sync messages.
  15.725 +        /// </summary>
  15.726 +        /// <param name="message">The PEPMessage to add to the list.</param>
  15.727 +        public void AddToReceivedSyncMessages(PEPMessage message)
  15.728 +        {
  15.729 +            /* Add message to list if:
  15.730 +             *  1.  a. WizardType is PGP and message is secure
  15.731 +             *      b. WizardType is pEp, the current step is Step 2 and the
  15.732 +             *         message hasn't been sent from myself
  15.733 +             *  2. Message is not in the list yet
  15.734 +             *  3. List has max 5 items
  15.735 +             */
  15.736 +            lock (mutexReceivedSyncMessages)
  15.737 +            {
  15.738 +                if (((this.Type == WizardType.PGP) &&
  15.739 +                     (message.IsSecure) ||
  15.740 +                     ((this.Type == WizardType.pEp) &&
  15.741 +                      (this.Step == Steps.Step2) &&
  15.742 +                      (this.Myself?.Fingerprint?.Equals(message?.KeyImport) == false))) &&
  15.743 +                    (this.receivedSyncMessages?.Find(a => (a.Id?.Equals(message.Id) == true)) == null) &&
  15.744 +                    (this.receivedSyncMessages?.Count <= 5))
  15.745 +                {
  15.746 +                    this.receivedSyncMessages?.Add(message);
  15.747 +                }
  15.748 +            }
  15.749 +        }
  15.750 +
  15.751 +        /// <summary>
  15.752 +        /// Closes the wizard and resets the partner identity in the management.db.
  15.753 +        /// </summary>
  15.754 +        private void CancelWizard()
  15.755 +        {
  15.756 +            try
  15.757 +            {
  15.758 +                pEpIdentity partner = this.Partner.Copy().ToCOMType();
  15.759 +
  15.760 +                if (string.IsNullOrEmpty(partner.fpr) == false)
  15.761 +                {
  15.762 +                    Task.Factory.StartNew(new Action(() =>
  15.763 +                    {
  15.764 +                        ThisAddIn.PEPEngine.KeyResetTrust(partner);
  15.765 +                    }), TaskCreationOptions.LongRunning);
  15.766 +                }
  15.767 +            }
  15.768 +            catch (Exception ex)
  15.769 +            {
  15.770 +                Log.Error("CancelWizard: Error resetting identity. " + ex.ToString());
  15.771 +            }
  15.772 +
  15.773 +            this.Close();
  15.774 +        }
  15.775 +
  15.776 +        /// <summary>
  15.777          /// Completes the process and moves wizard to last step.
  15.778          /// Sets the imported private key as own key, if needed.
  15.779          /// </summary>
  15.780          private void CompleteWizard()
  15.781          {
  15.782              // Marshall to main thread
  15.783 -            this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() =>
  15.784 +            this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
  15.785              {
  15.786                  bool success = false;
  15.787  
  15.788                  // Private key message received. Set key as default if needed.
  15.789 -                if (this.isInitiator)
  15.790 +                if (this.IsInitiator)
  15.791                  {
  15.792                      try
  15.793                      {
  15.794 @@ -553,9 +645,10 @@
  15.795              HandshakeItem item;
  15.796              if (HandshakeItem.Create(this.Myself, this.Partner, false, out item) == Globals.ReturnStatus.Success)
  15.797              {
  15.798 -                item.AreTabControlsVisible = (this.Type == WizardType.PGP);
  15.799 +                item.AreTabControlsVisible = false;
  15.800                  item.ActiveTab = (this.Type == WizardType.pEp) ? HandshakeItem.Tabs.Trustwords : HandshakeItem.Tabs.Fingerprint;
  15.801                  item.AreHandshakeButtonsVisible = false;
  15.802 +                item.Mode = HandshakeItem.HandshakeMode.Sync;
  15.803                  this.Items.Add(item);
  15.804  
  15.805                  success = true;
  15.806 @@ -566,17 +659,658 @@
  15.807          }
  15.808  
  15.809          /// <summary>
  15.810 +        /// Creates a list of wizard states that serve as model for the wizard.
  15.811 +        /// The pEp Key Import process consists of the following steps:
  15.812 +        ///     Step 1:
  15.813 +        ///         a. Is initiator(user opened wizard): Info message that sync message has been sent.
  15.814 +        ///            Waiting for answer message from other device.
  15.815 +        ///         b. Is not initiator (wizard opened through sync message): Info message that key import has been started.
  15.816 +        ///            Waiting for user decision to continue or abort.
  15.817 +        ///     Step 2:
  15.818 +        ///         - Show trustwords. User interaction: confirm or cancel.
  15.819 +        ///     Step 3: 
  15.820 +        ///         - Private keys have been sent. Waiting for answer message from other device.
  15.821 +        ///     Step 4: 
  15.822 +        ///         - Only on initiator side: Ask user if they want to set imported key as default. Next or Cancel.
  15.823 +        ///     Success:
  15.824 +        ///         - Key Import successfully finished.
  15.825 +        ///     Error:
  15.826 +        ///         - An error occured during the Key Import process.
  15.827 +        /// </summary>
  15.828 +        /// <returns>The list of wizard states.</returns>
  15.829 +        private List<WizardState> CreatePEPWizardStates()
  15.830 +        {
  15.831 +            List<WizardState> states = new List<WizardState>();
  15.832 +
  15.833 +            try
  15.834 +            {
  15.835 +                // Step 1
  15.836 +                states.Add(new WizardState
  15.837 +                {
  15.838 +                    // Step
  15.839 +                    Step = Steps.Step1,
  15.840 +
  15.841 +                    // Title text
  15.842 +                    TitleText = this.IsInitiator ? Properties.Resources.KeySyncWizard_PEPStep1ExplanationText : Properties.Resources.KeySyncWizard_PEPStep1NonInitiatorExplanationText,
  15.843 +
  15.844 +                    // Central area
  15.845 +                    AreTrustwordsVisible = false,
  15.846 +                    IsUserTextVisible = true,
  15.847 +                    UserText = this.UserName,
  15.848 +
  15.849 +                    // Back button
  15.850 +                    IsBackButtonVisible = false,
  15.851 +
  15.852 +                    // Accept button
  15.853 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Start,
  15.854 +                    IsAcceptButtonVisible = (this.IsInitiator == false),
  15.855 +                    AcceptButtonClick = new Action(() =>
  15.856 +                    {
  15.857 +                        if (this.ShowHandshake())
  15.858 +                        {
  15.859 +                            this.GoToNextStep();
  15.860 +                        }
  15.861 +                        else
  15.862 +                        {
  15.863 +                            this.GoToLastStep(false);
  15.864 +                        }
  15.865 +                    }),
  15.866 +
  15.867 +                    // Cancel button
  15.868 +                    CancelButtonText = Properties.Resources.Options_CancelText,
  15.869 +                    IsCancelButtonVisible = true,
  15.870 +                    CancelButtonClick = new Action(() =>
  15.871 +                    {
  15.872 +                        this.CancelWizard();
  15.873 +                    }),
  15.874 +
  15.875 +                    // Subtitle area
  15.876 +                    SubtitleText = this.IsInitiator ? Properties.Resources.KeySyncWizard_WaitingForResponseText : null
  15.877 +                });
  15.878 +
  15.879 +                // Step 2
  15.880 +                states.Add(new WizardState
  15.881 +                {
  15.882 +                    // Step
  15.883 +                    Step = Steps.Step2,
  15.884 +
  15.885 +                    // Title text
  15.886 +                    TitleText = Properties.Resources.KeySyncWizard_PEPStep2ExplanationText,
  15.887 +
  15.888 +                    // Central area
  15.889 +                    AreTrustwordsVisible = true,
  15.890 +                    IsUserTextVisible = false,
  15.891 +
  15.892 +                    // Back button
  15.893 +                    IsBackButtonVisible = false,
  15.894 +
  15.895 +                    // Accept button
  15.896 +                    AcceptButtonText = Properties.Resources.Handshake_ConfirmTrustwords,
  15.897 +                    IsAcceptButtonVisible = true,
  15.898 +                    AcceptButtonClick = new Action(() =>
  15.899 +                    {
  15.900 +                        this.GoToNextStep();
  15.901 +                        this.TrustKey();
  15.902 +                    }),
  15.903 +
  15.904 +                    // Cancel button
  15.905 +                    CancelButtonText = Properties.Resources.Handshake_WrongTrustwords,
  15.906 +                    IsCancelButtonVisible = true,
  15.907 +                    CancelButtonClick = new Action(() =>
  15.908 +                    {
  15.909 +                        this.CancelWizard();
  15.910 +                    }),
  15.911 +
  15.912 +                    // Subtitle area
  15.913 +                    SubtitleText = null
  15.914 +                });
  15.915 +
  15.916 +                // Step 3
  15.917 +                states.Add(new WizardState
  15.918 +                {
  15.919 +                    // Step
  15.920 +                    Step = Steps.Step3,
  15.921 +
  15.922 +                    // Title text
  15.923 +                    TitleText = Properties.Resources.KeySyncWizard_PEPStep3ExplanationText,
  15.924 +
  15.925 +                    // Central area
  15.926 +                    AreTrustwordsVisible = false,
  15.927 +                    IsUserTextVisible = true,
  15.928 +                    UserText = this.UserName,
  15.929 +
  15.930 +                    // Back button
  15.931 +                    IsBackButtonVisible = false,
  15.932 +
  15.933 +                    // Accept button
  15.934 +                    IsAcceptButtonVisible = false,
  15.935 +
  15.936 +                    // Cancel button
  15.937 +                    CancelButtonText = Properties.Resources.Options_CancelText,
  15.938 +                    IsCancelButtonVisible = true,
  15.939 +                    CancelButtonClick = new Action(() =>
  15.940 +                    {
  15.941 +                        this.CancelWizard();
  15.942 +                    }),
  15.943 +
  15.944 +                    // Subtitle area
  15.945 +                    SubtitleText = Properties.Resources.KeySyncWizard_WaitingForResponseText
  15.946 +                });
  15.947 +
  15.948 +                // Success
  15.949 +                states.Add(new WizardState
  15.950 +                {
  15.951 +                    // Step
  15.952 +                    Step = Steps.Success,
  15.953 +
  15.954 +                    // Title text
  15.955 +                    TitleText = null,
  15.956 +
  15.957 +                    // Central area
  15.958 +                    AreTrustwordsVisible = false,
  15.959 +                    IsUserTextVisible = true,
  15.960 +                    UserText = this.UserName,
  15.961 +
  15.962 +                    // Back button
  15.963 +                    IsBackButtonVisible = false,
  15.964 +
  15.965 +                    // Accept button
  15.966 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Finish,
  15.967 +                    IsAcceptButtonVisible = true,
  15.968 +                    AcceptButtonClick = new Action(() =>
  15.969 +                    {
  15.970 +                        this.Close();
  15.971 +                    }),
  15.972 +
  15.973 +                    // Cancel button
  15.974 +                    IsCancelButtonVisible = false,
  15.975 +
  15.976 +                    // Subtitle area
  15.977 +                    SubtitleText = null
  15.978 +                });
  15.979 +
  15.980 +                // Error
  15.981 +                states.Add(new WizardState
  15.982 +                {
  15.983 +                    // Step
  15.984 +                    Step = Steps.Error,
  15.985 +
  15.986 +                    // Title text
  15.987 +                    TitleText = Properties.Resources.KeySyncWizard_ErrorExplanationText,
  15.988 +
  15.989 +                    // Central area
  15.990 +                    AreTrustwordsVisible = false,
  15.991 +                    IsUserTextVisible = true,
  15.992 +                    UserText = this.UserName,
  15.993 +
  15.994 +                    // Back button
  15.995 +                    IsBackButtonVisible = false,
  15.996 +
  15.997 +                    // Accept button
  15.998 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Finish,
  15.999 +                    IsAcceptButtonVisible = true,
 15.1000 +                    AcceptButtonClick = new Action(() =>
 15.1001 +                    {
 15.1002 +                        this.CancelWizard();
 15.1003 +                    }),
 15.1004 +
 15.1005 +                    // Cancel button
 15.1006 +                    IsCancelButtonVisible = false,
 15.1007 +
 15.1008 +                    // Subtitle area
 15.1009 +                    SubtitleText = null
 15.1010 +                });
 15.1011 +            }
 15.1012 +            catch (Exception ex)
 15.1013 +            {
 15.1014 +                states = null;
 15.1015 +                Log.Error("CreateWizardStates: Error creating wizard states. " + ex.ToString());
 15.1016 +            }
 15.1017 +
 15.1018 +            return states;
 15.1019 +        }
 15.1020 +
 15.1021 +        /// <summary>
 15.1022 +        /// Creates a list of wizard states that serve as model for the wizard.
 15.1023 +        /// The PGP Key Import process consists of the following steps:
 15.1024 +        ///     Steps 1-3:
 15.1025 +        ///         - Instructions on how to prepare the answer message with pub key.
 15.1026 +        ///     Step 4: 
 15.1027 +        ///         - Waiting for answer message from other device.
 15.1028 +        ///     Step 5: 
 15.1029 +        ///         - Show fingerprints. Confirm or deny them.        
 15.1030 +        ///     Step 6 - 7: 
 15.1031 +        ///         - Instructions on how to prepare the answer message with private key.
 15.1032 +        ///     Success:
 15.1033 +        ///         - Key Import successfully finished.
 15.1034 +        ///     Error:
 15.1035 +        ///         - An error occured during the Key Import process.
 15.1036 +        /// </summary>
 15.1037 +        /// <returns>The list of wizard states.</returns>
 15.1038 +        private List<WizardState> CreatePGPWizardStates()
 15.1039 +        {
 15.1040 +            List<WizardState> states = new List<WizardState>();
 15.1041 +
 15.1042 +            try
 15.1043 +            {
 15.1044 +                // Step 1
 15.1045 +                states.Add(new WizardState
 15.1046 +                {
 15.1047 +                    // Step
 15.1048 +                    Step = Steps.Step1,
 15.1049 +
 15.1050 +                    // Title text
 15.1051 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep1ExplanationText,
 15.1052 +
 15.1053 +                    // Central area
 15.1054 +                    AreTrustwordsVisible = false,
 15.1055 +                    IsUserTextVisible = true,
 15.1056 +                    UserText = this.UserName,
 15.1057 +
 15.1058 +                    // Back button
 15.1059 +                    IsBackButtonVisible = false,
 15.1060 +
 15.1061 +                    // Accept button
 15.1062 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Next,
 15.1063 +                    IsAcceptButtonVisible = true,
 15.1064 +                    AcceptButtonClick = new Action(() =>
 15.1065 +                    {
 15.1066 +                        this.GoToNextStep();
 15.1067 +                    }),
 15.1068 +
 15.1069 +                    // Cancel button
 15.1070 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 15.1071 +                    IsCancelButtonVisible = true,
 15.1072 +                    CancelButtonClick = new Action(() =>
 15.1073 +                    {
 15.1074 +                        this.CancelWizard();
 15.1075 +                    }),
 15.1076 +
 15.1077 +                    // Subtitle area
 15.1078 +                    SubtitleText = null
 15.1079 +                });
 15.1080 +
 15.1081 +                // Step 2
 15.1082 +                states.Add(new WizardState
 15.1083 +                {
 15.1084 +                    // Step
 15.1085 +                    Step = Steps.Step2,
 15.1086 +
 15.1087 +                    // Title text
 15.1088 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep2ExplanationText,
 15.1089 +
 15.1090 +                    // Central area
 15.1091 +                    AreTrustwordsVisible = false,
 15.1092 +                    IsUserTextVisible = true,
 15.1093 +                    UserText = this.UserName,
 15.1094 +
 15.1095 +                    // Back button
 15.1096 +                    IsBackButtonVisible = true,
 15.1097 +                    BackButtonClick = new Action(() =>
 15.1098 +                    {
 15.1099 +                        this.GoToPreviousStep();
 15.1100 +                    }),
 15.1101 +
 15.1102 +                    // Accept button
 15.1103 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Next,
 15.1104 +                    IsAcceptButtonVisible = true,
 15.1105 +                    AcceptButtonClick = new Action(() =>
 15.1106 +                    {
 15.1107 +                        this.GoToNextStep();
 15.1108 +                    }),
 15.1109 +
 15.1110 +                    // Cancel button
 15.1111 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 15.1112 +                    IsCancelButtonVisible = true,
 15.1113 +                    CancelButtonClick = new Action(() =>
 15.1114 +                    {
 15.1115 +                        this.CancelWizard();
 15.1116 +                    }),
 15.1117 +
 15.1118 +                    // Subtitle area
 15.1119 +                    SubtitleText = null
 15.1120 +                });
 15.1121 +
 15.1122 +                // Step 3
 15.1123 +                states.Add(new WizardState
 15.1124 +                {
 15.1125 +                    // Step
 15.1126 +                    Step = Steps.Step3,
 15.1127 +
 15.1128 +                    // Title text
 15.1129 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep3ExplanationText,
 15.1130 +
 15.1131 +                    // Central area
 15.1132 +                    AreTrustwordsVisible = false,
 15.1133 +                    IsUserTextVisible = true,
 15.1134 +                    UserText = this.UserName,
 15.1135 +
 15.1136 +                    // Back button
 15.1137 +                    IsBackButtonVisible = true,
 15.1138 +                    BackButtonClick = new Action(() =>
 15.1139 +                    {
 15.1140 +                        this.GoToPreviousStep();
 15.1141 +                    }),
 15.1142 +
 15.1143 +                    // Accept button
 15.1144 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Next,
 15.1145 +                    IsAcceptButtonVisible = true,
 15.1146 +                    AcceptButtonClick = new Action(() =>
 15.1147 +                    {
 15.1148 +                        this.GoToNextStep();
 15.1149 +                        this.ProcessReceivedSyncMessages();
 15.1150 +                    }),
 15.1151 +
 15.1152 +                    // Cancel button
 15.1153 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 15.1154 +                    IsCancelButtonVisible = true,
 15.1155 +                    CancelButtonClick = new Action(() =>
 15.1156 +                    {
 15.1157 +                        this.CancelWizard();
 15.1158 +                    }),
 15.1159 +
 15.1160 +                    // Subtitle area
 15.1161 +                    SubtitleText = null
 15.1162 +                });
 15.1163 +
 15.1164 +                // Step 4
 15.1165 +                states.Add(new WizardState
 15.1166 +                {
 15.1167 +                    // Step
 15.1168 +                    Step = Steps.Step4,
 15.1169 +
 15.1170 +                    // Title text
 15.1171 +                    TitleText = Properties.Resources.KeySyncWizard_WaitingForResponseText,
 15.1172 +
 15.1173 +                    // Central area
 15.1174 +                    AreTrustwordsVisible = false,
 15.1175 +                    IsUserTextVisible = true,
 15.1176 +                    UserText = this.UserName,
 15.1177 +
 15.1178 +                    // Back button
 15.1179 +                    // Back button
 15.1180 +                    IsBackButtonVisible = true,
 15.1181 +                    BackButtonClick = new Action(() =>
 15.1182 +                    {
 15.1183 +                        this.GoToPreviousStep();
 15.1184 +                    }),
 15.1185 +
 15.1186 +                    // Accept button
 15.1187 +                    IsAcceptButtonVisible = false,
 15.1188 +
 15.1189 +                    // Cancel button
 15.1190 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 15.1191 +                    IsCancelButtonVisible = true,
 15.1192 +                    CancelButtonClick = new Action(() =>
 15.1193 +                    {
 15.1194 +                        this.CancelWizard();
 15.1195 +                    }),
 15.1196 +
 15.1197 +                    // Subtitle area
 15.1198 +                    SubtitleText = null
 15.1199 +                });
 15.1200 +
 15.1201 +                // Step 5
 15.1202 +                states.Add(new WizardState
 15.1203 +                {
 15.1204 +                    // Step
 15.1205 +                    Step = Steps.Step5,
 15.1206 +
 15.1207 +                    // Title text
 15.1208 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep5ExplanationText,
 15.1209 +
 15.1210 +                    // Central area
 15.1211 +                    AreTrustwordsVisible = true,
 15.1212 +                    IsUserTextVisible = false,
 15.1213 +
 15.1214 +                    // Back button
 15.1215 +                    IsBackButtonVisible = false,
 15.1216 +
 15.1217 +                    // Accept button
 15.1218 +                    AcceptButtonText = Properties.Resources.Handshake_ConfirmFingerprint,
 15.1219 +                    IsAcceptButtonVisible = true,
 15.1220 +                    AcceptButtonClick = new Action(() =>
 15.1221 +                    {
 15.1222 +                        this.GoToNextStep();
 15.1223 +                        this.TrustKey();
 15.1224 +                    }),
 15.1225 +
 15.1226 +                    // Cancel button
 15.1227 +                    CancelButtonText = Properties.Resources.Handshake_WrongFingerprint,
 15.1228 +                    IsCancelButtonVisible = true,
 15.1229 +                    CancelButtonClick = new Action(() =>
 15.1230 +                    {
 15.1231 +                        this.CancelWizard();
 15.1232 +                    }),
 15.1233 +
 15.1234 +                    // Subtitle area
 15.1235 +                    SubtitleText = null
 15.1236 +                });
 15.1237 +
 15.1238 +                // Step 6
 15.1239 +                states.Add(new WizardState
 15.1240 +                {
 15.1241 +                    // Step
 15.1242 +                    Step = Steps.Step6,
 15.1243 +
 15.1244 +                    // Title text
 15.1245 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep6ExplanationText,
 15.1246 +
 15.1247 +                    // Central area
 15.1248 +                    AreTrustwordsVisible = false,
 15.1249 +                    IsUserTextVisible = true,
 15.1250 +                    UserText = this.UserName,
 15.1251 +
 15.1252 +                    // Back button
 15.1253 +                    IsBackButtonVisible = false,
 15.1254 +
 15.1255 +                    // Accept button
 15.1256 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Next,
 15.1257 +                    IsAcceptButtonVisible = true,
 15.1258 +                    AcceptButtonClick = new Action(() =>
 15.1259 +                    {
 15.1260 +                        this.GoToNextStep();
 15.1261 +                    }),
 15.1262 +
 15.1263 +                    // Cancel button
 15.1264 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 15.1265 +                    IsCancelButtonVisible = true,
 15.1266 +                    CancelButtonClick = new Action(() =>
 15.1267 +                    {
 15.1268 +                        this.CancelWizard();
 15.1269 +                    }),
 15.1270 +
 15.1271 +                    // Subtitle area
 15.1272 +                    SubtitleText = null
 15.1273 +                });
 15.1274 +
 15.1275 +                // Step 7
 15.1276 +                states.Add(new WizardState
 15.1277 +                {
 15.1278 +                    // Step
 15.1279 +                    Step = Steps.Step7,
 15.1280 +
 15.1281 +                    // Title text
 15.1282 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep7ExplanationText,
 15.1283 +
 15.1284 +                    // Central area
 15.1285 +                    AreTrustwordsVisible = false,
 15.1286 +                    IsUserTextVisible = true,
 15.1287 +                    UserText = this.UserName,
 15.1288 +
 15.1289 +                    // Back button
 15.1290 +                    IsBackButtonVisible = true,
 15.1291 +                    BackButtonClick = new Action(() =>
 15.1292 +                    {
 15.1293 +                        this.GoToPreviousStep();
 15.1294 +                    }),
 15.1295 +
 15.1296 +                    // Accept button
 15.1297 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Next,
 15.1298 +                    IsAcceptButtonVisible = true,
 15.1299 +                    AcceptButtonClick = new Action(() =>
 15.1300 +                    {
 15.1301 +                        this.GoToNextStep();
 15.1302 +                        this.ProcessReceivedSyncMessages();
 15.1303 +                    }),
 15.1304 +
 15.1305 +                    // Cancel button
 15.1306 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 15.1307 +                    IsCancelButtonVisible = true,
 15.1308 +                    CancelButtonClick = new Action(() =>
 15.1309 +                    {
 15.1310 +                        this.CancelWizard();
 15.1311 +                    }),
 15.1312 +
 15.1313 +                    // Subtitle area
 15.1314 +                    SubtitleText = null
 15.1315 +                });
 15.1316 +
 15.1317 +                // Step 8
 15.1318 +                states.Add(new WizardState
 15.1319 +                {
 15.1320 +                    // Step
 15.1321 +                    Step = Steps.Step8,
 15.1322 +
 15.1323 +                    // Title text
 15.1324 +                    TitleText = Properties.Resources.KeySyncWizard_WaitingForResponseText,
 15.1325 +
 15.1326 +                    // Central area
 15.1327 +                    AreTrustwordsVisible = false,
 15.1328 +                    IsUserTextVisible = true,
 15.1329 +                    UserText = this.UserName,
 15.1330 +
 15.1331 +                    // Back button
 15.1332 +                    IsBackButtonVisible = true,
 15.1333 +                    BackButtonClick = new Action(() =>
 15.1334 +                    {
 15.1335 +                        this.GoToPreviousStep();
 15.1336 +                    }),
 15.1337 +
 15.1338 +                    // Accept button
 15.1339 +                    IsAcceptButtonVisible = false,
 15.1340 +
 15.1341 +                    // Cancel button
 15.1342 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 15.1343 +                    IsCancelButtonVisible = true,
 15.1344 +                    CancelButtonClick = new Action(() =>
 15.1345 +                    {
 15.1346 +                        this.CancelWizard();
 15.1347 +                    }),
 15.1348 +
 15.1349 +                    // Subtitle area
 15.1350 +                    SubtitleText = null
 15.1351 +                });
 15.1352 +
 15.1353 +                // Success
 15.1354 +                states.Add(new WizardState
 15.1355 +                {
 15.1356 +                    // Step
 15.1357 +                    Step = Steps.Success,
 15.1358 +
 15.1359 +                    // Title text
 15.1360 +                    TitleText = Properties.Resources.KeySyncWizard_PGPSuccessExplanationText,
 15.1361 +
 15.1362 +                    // Central area
 15.1363 +                    AreTrustwordsVisible = false,
 15.1364 +                    IsUserTextVisible = true,
 15.1365 +                    UserText = this.UserName,
 15.1366 +
 15.1367 +                    // Back button
 15.1368 +                    IsBackButtonVisible = false,
 15.1369 +
 15.1370 +                    // Accept button
 15.1371 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Finish,
 15.1372 +                    IsAcceptButtonVisible = true,
 15.1373 +                    AcceptButtonClick = new Action(() =>
 15.1374 +                    {
 15.1375 +                        this.Close();
 15.1376 +                    }),
 15.1377 +
 15.1378 +                    // Cancel button
 15.1379 +                    IsCancelButtonVisible = false,
 15.1380 +
 15.1381 +                    // Subtitle area
 15.1382 +                    SubtitleText = null
 15.1383 +                });
 15.1384 +
 15.1385 +                // Error
 15.1386 +                states.Add(new WizardState
 15.1387 +                {
 15.1388 +                    // Step
 15.1389 +                    Step = Steps.Error,
 15.1390 +
 15.1391 +                    // Title text
 15.1392 +                    TitleText = Properties.Resources.KeySyncWizard_ErrorExplanationText,
 15.1393 +
 15.1394 +                    // Central area
 15.1395 +                    AreTrustwordsVisible = false,
 15.1396 +                    IsUserTextVisible = true,
 15.1397 +                    UserText = this.UserName,
 15.1398 +
 15.1399 +                    // Back button
 15.1400 +                    IsBackButtonVisible = false,
 15.1401 +
 15.1402 +                    // Accept button
 15.1403 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Finish,
 15.1404 +                    IsAcceptButtonVisible = true,
 15.1405 +                    AcceptButtonClick = new Action(() =>
 15.1406 +                    {
 15.1407 +                        this.CancelWizard();
 15.1408 +                    }),
 15.1409 +
 15.1410 +                    // Cancel button
 15.1411 +                    IsCancelButtonVisible = false,
 15.1412 +
 15.1413 +                    // Subtitle area
 15.1414 +                    SubtitleText = null
 15.1415 +                });
 15.1416 +            }
 15.1417 +            catch (Exception ex)
 15.1418 +            {
 15.1419 +                states = null;
 15.1420 +                Log.Error("CreateWizardStates: Error creating wizard states. " + ex.ToString());
 15.1421 +            }
 15.1422 +
 15.1423 +            return states;
 15.1424 +        }
 15.1425 +
 15.1426 +        /// <summary>
 15.1427          /// Navigates to the last step of the wizard.
 15.1428          /// </summary>
 15.1429          /// <param name="success">Whether or not the wizard has been completed successfully.</param>
 15.1430          private void GoToLastStep(bool success)
 15.1431          {
 15.1432              // Go to last step
 15.1433 -            this.State = WizardState.Step4;
 15.1434 -            this.Success = success;
 15.1435 +            this.Step = success ? Steps.Success : Steps.Error;
 15.1436  
 15.1437 -            // Update content
 15.1438 -            this.UpdateContent();
 15.1439 +            // Update wording and state
 15.1440 +            var lastState = this.states.Find(a => a.Step == this.Step);
 15.1441 +            if (this.IsInitiator)
 15.1442 +            {
 15.1443 +                if (this.SetImportedKeyAsDefault)
 15.1444 +                {
 15.1445 +                    lastState.TitleText = Properties.Resources.KeySyncWizard_PEPSuccessImport + "\n\n" + Properties.Resources.KeySyncWizard_PEPSuccessOtherKeyUsedAsDefault;
 15.1446 +                }
 15.1447 +                else
 15.1448 +                {
 15.1449 +                    lastState.TitleText = Properties.Resources.KeySyncWizard_PEPSuccessImport + "\n\n" + Properties.Resources.KeySyncWizard_PEPSuccessOtherKeyUsed;
 15.1450 +                }
 15.1451 +            }
 15.1452 +            else
 15.1453 +            {
 15.1454 +                if (this.privateKeyImported)
 15.1455 +                {
 15.1456 +                    lastState.TitleText = Properties.Resources.KeySyncWizard_PEPSuccessExport + "\n\n" + Properties.Resources.KeySyncWizard_PEPSuccessOtherKeyUsed;
 15.1457 +                }
 15.1458 +                else
 15.1459 +                {
 15.1460 +                    lastState.TitleText = Properties.Resources.KeySyncWizard_PEPSuccessExport;
 15.1461 +                }
 15.1462 +            }
 15.1463 +
 15.1464 +            // Apply state
 15.1465 +            this.CurrentState = lastState;
 15.1466  
 15.1467              Log.Verbose("GoToLastStep: Process finished. Success is " + success.ToString());
 15.1468          }
 15.1469 @@ -587,26 +1321,42 @@
 15.1470          private void GoToNextStep()
 15.1471          {
 15.1472              // Go to next step
 15.1473 -            this.State++;
 15.1474 +            this.Step++;
 15.1475  
 15.1476 -            // Update content
 15.1477 -            this.UpdateContent();
 15.1478 +            // Set current state
 15.1479 +            this.CurrentState = states.Find(a => a.Step == this.Step);
 15.1480  
 15.1481 -            Log.Verbose("GoToNextStep: New state: " + Enum.GetName(typeof(WizardState), this.State));
 15.1482 +            Log.Verbose("GoToNextStep: New state: " + Enum.GetName(typeof(Steps), this.Step));
 15.1483 +        }
 15.1484 +
 15.1485 +        /// <summary>
 15.1486 +        /// Navigates to the previous state of the wizard.
 15.1487 +        /// </summary>
 15.1488 +        private void GoToPreviousStep()
 15.1489 +        {
 15.1490 +            // Go to next step
 15.1491 +            this.Step--;
 15.1492 +
 15.1493 +            // Set current state
 15.1494 +            this.CurrentState = states.Find(a => a.Step == this.Step);
 15.1495 +
 15.1496 +            Log.Verbose("GoToPreviousStep: New state: " + Enum.GetName(typeof(Steps), this.Step));
 15.1497          }
 15.1498  
 15.1499          /// <summary>
 15.1500          /// Initializes the wizard.
 15.1501          /// </summary>
 15.1502 -        private void InitializeWizard(WizardType type,
 15.1503 +        private void InitializeWizard(bool isInitiator,
 15.1504 +                                      WizardType type,
 15.1505                                        PEPIdentity myself,
 15.1506                                        string partnerFpr)
 15.1507          {
 15.1508              // Set initial state
 15.1509              this.DataContext = this;
 15.1510              this.Myself = myself;
 15.1511 -            this.State = WizardState.Step1;
 15.1512 +            this.Step = Steps.Step1;
 15.1513              this.Type = type;
 15.1514 +            this.IsInitiator = isInitiator;
 15.1515  
 15.1516              // If own identity is null, get default account
 15.1517              if (this.Myself == null)
 15.1518 @@ -699,8 +1449,39 @@
 15.1519                  this.Partner.Fingerprint = partnerFpr;
 15.1520              }
 15.1521  
 15.1522 -            // Update dialog content
 15.1523 -            this.UpdateContent();
 15.1524 +            // Define states
 15.1525 +            this.states = (this.Type == WizardType.pEp) ? this.CreatePEPWizardStates() : this.CreatePGPWizardStates();
 15.1526 +
 15.1527 +            // Set current state
 15.1528 +            this.CurrentState = states?.Find(a => a.Step == Steps.Step1);
 15.1529 +        }
 15.1530 +
 15.1531 +        /// <summary>
 15.1532 +        /// Runs through all received sync messages.
 15.1533 +        /// </summary>
 15.1534 +        private void ProcessReceivedSyncMessages()
 15.1535 +        {
 15.1536 +            lock (mutexReceivedSyncMessages)
 15.1537 +            {
 15.1538 +                if (this.receivedSyncMessages != null)
 15.1539 +                {
 15.1540 +                    foreach (var message in this.receivedSyncMessages)
 15.1541 +                    {
 15.1542 +                        try
 15.1543 +                        {
 15.1544 +                            Task.Factory.StartNew(new Action(() =>
 15.1545 +                            {
 15.1546 +                                MsgProcessor msgProcessor = new MsgProcessor();
 15.1547 +                                msgProcessor.Decrypt(message);
 15.1548 +                            }));
 15.1549 +                        }
 15.1550 +                        catch (Exception ex)
 15.1551 +                        {
 15.1552 +                            Log.Error("ProcessReceivedSyncMessages: Error processing sync message. " + ex.ToString());
 15.1553 +                        }
 15.1554 +                    }
 15.1555 +                }
 15.1556 +            }
 15.1557          }
 15.1558  
 15.1559          /// <summary>
 15.1560 @@ -714,93 +1495,117 @@
 15.1561              {
 15.1562                  try
 15.1563                  {
 15.1564 -                    // If we have no partner at this point, use a copy of myself
 15.1565 -                    if (this.Partner == null)
 15.1566 +                    // Start sending in background
 15.1567 +                    Task.Factory.StartNew(new Action(() =>
 15.1568                      {
 15.1569 -                        this.Partner = this.Myself.Copy();
 15.1570 -                        Log.Verbose("SendSyncMessage: Partner was null. Using copy of myself.");
 15.1571 -                    }
 15.1572 +                        // If we have no partner at this point, use a copy of myself
 15.1573 +                        if (this.Partner == null)
 15.1574 +                        {
 15.1575 +                            this.Partner = this.Myself.Copy();
 15.1576 +                            this.Partner.Fingerprint = null;
 15.1577 +                            Log.Verbose("SendSyncMessage: Partner was null. Using copy of myself.");
 15.1578 +                        }
 15.1579  
 15.1580 -                    // Create basic message
 15.1581 -                    bool processMessage = true;
 15.1582 -                    PEPMessage message = new PEPMessage
 15.1583 -                    {
 15.1584 -                        From = this.Myself,
 15.1585 -                        ShortMsg = (messageType == MessageTypes.InitialMessage && this.Type == WizardType.PGP) ? Properties.Resources.KeySyncWizard_PGPInitialMessageSubject : PEPMessage.PEP_HIDDEN_SYNC_MESSAGE_SUBJECT,
 15.1586 -                        LongMsg = (messageType == MessageTypes.InitialMessage && this.Type == WizardType.PGP) ? Properties.Resources.KeySyncWizard_PGPInitialMessageBody : PEPMessage.PEP_HIDDEN_SYNC_MESSAGE_BODY,
 15.1587 -                        AutoConsume = (this.Type == WizardType.pEp) ? "yes" : null,
 15.1588 -                        Direction = pEpMsgDirection.pEpDirOutgoing,
 15.1589 -                        ForceUnencrypted = (messageType == MessageTypes.InitialMessage ? true : false),
 15.1590 -                        KeyImport = (this.Type == WizardType.pEp ? this.Myself.Fingerprint : null)
 15.1591 -                    };
 15.1592 -                    message.To.Add(this.Partner);
 15.1593 +                        // Create basic message
 15.1594 +                        bool processMessage = true;
 15.1595 +                        PEPMessage message = new PEPMessage
 15.1596 +                        {
 15.1597 +                            From = this.Myself,
 15.1598 +                            ShortMsg = (messageType == MessageTypes.InitialMessage && this.Type == WizardType.PGP) ? Properties.Resources.KeySyncWizard_PGPInitialMessageSubject : PEPMessage.PEP_HIDDEN_SYNC_MESSAGE_SUBJECT,
 15.1599 +                            LongMsg = (messageType == MessageTypes.InitialMessage && this.Type == WizardType.PGP) ? Properties.Resources.KeySyncWizard_PGPInitialMessageBody : PEPMessage.PEP_HIDDEN_SYNC_MESSAGE_BODY,
 15.1600 +                            AutoConsume = (this.Type == WizardType.pEp) ? "yes" : null,
 15.1601 +                            Direction = pEpMsgDirection.pEpDirOutgoing,
 15.1602 +                            ForceUnencrypted = (messageType == MessageTypes.InitialMessage ? true : false),
 15.1603 +                            KeyImport = (this.Type == WizardType.pEp ? this.Myself.Fingerprint : null)
 15.1604 +                        };
 15.1605 +                        message.To.Add(this.Partner);
 15.1606  
 15.1607 -                    Log.Verbose("SendSyncMessage: Basic message successfully created.");
 15.1608 +                        Log.Verbose("SendSyncMessage: Basic message successfully created.");
 15.1609  
 15.1610 -                    // If the message is the private key transport message, add own private key
 15.1611 -                    PEPMessage msg;
 15.1612 -                    if (messageType == MessageTypes.PrivateKeyMessage)
 15.1613 -                    {
 15.1614 +                        // If message type isn't InitialMessage, encrypt it accordingly
 15.1615 +                        PEPMessage msg;
 15.1616                          MsgProcessor msgProcessor = new MsgProcessor();
 15.1617 -                        if (msgProcessor.EncryptAndAddPrivateKey(message, this.Partner.Fingerprint, out msg))
 15.1618 +                        if ((messageType == MessageTypes.PrivateKeyMessage) &&
 15.1619 +                            (this.ExportPrivateKey))
 15.1620                          {
 15.1621 -                            Log.Verbose("SendSyncMessage: Private key message successfully created.");
 15.1622 -                            message = msg;
 15.1623 -                            processMessage = false;
 15.1624 +                            // Encrypt and add private key
 15.1625 +                            if (msgProcessor.EncryptAndAddPrivateKey(message, this.Partner.Fingerprint, out msg))
 15.1626 +                            {
 15.1627 +                                Log.Verbose("SendSyncMessage: Private key message successfully created.");
 15.1628 +                                message = msg;
 15.1629 +                                processMessage = false;
 15.1630 +                            }
 15.1631 +                            else
 15.1632 +                            {
 15.1633 +                                Log.Error("SendSyncMessage: Error encrypting private key message.");
 15.1634 +                                message = null;
 15.1635 +                            }
 15.1636 +                        }
 15.1637 +                        else if (((messageType == MessageTypes.PrivateKeyMessage) &&
 15.1638 +                                  (this.ExportPrivateKey == false)) ||
 15.1639 +                                 (messageType == MessageTypes.PublicKeyMessage))
 15.1640 +                        {
 15.1641 +                            // Encrypt using partner fpr as extra key
 15.1642 +                            if (msgProcessor.Encrypt(message, new string[] { this.Partner.Fingerprint }, out msg))
 15.1643 +                            {
 15.1644 +                                Log.Verbose("SendSyncMessage: Public key message successfully created.");
 15.1645 +                                message = msg;
 15.1646 +                                processMessage = false;
 15.1647 +                            }
 15.1648 +                            else
 15.1649 +                            {
 15.1650 +                                Log.Error("SendSyncMessage: Error encrypting public key message.");
 15.1651 +                                message = null;
 15.1652 +                            }
 15.1653 +                        }
 15.1654 +
 15.1655 +                        // If we have a message, send it
 15.1656 +                        if (message != null)
 15.1657 +                        {
 15.1658 +                            Log.Verbose("SendSyncMessage: Sending message...");
 15.1659 +
 15.1660 +                            // Disable passive mode if needed
 15.1661 +                            bool reenablePassiveMode = false;
 15.1662 +                            if ((messageType == MessageTypes.InitialMessage) &&
 15.1663 +                                (Globals.ThisAddIn.Settings.IsPassiveModeEnabled))
 15.1664 +                            {
 15.1665 +                                try
 15.1666 +                                {
 15.1667 +                                    ThisAddIn.PEPEngine.PassiveMode(false);
 15.1668 +                                    reenablePassiveMode = true;
 15.1669 +                                    Log.Verbose("SendSyncMessage: Passive mode temporarily disabled.");
 15.1670 +                                }
 15.1671 +                                catch (Exception ex)
 15.1672 +                                {
 15.1673 +                                    Log.Error("SendSyncMessage: Error disabling passive mode. " + ex.ToString());
 15.1674 +                                }
 15.1675 +                            }
 15.1676 +
 15.1677 +                            // Send message
 15.1678 +                            Globals.ThisAddIn.CreateAndSendMessage(message, true, true, processMessage, true);
 15.1679 +
 15.1680 +                            // Log that message has been sent
 15.1681 +                            this.sentMessages?.Add(messageType);
 15.1682 +
 15.1683 +                            // Reenable passive mode if needed
 15.1684 +                            if (reenablePassiveMode)
 15.1685 +                            {
 15.1686 +                                try
 15.1687 +                                {
 15.1688 +                                    ThisAddIn.PEPEngine.PassiveMode(Globals.ThisAddIn.Settings.IsPassiveModeEnabled);
 15.1689 +                                    Log.Verbose("SendSyncMessage: Passive mode reenabled.");
 15.1690 +                                }
 15.1691 +                                catch (Exception ex)
 15.1692 +                                {
 15.1693 +                                    Log.Error("SendSyncMessage: Error reenabling passive mode. " + ex.ToString());
 15.1694 +                                }
 15.1695 +                            }
 15.1696                          }
 15.1697                          else
 15.1698                          {
 15.1699 -                            Log.Error("SendSyncMessage: Error encrypting private key message.");
 15.1700 -                            message = null;
 15.1701 +                            Log.Error("SendSyncMessage: Myself identity is null.");
 15.1702                          }
 15.1703 -                    }
 15.1704 -
 15.1705 -                    // If we have a message, send it
 15.1706 -                    if (message != null)
 15.1707 -                    {
 15.1708 -                        Log.Verbose("SendSyncMessage: Sending message...");
 15.1709 -
 15.1710 -                        // Disable passive mode if needed
 15.1711 -                        bool reenablePassiveMode = false;
 15.1712 -                        if ((messageType == MessageTypes.InitialMessage) &&
 15.1713 -                            (Globals.ThisAddIn.Settings.IsPassiveModeEnabled))
 15.1714 -                        {
 15.1715 -                            try
 15.1716 -                            {
 15.1717 -                                ThisAddIn.PEPEngine.PassiveMode(false);
 15.1718 -                                reenablePassiveMode = true;
 15.1719 -                                Log.Verbose("SendSyncMessage: Passive mode temporarily disabled.");
 15.1720 -                            }
 15.1721 -                            catch (Exception ex)
 15.1722 -                            {
 15.1723 -                                Log.Error("SendSyncMessage: Error disabling passive mode. " + ex.ToString());
 15.1724 -                            }
 15.1725 -                        }
 15.1726 -
 15.1727 -                        // Send message
 15.1728 -                        Globals.ThisAddIn.CreateAndSendMessage(message, true, true, processMessage);
 15.1729 -
 15.1730 -                        // Log that message has been sent
 15.1731 -                        this.sentMessages?.Add(messageType);
 15.1732 -
 15.1733 -                        // Reenable passive mode if needed
 15.1734 -                        if (reenablePassiveMode)
 15.1735 -                        {
 15.1736 -                            try
 15.1737 -                            {
 15.1738 -                                ThisAddIn.PEPEngine.PassiveMode(Globals.ThisAddIn.Settings.IsPassiveModeEnabled);
 15.1739 -                                Log.Verbose("SendSyncMessage: Passive mode reenabled.");
 15.1740 -                            }
 15.1741 -                            catch (Exception ex)
 15.1742 -                            {
 15.1743 -                                Log.Error("SendSyncMessage: Error reenabling passive mode. " + ex.ToString());
 15.1744 -                            }
 15.1745 -                        }
 15.1746 -                    }
 15.1747 -                    else
 15.1748 -                    {
 15.1749 -                        Log.Error("SendSyncMessage: Myself identity is null.");
 15.1750 -                    }
 15.1751 +                    }), TaskCreationOptions.LongRunning);
 15.1752                  }
 15.1753                  catch (Exception ex)
 15.1754                  {
 15.1755 @@ -810,7 +1615,7 @@
 15.1756          }
 15.1757  
 15.1758          /// <summary>
 15.1759 -        /// Trusts the communication partner key (makes the channel green)
 15.1760 +        /// Trusts the communication partner key (makes the channel green).
 15.1761          /// </summary>
 15.1762          private void TrustKey()
 15.1763          {
 15.1764 @@ -818,31 +1623,28 @@
 15.1765              {
 15.1766                  try
 15.1767                  {
 15.1768 -                    Log.Verbose("TrustKey: Trusting partner key...");
 15.1769 +                    // Run in background
 15.1770 +                    Task.Factory.StartNew(new Action(() =>
 15.1771 +                    {
 15.1772 +                        Log.Verbose("TrustKey: Trusting partner key...");
 15.1773  
 15.1774 -                    this._Partner = this.Items[0].Partner;
 15.1775 -                    pEpIdentity partner = this._Partner.ToCOMType();
 15.1776 -                    ThisAddIn.PEPEngine.TrustPersonalKey(partner);
 15.1777 +                        // Trust the partner's key
 15.1778 +                        this._Partner = this.Items[0].Partner;
 15.1779 +                        pEpIdentity partner = this._Partner.ToCOMType();
 15.1780 +                        ThisAddIn.PEPEngine.TrustPersonalKey(partner);
 15.1781  
 15.1782 -                    // If Trustwords are being accepted after having received
 15.1783 -                    // the private key, finish process.
 15.1784 -                    if (this.State == WizardState.Step3)
 15.1785 +                        // Process messages that might have been received
 15.1786 +                        this.ProcessReceivedSyncMessages();
 15.1787 +
 15.1788 +                    }), TaskCreationOptions.LongRunning).ContinueWith(new Action<Task>((result) =>
 15.1789                      {
 15.1790 -                        Log.Verbose("TrustKey: Private key already received. Completing wizard.");
 15.1791 -                        this.CompleteWizard();
 15.1792 -                    }
 15.1793 -                    else
 15.1794 -                    {
 15.1795 -                        Log.Verbose("TrustKey: No private key received yet. Going to next step.");
 15.1796 -                        this.GoToNextStep();
 15.1797 -                    }
 15.1798 -
 15.1799 -                    // In pEp sync mode, send private key to partner
 15.1800 -                    if (this.Type == WizardType.pEp)
 15.1801 -                    {
 15.1802 -                        Log.Verbose("TrustKey: Sending private key to partner.");
 15.1803 -                        this.SendSyncMessage(MessageTypes.PrivateKeyMessage);
 15.1804 -                    }
 15.1805 +                        // In pEp sync mode, send private key message to partner
 15.1806 +                        if (this.Type == WizardType.pEp)
 15.1807 +                        {
 15.1808 +                            Log.Verbose("TrustKey: Sending private key to partner.");
 15.1809 +                            this.SendSyncMessage(MessageTypes.PrivateKeyMessage);
 15.1810 +                        }
 15.1811 +                    }));
 15.1812                  }
 15.1813                  catch (Exception ex)
 15.1814                  {
 15.1815 @@ -858,108 +1660,42 @@
 15.1816          }
 15.1817  
 15.1818          /// <summary>
 15.1819 -        /// Updates the dialog content according to its current state.
 15.1820 -        /// </summary>
 15.1821 -        private void UpdateContent()
 15.1822 -        {
 15.1823 -            // Set title
 15.1824 -            if (string.IsNullOrEmpty(this._TitleText))
 15.1825 -            {
 15.1826 -                this.TitleText = this.TitleText = this.Myself?.Address;
 15.1827 -            }
 15.1828 -
 15.1829 -            // Set content according to state
 15.1830 -            switch (this.State)
 15.1831 -            {
 15.1832 -                case WizardState.Step1:
 15.1833 -                    {
 15.1834 -                        this.NextButtonText = Properties.Resources.KeySyncWizard_Next;
 15.1835 -                        this.ExplanationText = (this.Type == WizardType.pEp) ? Properties.Resources.KeySyncWizard_Step1PEPExplanationText : Properties.Resources.KeySyncWizard_Step1PGPExplanationText;
 15.1836 -                        this.SubtitleText = (this.Type == WizardType.pEp) ? Properties.Resources.KeySyncWizard_WaitingForResponseText : Properties.Resources.KeySyncWizard_Step1PGPSubtitleText;
 15.1837 -                    }
 15.1838 -                    break;
 15.1839 -                case WizardState.Step2:
 15.1840 -                    {
 15.1841 -                        this.NextButtonText = (this.Type == WizardType.pEp) ? Properties.Resources.Handshake_ConfirmTrustwords : Properties.Resources.Handshake_ConfirmFingerprint;
 15.1842 -                        this.ExplanationText = (this.Type == WizardType.pEp) ? Properties.Resources.KeySyncWizard_Step2PEPExplanationText : Properties.Resources.KeySyncWizard_Step2PGPExplanationText;
 15.1843 -                        this.SubtitleText = (this.Type == WizardType.pEp) ? Properties.Resources.Handshake_ConfirmTrustwords : Properties.Resources.Handshake_ConfirmFingerprint;
 15.1844 -                    }
 15.1845 -                    break;
 15.1846 -                case WizardState.Step3:
 15.1847 -                    {
 15.1848 -                        this.NextButtonText = Properties.Resources.KeySyncWizard_Next;
 15.1849 -                        this.ExplanationText = (this.Type == WizardType.pEp) ? Properties.Resources.KeySyncWizard_Step3PEPExplanationText : Properties.Resources.KeySyncWizard_Step3PGPExplanationText;
 15.1850 -                        this.SubtitleText = Properties.Resources.KeySyncWizard_WaitingForResponseText;
 15.1851 -                    }
 15.1852 -                    break;
 15.1853 -                case WizardState.Step4:
 15.1854 -                    {
 15.1855 -                        this.NextButtonText = Properties.Resources.KeySyncWizard_Finish;
 15.1856 -
 15.1857 -                        if (this.Success)
 15.1858 -                        {
 15.1859 -                            this.SubtitleText = Properties.Resources.KeySyncWizard_SuccessText;
 15.1860 -
 15.1861 -                            switch (this.Type)
 15.1862 -                            {
 15.1863 -                                case WizardType.PGP:
 15.1864 -                                    {
 15.1865 -                                        this.ExplanationText = Properties.Resources.KeySyncWizard_Step4SuccessExplanationText;
 15.1866 -                                    }
 15.1867 -                                    break;
 15.1868 -                                case WizardType.pEp:
 15.1869 -                                    {
 15.1870 -                                        if (this.isInitiator)
 15.1871 -                                        {
 15.1872 -                                            this.ExplanationText = Properties.Resources.KeySyncWizard_Step4PEPSuccessInitiatorExplanationText;
 15.1873 -                                        }
 15.1874 -                                        else
 15.1875 -                                        {
 15.1876 -                                            this.ExplanationText = Properties.Resources.KeySyncWizard_Step4PEPSuccessNonInitiatorExplanationText;
 15.1877 -                                        }
 15.1878 -                                    }
 15.1879 -                                    break;
 15.1880 -                                case WizardType.Undefined:
 15.1881 -                                default:
 15.1882 -                                    {
 15.1883 -                                        this.ExplanationText = string.Empty;
 15.1884 -                                    }
 15.1885 -                                    break;
 15.1886 -                            }
 15.1887 -                        }
 15.1888 -                        else
 15.1889 -                        {
 15.1890 -                            this.ExplanationText = Properties.Resources.KeySyncWizard_Step4ErrorExplanationText;
 15.1891 -                            this.SubtitleText = Properties.Resources.KeySyncWizard_ErrorText;
 15.1892 -                        }
 15.1893 -                    }
 15.1894 -                    break;
 15.1895 -                case WizardState.Undefined:
 15.1896 -                default:
 15.1897 -                    this.NextButtonText = Properties.Resources.KeySyncWizard_Finish;
 15.1898 -                    this.ExplanationText = string.Empty;
 15.1899 -                    this.SubtitleText = string.Empty;
 15.1900 -                    break;
 15.1901 -            }
 15.1902 -        }
 15.1903 -
 15.1904 -        /// <summary>
 15.1905          /// Resets the object to its defaults.
 15.1906          /// </summary>
 15.1907          public void Reset()
 15.1908          {
 15.1909 -            this._ExplanationText = null;
 15.1910 +            this._CurrentState = new WizardState();
 15.1911 +            this._ExportPrivateKey = true;
 15.1912 +            this._IsInitiator = false;
 15.1913              this._Items = new ObservableCollection<HandshakeItem>();
 15.1914              this._Myself = null;
 15.1915 -            this._NextButtonText = null;
 15.1916              this._Partner = null;
 15.1917 -            this._State = WizardState.Undefined;
 15.1918 -            this._SubtitleText = null;
 15.1919 -            this._Success = false;
 15.1920 +            this._Step = Steps.Undefined;
 15.1921 +            this._SetImportedKeyAsDefault = true;
 15.1922              this._Type = WizardType.Undefined;
 15.1923 -            this._TitleText = null;
 15.1924          }
 15.1925  
 15.1926          #endregion
 15.1927 +
 15.1928 +        /// <summary>
 15.1929 +        /// Container to define a wizard state.
 15.1930 +        /// </summary>
 15.1931 +        public class WizardState
 15.1932 +        {
 15.1933 +            public Action                   AcceptButtonClick           { get; set; }   =   null;
 15.1934 +            public string                   AcceptButtonText            { get; set; }   =   null;
 15.1935 +            public bool                     AreTrustwordsVisible        { get; set; }   =   false;
 15.1936 +            public Action                   BackButtonClick             { get; set; }   =   null;
 15.1937 +            public Action                   CancelButtonClick           { get; set; }   =   null;
 15.1938 +            public string                   CancelButtonText            { get; set; }   =   null;
 15.1939 +            public bool                     IsAcceptButtonVisible       { get; set; }   =   true;
 15.1940 +            public bool                     IsBackButtonVisible         { get; set; }   =   false;
 15.1941 +            public bool                     IsCancelButtonVisible       { get; set; }   =   true;
 15.1942 +            public bool                     IsUserTextVisible           { get; set; }   =   true;
 15.1943 +            public KeySyncWizard.Steps      Step                        { get; set; }   =   Steps.Undefined;
 15.1944 +            public string                   SubtitleText                { get; set; }   =   null;
 15.1945 +            public string                   TitleText                   { get; set; }   =   null;
 15.1946 +            public string                   UserText                    { get; set; }   =   null;
 15.1947 +        }
 15.1948      }
 15.1949  }
    16.1 --- a/UI/ValueConverters.cs	Thu May 10 12:18:14 2018 +0200
    16.2 +++ b/UI/ValueConverters.cs	Tue May 22 11:35:06 2018 +0200
    16.3 @@ -276,61 +276,6 @@
    16.4      }
    16.5  
    16.6      /// <summary>
    16.7 -    /// Returns a bool value indicating if the wizard state matches any of the given parameter.
    16.8 -    /// </summary>
    16.9 -    public class IsWizardStateConverter : IValueConverter
   16.10 -    {
   16.11 -        public object Convert(object value,
   16.12 -                              Type targetType,
   16.13 -                              object parameter,
   16.14 -                              CultureInfo culture)
   16.15 -        {
   16.16 -            bool success;
   16.17 -            KeySyncWizard.WizardState param;
   16.18 -
   16.19 -            if ((value is KeySyncWizard.WizardState) &&
   16.20 -                (parameter is string))
   16.21 -            {
   16.22 -                string[] parameters = (parameter as string).Split('|');
   16.23 -
   16.24 -                if (parameters?.Length > 0)
   16.25 -                {
   16.26 -                    foreach (var p in parameters)
   16.27 -                    {
   16.28 -                        success = Enum.TryParse(p, out param);
   16.29 -
   16.30 -                        if (success)
   16.31 -                        {
   16.32 -                            if (((KeySyncWizard.WizardState)value) == param)
   16.33 -                            {
   16.34 -                                return true;
   16.35 -                            }
   16.36 -                        }
   16.37 -                        else
   16.38 -                        {
   16.39 -                            throw new ArgumentException();
   16.40 -                        }
   16.41 -                    }
   16.42 -                }
   16.43 -
   16.44 -                return false;
   16.45 -            }
   16.46 -            else
   16.47 -            {
   16.48 -                throw new ArgumentException();
   16.49 -            }
   16.50 -        }
   16.51 -
   16.52 -        public object ConvertBack(object value,
   16.53 -                                  Type targetType,
   16.54 -                                  object parameter,
   16.55 -                                  CultureInfo culture)
   16.56 -        {
   16.57 -            throw new NotImplementedException();
   16.58 -        }
   16.59 -    }
   16.60 -
   16.61 -    /// <summary>
   16.62      /// Converter to check if a list is empty.
   16.63      /// </summary>
   16.64      public class IsListEmptyConverter : IValueConverter
   16.65 @@ -530,6 +475,38 @@
   16.66      }
   16.67  
   16.68      /// <summary>
   16.69 +    /// Returns true if the Wizard is in the given state.
   16.70 +    /// </summary>
   16.71 +    public class IsWizardTypeConverter : IValueConverter
   16.72 +    {
   16.73 +        public object Convert(object value,
   16.74 +                              Type targetType,
   16.75 +                              object parameter,
   16.76 +                              CultureInfo culture)
   16.77 +        {
   16.78 +            string val = null;
   16.79 +            string param = parameter as string;
   16.80 +
   16.81 +            try
   16.82 +            {
   16.83 +                val = Enum.GetName(typeof(KeySyncWizard.WizardType), value);
   16.84 +            }
   16.85 +            catch
   16.86 +            {
   16.87 +                val = null;
   16.88 +            }
   16.89 +
   16.90 +            return (param?.Equals(val) == true);
   16.91 +        }
   16.92 +
   16.93 +        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   16.94 +        {
   16.95 +            throw new NotImplementedException();
   16.96 +        }
   16.97 +    }
   16.98 +
   16.99 +
  16.100 +    /// <summary>
  16.101      /// Converter to AND several bool values and convert to Visibility.
  16.102      /// </summary>
  16.103      public class MultiBooleanToVisibilityConverter : IMultiValueConverter