Merge with default OUT-431
authorThomas
Thu, 17 May 2018 11:26:23 +0200
branchOUT-431
changeset 2200c578f001cfe5
parent 2184 71d798d2b545
parent 2199 5c8c43f38243
child 2201 5c9f9d4ec13f
Merge with default
CryptableMailItem.cs
MsgProcessor.cs
     1.1 --- a/CryptableMailItem.cs	Thu May 10 12:38:22 2018 +0200
     1.2 +++ b/CryptableMailItem.cs	Thu May 17 11:26:23 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,14 +1446,13 @@
    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 @@ -1494,9 +1496,6 @@
    1.60                          }
    1.61                          else
    1.62                          {
    1.63 -                            // Check for sync message
    1.64 -                            this.CheckForSyncMessage((processedRating == pEpRating.pEpRatingUnencrypted) ? message : processedMessage, decryptionFlags);
    1.65 -
    1.66                              // Save processed message data to Outlook
    1.67                              if (processedMessage != null)
    1.68                              {
    1.69 @@ -1871,85 +1870,6 @@
    1.70           *************************************************************/
    1.71  
    1.72          /// <summary>
    1.73 -        /// Checks if the key sync wizard is open or the message is a sync message.
    1.74 -        /// If this is true, the message will get processed further, either raising
    1.75 -        /// the respective event or opening the wizard.
    1.76 -        /// </summary>
    1.77 -        /// <param name="message">The message to check.</param>
    1.78 -        /// <param name="flags">The decrypt flags.</param>
    1.79 -        private void CheckForSyncMessage(PEPMessage message, pEpDecryptFlags flags)
    1.80 -        {
    1.81 -            try
    1.82 -            {
    1.83 -                /* To determine whether the processed message is a sync message:
    1.84 -                 * 1. Is incoming (do not process sent messages)
    1.85 -                 * 2. Has the KeyImport header (in case of pEp sync) and the header is not
    1.86 -                 *    the own fingerprint.
    1.87 -                 * - or -
    1.88 -                 * 3. a. The WizardType is PGP
    1.89 -                 *    b. The message has one To recipient that is also the From recipient
    1.90 -                 *    c. The From recipient is an own identity (seems actually unnecessary)
    1.91 -                 */
    1.92 -                if ((KeySyncWizard.Wizard?.Type == KeySyncWizard.WizardType.PGP) ||
    1.93 -                    (message?.KeyImport?.Equals(KeySyncWizard.Wizard?.Myself?.Fingerprint) == false))
    1.94 -                {
    1.95 -                    if ((message.To.Count == 1) &&
    1.96 -                        (message.To[0].EqualsByAddress(message.From)) &&
    1.97 -                        (PEPIdentity.GetIsOwnIdentity(message.From.Address)))
    1.98 -                    {
    1.99 -                        Log.Verbose("CheckForSyncMessage: Sync message found.");
   1.100 -
   1.101 -                        if ((KeySyncWizard.Wizard?.Type != KeySyncWizard.WizardType.PGP) &&
   1.102 -                            (KeySyncWizard.Wizard?.IsVisible == false) &&
   1.103 -                            (message.Rating < pEpRating.pEpRatingTrusted))
   1.104 -                        {
   1.105 -                            Log.Verbose("CheckForSyncMessage: Wizard not open yet.");
   1.106 -
   1.107 -                            // Get own identity
   1.108 -                            PEPIdentity myself = null;
   1.109 -                            try
   1.110 -                            {
   1.111 -                                pEpIdentity _myself = message.To[0].ToCOMType();
   1.112 -                                myself = new PEPIdentity(ThisAddIn.PEPEngine.Myself(_myself));
   1.113 -                            }
   1.114 -                            catch (Exception ex)
   1.115 -                            {
   1.116 -                                myself = null;
   1.117 -                                Log.Verbose("CheckForSyncMessage: Error getting own identity. " + ex.ToString());
   1.118 -                            }
   1.119 -
   1.120 -                            // Only open if not sent to myself. Check again if not open
   1.121 -                            if ((myself?.Fingerprint?.Equals(message?.KeyImport) == false) &&
   1.122 -                                (KeySyncWizard.Wizard?.IsVisible == false))
   1.123 -                            {
   1.124 -                                // Marshall to main thread and create new wizard
   1.125 -                                KeySyncWizard.Wizard?.Dispatcher?.Invoke(new Action(() =>
   1.126 -                                {
   1.127 -                                    KeySyncWizard.Wizard = new KeySyncWizard(KeySyncWizard.WizardType.pEp, false, message.To[0], message.KeyImport);
   1.128 -                                    KeySyncWizard.Wizard.Show();
   1.129 -                                    Log.Verbose("CheckForSyncMessage: Wizard opened.");
   1.130 -                                }));
   1.131 -                            }
   1.132 -                        }
   1.133 -                        else
   1.134 -                        {
   1.135 -                            Log.Verbose("CheckForSyncMessage: Wizard already open or message rating is trusted. Invoking sync message received event.");
   1.136 -                            CryptableMailItem.SyncMessageReceived?.Invoke(this, new SyncMessageEventArgs(message, flags));
   1.137 -                        }
   1.138 -                    }
   1.139 -                    else
   1.140 -                    {
   1.141 -                        Log.Warning("CheckForSyncMessage: PGP Wizard open or message with KeyImport header, but message doesn't meet formal criteria.");
   1.142 -                    }
   1.143 -                }
   1.144 -            }
   1.145 -            catch (Exception ex)
   1.146 -            {
   1.147 -                Log.Error("CheckForSyncMessage: Error detecting if sync message. " + ex.ToString());
   1.148 -            }
   1.149 -        }
   1.150 -
   1.151 -        /// <summary>
   1.152          /// Releases all resources and disconnects internal events.
   1.153          /// The internal mail item will NOT be released -- this is managed externally.
   1.154          /// </summary>
   1.155 @@ -2200,27 +2120,6 @@
   1.156          }
   1.157  
   1.158          /// <summary>
   1.159 -        /// Class used to store the arguments in the SyncMessageReceived event.
   1.160 -        /// </summary>
   1.161 -        internal class SyncMessageEventArgs : EventArgs
   1.162 -        {
   1.163 -            public PEPMessage Message = null;
   1.164 -            public pEpDecryptFlags Flags = pEpDecryptFlags.pEpDecryptFlagsNone;
   1.165 -
   1.166 -            /// <summary>
   1.167 -            /// Constructs a new SyncMessageEventArgs with the given arguments.
   1.168 -            /// </summary>
   1.169 -            /// <param name="message">The message that has been received.</param>
   1.170 -            /// <param name="flags">The decryption flags of the received message.</param>
   1.171 -            public SyncMessageEventArgs(PEPMessage message,
   1.172 -                                        pEpDecryptFlags flags)
   1.173 -            {
   1.174 -                this.Message = message;
   1.175 -                this.Flags = flags;
   1.176 -            }
   1.177 -        }
   1.178 -
   1.179 -        /// <summary>
   1.180          /// Class used to store an entry in the encrypted conversation cache.
   1.181          /// This will identify the original parent encrypted mail item.
   1.182          /// </summary>
     2.1 --- a/MsgProcessor.cs	Thu May 10 12:38:22 2018 +0200
     2.2 +++ b/MsgProcessor.cs	Thu May 17 11:26:23 2018 +0200
     2.3 @@ -13,6 +13,12 @@
     2.4      /// </summary>
     2.5      internal class MsgProcessor
     2.6      {
     2.7 +        /// <summary>
     2.8 +        /// Event handler for when a sync message is being detected during decryption.
     2.9 +        /// </summary>
    2.10 +        public delegate void SyncMessageReceivedHandler(object sender, MsgProcessor.SyncMessageEventArgs e);
    2.11 +        public static event SyncMessageReceivedHandler SyncMessageReceived;
    2.12 +
    2.13          /**************************************************************
    2.14           * 
    2.15           * Constructors/Destructors
    2.16 @@ -33,6 +39,93 @@
    2.17           *************************************************************/
    2.18  
    2.19          /// <summary>
    2.20 +        /// Checks if the key sync wizard is open or the message is a sync message.
    2.21 +        /// If this is true, the message will get processed further, either raising
    2.22 +        /// the respective event or opening the wizard.
    2.23 +        /// </summary>
    2.24 +        /// <param name="message">The message to check.</param>
    2.25 +        /// <param name="flags">The decrypt flags.</param>
    2.26 +        private void CheckForSyncMessage(PEPMessage message, ref pEpDecryptFlags flags)
    2.27 +        {
    2.28 +            try
    2.29 +            {
    2.30 +                /* To determine whether the processed message is a sync message:
    2.31 +                 * 1. Is incoming (do not process sent messages)
    2.32 +                 * 2. Has the KeyImport header (in case of pEp sync) and the header is not
    2.33 +                 *    the own fingerprint.
    2.34 +                 * - or -
    2.35 +                 * 3. a. The WizardType is PGP
    2.36 +                 *    b. The message has one To recipient that is also the From recipient
    2.37 +                 *    c. The From recipient is an own identity (seems actually unnecessary)
    2.38 +                 */
    2.39 +                if ((KeySyncWizard.Wizard?.Type == KeySyncWizard.WizardType.PGP) ||
    2.40 +                    (message?.KeyImport?.Equals(KeySyncWizard.Wizard?.Myself?.Fingerprint) == false))
    2.41 +                {
    2.42 +                    if ((message.To.Count == 1) &&
    2.43 +                        (message.To[0].EqualsByAddress(message.From)) &&
    2.44 +                        (PEPIdentity.GetIsOwnIdentity(message.From.Address)))
    2.45 +                    {
    2.46 +                        Log.Verbose("CheckForSyncMessage: Sync message found.");
    2.47 +
    2.48 +                        if ((KeySyncWizard.Wizard?.Type != KeySyncWizard.WizardType.PGP) &&
    2.49 +                            (KeySyncWizard.Wizard?.IsVisible == false) &&
    2.50 +                            (message.Rating < pEpRating.pEpRatingTrusted))
    2.51 +                        {
    2.52 +                            Log.Verbose("CheckForSyncMessage: Wizard not open yet.");
    2.53 +
    2.54 +                            // Get own identity
    2.55 +                            PEPIdentity myself = null;
    2.56 +                            try
    2.57 +                            {
    2.58 +                                pEpIdentity _myself = message.To[0].ToCOMType();
    2.59 +                                myself = new PEPIdentity(ThisAddIn.PEPEngine.Myself(_myself));
    2.60 +                            }
    2.61 +                            catch (Exception ex)
    2.62 +                            {
    2.63 +                                myself = null;
    2.64 +                                Log.Verbose("CheckForSyncMessage: Error getting own identity. " + ex.ToString());
    2.65 +                            }
    2.66 +
    2.67 +                            // Only open if not sent to myself. Check again if not open
    2.68 +                            if ((myself?.Fingerprint?.Equals(message?.KeyImport) == false) &&
    2.69 +                                (KeySyncWizard.Wizard?.IsVisible == false))
    2.70 +                            {
    2.71 +                                // Marshall to main thread and create new wizard
    2.72 +                                KeySyncWizard.Wizard?.Dispatcher?.Invoke(new Action(() =>
    2.73 +                                {
    2.74 +                                    KeySyncWizard.Wizard = new KeySyncWizard(KeySyncWizard.WizardType.pEp, false, message.To[0], message.KeyImport);
    2.75 +                                    KeySyncWizard.Wizard.Show();
    2.76 +                                    Log.Verbose("CheckForSyncMessage: Wizard opened.");
    2.77 +                                })); 
    2.78 +                            }
    2.79 +                        }
    2.80 +                        else
    2.81 +                        {
    2.82 +                            Log.Verbose("CheckForSyncMessage: Wizard already open or message rating is trusted. Invoking sync message received event.");
    2.83 +                            MsgProcessor.SyncMessageReceived?.Invoke(this, new SyncMessageEventArgs(message, flags));
    2.84 +                        }
    2.85 +
    2.86 +                        // Delete message if necessary
    2.87 +                        if ((KeySyncWizard.Wizard?.Type == KeySyncWizard.WizardType.pEp) &&
    2.88 +                            (string.IsNullOrEmpty(message?.KeyImport) == false) &&
    2.89 +                            (KeySyncWizard.Wizard?.Myself?.Fingerprint?.Equals(message?.KeyImport) == false))
    2.90 +                        {
    2.91 +                            flags = (flags | pEpDecryptFlags.pEpDecryptFlagConsume);
    2.92 +                        }
    2.93 +                    }
    2.94 +                    else
    2.95 +                    {
    2.96 +                        Log.Warning("CheckForSyncMessage: PGP Wizard open or message with KeyImport header, but message doesn't meet formal criteria.");
    2.97 +                    }
    2.98 +                }
    2.99 +            }
   2.100 +            catch (Exception ex)
   2.101 +            {
   2.102 +                Log.Error("CheckForSyncMessage: Error detecting if sync message. " + ex.ToString());
   2.103 +            }
   2.104 +        }
   2.105 +
   2.106 +        /// <summary>
   2.107          /// Processes the given message including any decryption where necessary.
   2.108          /// This will then return the latest pEp rating for the message.
   2.109          /// If rating is ever undefined: it can be assumed an error occured.
   2.110 @@ -393,14 +486,6 @@
   2.111  
   2.112              Log.Verbose("ProcessSentMessage: Started");
   2.113  
   2.114 -            // Check if we have an extra key for sync messages and add it
   2.115 -            if (string.IsNullOrEmpty(KeySyncWizard.Wizard?.Partner?.Fingerprint) == false)
   2.116 -            {
   2.117 -                List<string> eKeys = extraKeys?.ToList<string>() ?? new List<string>();
   2.118 -                eKeys.Add(KeySyncWizard.Wizard.Partner.Fingerprint);
   2.119 -                extraKeys = eKeys.ToArray<string>();
   2.120 -            }
   2.121 -
   2.122              // Force the working message to outgoing direction.
   2.123              // This protects mostly for outgoing rating calculation which requires it.
   2.124              // However, if the message is ever incoming direction here, a failure occured elsewhere.
   2.125 @@ -767,6 +852,19 @@
   2.126  
   2.127          /// <summary>
   2.128          /// Decrypts the given pEp message.
   2.129 +        /// This is a wrapper for special cases where we don't need the actual result.
   2.130 +        /// </summary>
   2.131 +        /// <param name="sourceMessage">The message to decrypt.</param>
   2.132 +        /// <returns>True if decryption was considered successful, otherwise false.</returns>
   2.133 +        public bool Decrypt(PEPMessage sourceMessage)
   2.134 +        {
   2.135 +            PEPMessage outMessage;
   2.136 +
   2.137 +            return this.Decrypt(sourceMessage, out outMessage);
   2.138 +        }
   2.139 +
   2.140 +        /// <summary>
   2.141 +        /// Decrypts the given pEp message.
   2.142          /// This is a wrapper for special cases where we don't need to take care of
   2.143          /// rating, key list or flags.
   2.144          /// </summary>
   2.145 @@ -882,7 +980,10 @@
   2.146              {
   2.147                  destMessage = null;
   2.148                  keyList = new string[0];
   2.149 -            }            
   2.150 +            }
   2.151 +
   2.152 +            // Check for sync message
   2.153 +            this.CheckForSyncMessage((rating == pEpRating.pEpRatingUnencrypted) ? sourceMessage : destMessage, ref flags);
   2.154  
   2.155              Log.SensitiveData("Decrypt: Complete. " + sourceMessage?.Id);
   2.156  
   2.157 @@ -1159,5 +1260,26 @@
   2.158                  this.ProcessedStatus = Globals.ReturnStatus.Success;
   2.159              }
   2.160          }
   2.161 +
   2.162 +        /// <summary>
   2.163 +        /// Class used to store the arguments in the SyncMessageReceived event.
   2.164 +        /// </summary>
   2.165 +        internal class SyncMessageEventArgs : EventArgs
   2.166 +        {
   2.167 +            public PEPMessage Message = null;
   2.168 +            public pEpDecryptFlags Flags = pEpDecryptFlags.pEpDecryptFlagsNone;
   2.169 +
   2.170 +            /// <summary>
   2.171 +            /// Constructs a new SyncMessageEventArgs with the given arguments.
   2.172 +            /// </summary>
   2.173 +            /// <param name="message">The message that has been received.</param>
   2.174 +            /// <param name="flags">The decryption flags of the received message.</param>
   2.175 +            public SyncMessageEventArgs(PEPMessage message,
   2.176 +                                        pEpDecryptFlags flags)
   2.177 +            {
   2.178 +                this.Message = message;
   2.179 +                this.Flags = flags;
   2.180 +            }
   2.181 +        }
   2.182      }
   2.183  }
     3.1 --- a/PEPSettings.cs	Thu May 10 12:38:22 2018 +0200
     3.2 +++ b/PEPSettings.cs	Thu May 17 11:26:23 2018 +0200
     3.3 @@ -1846,7 +1846,6 @@
     3.4              protected bool          _IsSyncEnabled;
     3.5              protected string        _SentFolderEntryId;
     3.6              protected string        _SmtpAddress;
     3.7 -            protected string        _StoreId;
     3.8              protected string        _Type;
     3.9              protected string        _UserName;
    3.10  
     4.1 --- a/Properties/Resources.Designer.cs	Thu May 10 12:38:22 2018 +0200
     4.2 +++ b/Properties/Resources.Designer.cs	Thu May 17 11:26:23 2018 +0200
     4.3 @@ -701,6 +701,24 @@
     4.4          }
     4.5          
     4.6          /// <summary>
     4.7 +        ///   Looks up a localized string similar to Back.
     4.8 +        /// </summary>
     4.9 +        public static string KeySyncWizard_BackButtonText {
    4.10 +            get {
    4.11 +                return ResourceManager.GetString("KeySyncWizard_BackButtonText", resourceCulture);
    4.12 +            }
    4.13 +        }
    4.14 +        
    4.15 +        /// <summary>
    4.16 +        ///   Looks up a localized string similar to An error occured. Your key could not be imported correctly. Please try again..
    4.17 +        /// </summary>
    4.18 +        public static string KeySyncWizard_ErrorExplanationText {
    4.19 +            get {
    4.20 +                return ResourceManager.GetString("KeySyncWizard_ErrorExplanationText", resourceCulture);
    4.21 +            }
    4.22 +        }
    4.23 +        
    4.24 +        /// <summary>
    4.25          ///   Looks up a localized string similar to Error.
    4.26          /// </summary>
    4.27          public static string KeySyncWizard_ErrorText {
    4.28 @@ -710,6 +728,15 @@
    4.29          }
    4.30          
    4.31          /// <summary>
    4.32 +        ///   Looks up a localized string similar to Export my private key to the other device.
    4.33 +        /// </summary>
    4.34 +        public static string KeySyncWizard_ExportOwnPrivateKey {
    4.35 +            get {
    4.36 +                return ResourceManager.GetString("KeySyncWizard_ExportOwnPrivateKey", resourceCulture);
    4.37 +            }
    4.38 +        }
    4.39 +        
    4.40 +        /// <summary>
    4.41          ///   Looks up a localized string similar to Finish.
    4.42          /// </summary>
    4.43          public static string KeySyncWizard_Finish {
    4.44 @@ -728,6 +755,89 @@
    4.45          }
    4.46          
    4.47          /// <summary>
    4.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..
    4.49 +        /// </summary>
    4.50 +        public static string KeySyncWizard_PEPStep1ExplanationText {
    4.51 +            get {
    4.52 +                return ResourceManager.GetString("KeySyncWizard_PEPStep1ExplanationText", resourceCulture);
    4.53 +            }
    4.54 +        }
    4.55 +        
    4.56 +        /// <summary>
    4.57 +        ///   Looks up a localized string similar to If you initiated a key import for the following account, please click Start.
    4.58 +        ///
    4.59 +        ///If this was not you, please cancel..
    4.60 +        /// </summary>
    4.61 +        public static string KeySyncWizard_PEPStep1NonInitiatorExplanationText {
    4.62 +            get {
    4.63 +                return ResourceManager.GetString("KeySyncWizard_PEPStep1NonInitiatorExplanationText", resourceCulture);
    4.64 +            }
    4.65 +        }
    4.66 +        
    4.67 +        /// <summary>
    4.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..
    4.69 +        /// </summary>
    4.70 +        public static string KeySyncWizard_PEPStep2ExplanationText {
    4.71 +            get {
    4.72 +                return ResourceManager.GetString("KeySyncWizard_PEPStep2ExplanationText", resourceCulture);
    4.73 +            }
    4.74 +        }
    4.75 +        
    4.76 +        /// <summary>
    4.77 +        ///   Looks up a localized string similar to Importing key....
    4.78 +        /// </summary>
    4.79 +        public static string KeySyncWizard_PEPStep3ExplanationText {
    4.80 +            get {
    4.81 +                return ResourceManager.GetString("KeySyncWizard_PEPStep3ExplanationText", resourceCulture);
    4.82 +            }
    4.83 +        }
    4.84 +        
    4.85 +        /// <summary>
    4.86 +        ///   Looks up a localized string similar to Key import successful!.
    4.87 +        /// </summary>
    4.88 +        public static string KeySyncWizard_PEPStep4ExplanationText {
    4.89 +            get {
    4.90 +                return ResourceManager.GetString("KeySyncWizard_PEPStep4ExplanationText", resourceCulture);
    4.91 +            }
    4.92 +        }
    4.93 +        
    4.94 +        /// <summary>
    4.95 +        ///   Looks up a localized string similar to Key successfully exported!.
    4.96 +        /// </summary>
    4.97 +        public static string KeySyncWizard_PEPSuccessExport {
    4.98 +            get {
    4.99 +                return ResourceManager.GetString("KeySyncWizard_PEPSuccessExport", resourceCulture);
   4.100 +            }
   4.101 +        }
   4.102 +        
   4.103 +        /// <summary>
   4.104 +        ///   Looks up a localized string similar to Key successfully imported!.
   4.105 +        /// </summary>
   4.106 +        public static string KeySyncWizard_PEPSuccessImport {
   4.107 +            get {
   4.108 +                return ResourceManager.GetString("KeySyncWizard_PEPSuccessImport", resourceCulture);
   4.109 +            }
   4.110 +        }
   4.111 +        
   4.112 +        /// <summary>
   4.113 +        ///   Looks up a localized string similar to The key from your other device will now also be used to decrypt messages..
   4.114 +        /// </summary>
   4.115 +        public static string KeySyncWizard_PEPSuccessOtherKeyUsed {
   4.116 +            get {
   4.117 +                return ResourceManager.GetString("KeySyncWizard_PEPSuccessOtherKeyUsed", resourceCulture);
   4.118 +            }
   4.119 +        }
   4.120 +        
   4.121 +        /// <summary>
   4.122 +        ///   Looks up a localized string similar to The key from your other device will now be used as your default private key..
   4.123 +        /// </summary>
   4.124 +        public static string KeySyncWizard_PEPSuccessOtherKeyUsedAsDefault {
   4.125 +            get {
   4.126 +                return ResourceManager.GetString("KeySyncWizard_PEPSuccessOtherKeyUsedAsDefault", resourceCulture);
   4.127 +            }
   4.128 +        }
   4.129 +        
   4.130 +        /// <summary>
   4.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:  
   4.132          ///
   4.133          ///1. has your public PGP key attached and
   4.134 @@ -749,98 +859,56 @@
   4.135          }
   4.136          
   4.137          /// <summary>
   4.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..
   4.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..
   4.140          /// </summary>
   4.141 -        public static string KeySyncWizard_Step1PEPExplanationText {
   4.142 +        public static string KeySyncWizard_PGPStep1ExplanationText {
   4.143              get {
   4.144 -                return ResourceManager.GetString("KeySyncWizard_Step1PEPExplanationText", resourceCulture);
   4.145 +                return ResourceManager.GetString("KeySyncWizard_PGPStep1ExplanationText", resourceCulture);
   4.146              }
   4.147          }
   4.148          
   4.149          /// <summary>
   4.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:  
   4.151 -        ///
   4.152 -        ///1. has your public PGP key attached and
   4.153 -        ///2. is encrypted with the p≡p key you just imported.
   4.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..
   4.155          /// </summary>
   4.156 -        public static string KeySyncWizard_Step1PGPExplanationText {
   4.157 +        public static string KeySyncWizard_PGPStep2ExplanationText {
   4.158              get {
   4.159 -                return ResourceManager.GetString("KeySyncWizard_Step1PGPExplanationText", resourceCulture);
   4.160 +                return ResourceManager.GetString("KeySyncWizard_PGPStep2ExplanationText", resourceCulture);
   4.161              }
   4.162          }
   4.163          
   4.164          /// <summary>
   4.165 -        ///   Looks up a localized string similar to A message with your public key has been sent to yourself..
   4.166 +        ///   Looks up a localized string similar to Encrypt the answer message with the public p≡p key you just imported and send it..
   4.167          /// </summary>
   4.168 -        public static string KeySyncWizard_Step1PGPSubtitleText {
   4.169 +        public static string KeySyncWizard_PGPStep3ExplanationText {
   4.170              get {
   4.171 -                return ResourceManager.GetString("KeySyncWizard_Step1PGPSubtitleText", resourceCulture);
   4.172 -            }
   4.173 -        }
   4.174 -        
   4.175 -        /// <summary>
   4.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..
   4.177 -        /// </summary>
   4.178 -        public static string KeySyncWizard_Step2PEPExplanationText {
   4.179 -            get {
   4.180 -                return ResourceManager.GetString("KeySyncWizard_Step2PEPExplanationText", resourceCulture);
   4.181 +                return ResourceManager.GetString("KeySyncWizard_PGPStep3ExplanationText", resourceCulture);
   4.182              }
   4.183          }
   4.184          
   4.185          /// <summary>
   4.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..
   4.187          /// </summary>
   4.188 -        public static string KeySyncWizard_Step2PGPExplanationText {
   4.189 +        public static string KeySyncWizard_PGPStep5ExplanationText {
   4.190              get {
   4.191 -                return ResourceManager.GetString("KeySyncWizard_Step2PGPExplanationText", resourceCulture);
   4.192 +                return ResourceManager.GetString("KeySyncWizard_PGPStep5ExplanationText", resourceCulture);
   4.193              }
   4.194          }
   4.195          
   4.196          /// <summary>
   4.197 -        ///   Looks up a localized string similar to Importing key....
   4.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..
   4.199          /// </summary>
   4.200 -        public static string KeySyncWizard_Step3PEPExplanationText {
   4.201 +        public static string KeySyncWizard_PGPStep6ExplanationText {
   4.202              get {
   4.203 -                return ResourceManager.GetString("KeySyncWizard_Step3PEPExplanationText", resourceCulture);
   4.204 +                return ResourceManager.GetString("KeySyncWizard_PGPStep6ExplanationText", resourceCulture);
   4.205              }
   4.206          }
   4.207          
   4.208          /// <summary>
   4.209 -        ///   Looks up a localized string similar to Please send now another reply message that:  
   4.210 -        ///
   4.211 -        ///1. has your private PGP key attached and
   4.212 -        ///2. is encrypted with the p≡p key you just imported.
   4.213 +        ///   Looks up a localized string similar to Encrypt the answer message again with the public p≡p key and send it..
   4.214          /// </summary>
   4.215 -        public static string KeySyncWizard_Step3PGPExplanationText {
   4.216 +        public static string KeySyncWizard_PGPStep7ExplanationText {
   4.217              get {
   4.218 -                return ResourceManager.GetString("KeySyncWizard_Step3PGPExplanationText", resourceCulture);
   4.219 -            }
   4.220 -        }
   4.221 -        
   4.222 -        /// <summary>
   4.223 -        ///   Looks up a localized string similar to An error occured. Your key could not be imported correctly. Please try again..
   4.224 -        /// </summary>
   4.225 -        public static string KeySyncWizard_Step4ErrorExplanationText {
   4.226 -            get {
   4.227 -                return ResourceManager.GetString("KeySyncWizard_Step4ErrorExplanationText", resourceCulture);
   4.228 -            }
   4.229 -        }
   4.230 -        
   4.231 -        /// <summary>
   4.232 -        ///   Looks up a localized string similar to The key from your other device will now be used as your default private key..
   4.233 -        /// </summary>
   4.234 -        public static string KeySyncWizard_Step4PEPSuccessInitiatorExplanationText {
   4.235 -            get {
   4.236 -                return ResourceManager.GetString("KeySyncWizard_Step4PEPSuccessInitiatorExplanationText", resourceCulture);
   4.237 -            }
   4.238 -        }
   4.239 -        
   4.240 -        /// <summary>
   4.241 -        ///   Looks up a localized string similar to The key from the other device can now be used to decrypt messages..
   4.242 -        /// </summary>
   4.243 -        public static string KeySyncWizard_Step4PEPSuccessNonInitiatorExplanationText {
   4.244 -            get {
   4.245 -                return ResourceManager.GetString("KeySyncWizard_Step4PEPSuccessNonInitiatorExplanationText", resourceCulture);
   4.246 +                return ResourceManager.GetString("KeySyncWizard_PGPStep7ExplanationText", resourceCulture);
   4.247              }
   4.248          }
   4.249          
   4.250 @@ -849,9 +917,27 @@
   4.251          ///
   4.252          ///Your private PGP key has been successfully imported and will now be used as default p≡p key..
   4.253          /// </summary>
   4.254 -        public static string KeySyncWizard_Step4SuccessExplanationText {
   4.255 +        public static string KeySyncWizard_PGPSuccessExplanationText {
   4.256              get {
   4.257 -                return ResourceManager.GetString("KeySyncWizard_Step4SuccessExplanationText", resourceCulture);
   4.258 +                return ResourceManager.GetString("KeySyncWizard_PGPSuccessExplanationText", resourceCulture);
   4.259 +            }
   4.260 +        }
   4.261 +        
   4.262 +        /// <summary>
   4.263 +        ///   Looks up a localized string similar to Use the imported key as default key.
   4.264 +        /// </summary>
   4.265 +        public static string KeySyncWizard_SetImportedKeyAsDefault {
   4.266 +            get {
   4.267 +                return ResourceManager.GetString("KeySyncWizard_SetImportedKeyAsDefault", resourceCulture);
   4.268 +            }
   4.269 +        }
   4.270 +        
   4.271 +        /// <summary>
   4.272 +        ///   Looks up a localized string similar to Start.
   4.273 +        /// </summary>
   4.274 +        public static string KeySyncWizard_Start {
   4.275 +            get {
   4.276 +                return ResourceManager.GetString("KeySyncWizard_Start", resourceCulture);
   4.277              }
   4.278          }
   4.279          
     5.1 --- a/Properties/Resources.de.resx	Thu May 10 12:38:22 2018 +0200
     5.2 +++ b/Properties/Resources.de.resx	Thu May 17 11:26:23 2018 +0200
     5.3 @@ -651,7 +651,7 @@
     5.4      <value>Die Mailgröße überschreitet die zulässige Größenbeschränkung für die Verschlüsselung.</value>
     5.5    </data>
     5.6    <data name="Handshake_WrongFingerprint" xml:space="preserve">
     5.7 -    <value>Falscher Fingerprint</value>
     5.8 +    <value>Falscher Fingerabdruck</value>
     5.9    </data>
    5.10    <data name="Handshake_TrustwordsExpanderTooltipFull" xml:space="preserve">
    5.11      <value>Vollversion der Trustwords anzeigen</value>
    5.12 @@ -722,22 +722,16 @@
    5.13    <data name="KeySyncWizard_Finish" xml:space="preserve">
    5.14      <value>Fertig stellen</value>
    5.15    </data>
    5.16 -  <data name="KeySyncWizard_Step1PGPExplanationText" xml:space="preserve">
    5.17 -    <value>Bitte importieren Sie Ihren öffentlichen p≡p-Schlüssel auf Ihrem PGP-Gerät und senden Sie eine Antwortnachricht:  
    5.18 -
    5.19 -1. an die Sie Ihren öffentlichen PGP-Schlüssel anhängen und
    5.20 -2. die Sie mit dem gerade importierten p≡p-Schlüssel verschlüsseln</value>
    5.21 +  <data name="KeySyncWizard_PGPStep1ExplanationText" xml:space="preserve">
    5.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>
    5.23    </data>
    5.24 -  <data name="KeySyncWizard_Step2PGPExplanationText" xml:space="preserve">
    5.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>
    5.26 +  <data name="KeySyncWizard_PGPStep2ExplanationText" xml:space="preserve">
    5.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>
    5.28    </data>
    5.29 -  <data name="KeySyncWizard_Step3PGPExplanationText" xml:space="preserve">
    5.30 -    <value>Senden Sie nun bitte eine weitere Antwortnachricht:  
    5.31 -
    5.32 -1. an die Sie Ihren privaten PGP-Schlüssel anhängen und 
    5.33 -2. die Sie mit dem gerade importierten p≡p-Schlüssel verschlüsseln </value>
    5.34 +  <data name="KeySyncWizard_PGPStep3ExplanationText" xml:space="preserve">
    5.35 +    <value>Verschlüsseln Sie die Antwortnachricht mit dem öffentlichen p≡p-Schlüssel, den Sie gerade importiert haben und versenden Sie sie.</value>
    5.36    </data>
    5.37 -  <data name="KeySyncWizard_Step4SuccessExplanationText" xml:space="preserve">
    5.38 +  <data name="KeySyncWizard_PGPSuccessExplanationText" xml:space="preserve">
    5.39      <value>Schlüsselimport erfolgreich
    5.40  
    5.41  Ihr privater PGP-Schlüssel wurde erfolgreich importiert und wird nun standardmäßig auch als p≡p-Schlüssel verwendet.</value>
    5.42 @@ -745,23 +739,23 @@
    5.43    <data name="KeySyncWizard_WindowTitle" xml:space="preserve">
    5.44      <value>Schlüsselimport</value>
    5.45    </data>
    5.46 -  <data name="KeySyncWizard_Step1PEPExplanationText" xml:space="preserve">
    5.47 +  <data name="KeySyncWizard_PEPStep1ExplanationText" xml:space="preserve">
    5.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>
    5.49    </data>
    5.50 -  <data name="KeySyncWizard_Step2PEPExplanationText" xml:space="preserve">
    5.51 +  <data name="KeySyncWizard_PEPStep2ExplanationText" xml:space="preserve">
    5.52      <value>Bitte vergleichen Sie die folgenden Trustwords mit denjenigen auf Ihrem anderen Gerät und bestätigen Sie sie, wenn sie übereinstimmen.</value>
    5.53    </data>
    5.54    <data name="KeySyncWizard_WaitingForResponseText" xml:space="preserve">
    5.55      <value>Es wird auf eine Antwort vom anderen Gerät gewartet...</value>
    5.56    </data>
    5.57 -  <data name="KeySyncWizard_Step4PEPSuccessInitiatorExplanationText" xml:space="preserve">
    5.58 -    <value>Der Schlüssel von Ihrem anderen Gerät wird nun standardmäßig verwendet.</value>
    5.59 +  <data name="KeySyncWizard_PEPSuccessImport" xml:space="preserve">
    5.60 +    <value>Schlüsselimport erfolgreich!</value>
    5.61    </data>
    5.62 -  <data name="KeySyncWizard_Step4ErrorExplanationText" xml:space="preserve">
    5.63 +  <data name="KeySyncWizard_ErrorExplanationText" xml:space="preserve">
    5.64      <value>Es ist ein Fehler aufgetreten. Ihr Schlüssel konnte nicht importiert werden. Bitte versuchen Sie es erneut.</value>
    5.65    </data>
    5.66 -  <data name="KeySyncWizard_Step4PEPSuccessNonInitiatorExplanationText" xml:space="preserve">
    5.67 -    <value>Der Schlüssel des anderen Geräts kann nun zum Entschlüsseln von Nachrichten verwendet werden.</value>
    5.68 +  <data name="KeySyncWizard_PEPSuccessExport" xml:space="preserve">
    5.69 +    <value>Schlüsselexport erfolgreich!</value>
    5.70    </data>
    5.71    <data name="KeySyncWizard_SuccessText" xml:space="preserve">
    5.72      <value>Schlüsselimport erfolgreich!</value>
    5.73 @@ -769,7 +763,7 @@
    5.74    <data name="KeySyncWizard_ErrorText" xml:space="preserve">
    5.75      <value>Fehler</value>
    5.76    </data>
    5.77 -  <data name="KeySyncWizard_Step3PEPExplanationText" xml:space="preserve">
    5.78 +  <data name="KeySyncWizard_PEPStep3ExplanationText" xml:space="preserve">
    5.79      <value>Schlüssel wird importiert...</value>
    5.80    </data>
    5.81    <data name="StoreContextMenu_OpenPGPKeyImportWizard" xml:space="preserve">
    5.82 @@ -781,9 +775,6 @@
    5.83    <data name="StoreContextMenu_KeyImportText" xml:space="preserve">
    5.84      <value>Schlüsselimport</value>
    5.85    </data>
    5.86 -  <data name="KeySyncWizard_Step1PGPSubtitleText" xml:space="preserve">
    5.87 -    <value>Eine Nachricht mit Ihrem öffentlichen Schlüssel wurde an Sie selbst versendet.</value>
    5.88 -  </data>
    5.89    <data name="KeySyncWizard_PGPInitialMessageBody" xml:space="preserve">
    5.90      <value>Um mit dem Schlüsselimport fortzufahren, importieren Sie bitte den angehängten öffentlichen p≡p-Schlüssel und senden Sie eine Antwortnachricht:  
    5.91  
    5.92 @@ -793,4 +784,39 @@
    5.93    <data name="KeySyncWizard_PGPInitialMessageSubject" xml:space="preserve">
    5.94      <value>p≡p-Schlüsselimport</value>
    5.95    </data>
    5.96 +  <data name="KeySyncWizard_Start" xml:space="preserve">
    5.97 +    <value>Start</value>
    5.98 +  </data>
    5.99 +  <data name="KeySyncWizard_PEPStep1NonInitiatorExplanationText" xml:space="preserve">
   5.100 +    <value>Wenn Sie einen Schlüsselimport von einem anderen Gerät gestartet haben, klicken Sie bitte auf Start.
   5.101 +
   5.102 +Andernfalls klicken Sie bitte auf Abbrechen.</value>
   5.103 +  </data>
   5.104 +  <data name="KeySyncWizard_PGPStep5ExplanationText" xml:space="preserve">
   5.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>
   5.106 +  </data>
   5.107 +  <data name="KeySyncWizard_PGPStep6ExplanationText" xml:space="preserve">
   5.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>
   5.109 +  </data>
   5.110 +  <data name="KeySyncWizard_PGPStep7ExplanationText" xml:space="preserve">
   5.111 +    <value>Verschlüsseln Sie die Antwortnachricht nun wieder mit dem öffentlichen p≡p-Schlüssel und versenden Sie sie.</value>
   5.112 +  </data>
   5.113 +  <data name="KeySyncWizard_BackButtonText" xml:space="preserve">
   5.114 +    <value>Zurück</value>
   5.115 +  </data>
   5.116 +  <data name="KeySyncWizard_PEPStep4ExplanationText" xml:space="preserve">
   5.117 +    <value>Schlüsselimport erfolgreich!</value>
   5.118 +  </data>
   5.119 +  <data name="KeySyncWizard_ExportOwnPrivateKey" xml:space="preserve">
   5.120 +    <value>Meinen privaten Schlüssel auf das andere Gerät exportieren</value>
   5.121 +  </data>
   5.122 +  <data name="KeySyncWizard_SetImportedKeyAsDefault" xml:space="preserve">
   5.123 +    <value>Den importierten Schlüssel standardmäßig verwenden</value>
   5.124 +  </data>
   5.125 +  <data name="KeySyncWizard_PEPSuccessOtherKeyUsed" xml:space="preserve">
   5.126 +    <value>Der Schlüssel von Ihrem anderen Gerät kann nun ebenfalls zum Entschlüsseln verwendet werden.</value>
   5.127 +  </data>
   5.128 +  <data name="KeySyncWizard_PEPSuccessOtherKeyUsedAsDefault" xml:space="preserve">
   5.129 +    <value>Der Schlüssel von Ihrem anderen Gerät wird nun standardmäßig verwendet.</value>
   5.130 +  </data>
   5.131  </root>
   5.132 \ No newline at end of file
     6.1 --- a/Properties/Resources.resx	Thu May 10 12:38:22 2018 +0200
     6.2 +++ b/Properties/Resources.resx	Thu May 17 11:26:23 2018 +0200
     6.3 @@ -804,22 +804,16 @@
     6.4    <data name="KeySyncWizard_Finish" xml:space="preserve">
     6.5      <value>Finish</value>
     6.6    </data>
     6.7 -  <data name="KeySyncWizard_Step1PGPExplanationText" xml:space="preserve">
     6.8 -    <value>Please import your public p≡p key on your PGP device and reply with a message that:  
     6.9 -
    6.10 -1. has your public PGP key attached and
    6.11 -2. is encrypted with the p≡p key you just imported</value>
    6.12 +  <data name="KeySyncWizard_PGPStep1ExplanationText" xml:space="preserve">
    6.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>
    6.14    </data>
    6.15 -  <data name="KeySyncWizard_Step2PGPExplanationText" xml:space="preserve">
    6.16 -    <value>Please compare the PGP fingerprints of the below keys with the ones on your PGP device and confirm if they match.</value>
    6.17 +  <data name="KeySyncWizard_PGPStep2ExplanationText" xml:space="preserve">
    6.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>
    6.19    </data>
    6.20 -  <data name="KeySyncWizard_Step3PGPExplanationText" xml:space="preserve">
    6.21 -    <value>Please send now another reply message that:  
    6.22 -
    6.23 -1. has your private PGP key attached and
    6.24 -2. is encrypted with the p≡p key you just imported</value>
    6.25 +  <data name="KeySyncWizard_PGPStep3ExplanationText" xml:space="preserve">
    6.26 +    <value>Encrypt the answer message with the public p≡p key you just imported and send it.</value>
    6.27    </data>
    6.28 -  <data name="KeySyncWizard_Step4SuccessExplanationText" xml:space="preserve">
    6.29 +  <data name="KeySyncWizard_PGPSuccessExplanationText" xml:space="preserve">
    6.30      <value>Key successfully imported
    6.31  
    6.32  Your private PGP key has been successfully imported and will now be used as default p≡p key.</value>
    6.33 @@ -827,10 +821,10 @@
    6.34    <data name="KeySyncWizard_WindowTitle" xml:space="preserve">
    6.35      <value>Key Import</value>
    6.36    </data>
    6.37 -  <data name="KeySyncWizard_Step1PEPExplanationText" xml:space="preserve">
    6.38 +  <data name="KeySyncWizard_PEPStep1ExplanationText" xml:space="preserve">
    6.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>
    6.40    </data>
    6.41 -  <data name="KeySyncWizard_Step2PEPExplanationText" xml:space="preserve">
    6.42 +  <data name="KeySyncWizard_PEPStep2ExplanationText" xml:space="preserve">
    6.43      <value>Please compare the following Trustwords with the ones on your other device and confirm if they match.</value>
    6.44    </data>
    6.45    <data name="KeySyncWizard_WaitingForResponseText" xml:space="preserve">
    6.46 @@ -839,14 +833,14 @@
    6.47    <data name="KeySyncWizard_Next" xml:space="preserve">
    6.48      <value>Next</value>
    6.49    </data>
    6.50 -  <data name="KeySyncWizard_Step4PEPSuccessInitiatorExplanationText" xml:space="preserve">
    6.51 -    <value>The key from your other device will now be used as your default private key.</value>
    6.52 +  <data name="KeySyncWizard_PEPSuccessImport" xml:space="preserve">
    6.53 +    <value>Key successfully imported!</value>
    6.54    </data>
    6.55 -  <data name="KeySyncWizard_Step4ErrorExplanationText" xml:space="preserve">
    6.56 +  <data name="KeySyncWizard_ErrorExplanationText" xml:space="preserve">
    6.57      <value>An error occured. Your key could not be imported correctly. Please try again.</value>
    6.58    </data>
    6.59 -  <data name="KeySyncWizard_Step4PEPSuccessNonInitiatorExplanationText" xml:space="preserve">
    6.60 -    <value>The key from the other device can now be used to decrypt messages.</value>
    6.61 +  <data name="KeySyncWizard_PEPSuccessExport" xml:space="preserve">
    6.62 +    <value>Key successfully exported!</value>
    6.63    </data>
    6.64    <data name="KeySyncWizard_SuccessText" xml:space="preserve">
    6.65      <value>Key import successful!</value>
    6.66 @@ -854,7 +848,7 @@
    6.67    <data name="KeySyncWizard_ErrorText" xml:space="preserve">
    6.68      <value>Error</value>
    6.69    </data>
    6.70 -  <data name="KeySyncWizard_Step3PEPExplanationText" xml:space="preserve">
    6.71 +  <data name="KeySyncWizard_PEPStep3ExplanationText" xml:space="preserve">
    6.72      <value>Importing key...</value>
    6.73    </data>
    6.74    <data name="StoreContextMenu_OpenPGPKeyImportWizard" xml:space="preserve">
    6.75 @@ -869,9 +863,6 @@
    6.76    <data name="ImageLogoIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
    6.77      <value>..\resources\imagelogoicon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
    6.78    </data>
    6.79 -  <data name="KeySyncWizard_Step1PGPSubtitleText" xml:space="preserve">
    6.80 -    <value>A message with your public key has been sent to yourself.</value>
    6.81 -  </data>
    6.82    <data name="KeySyncWizard_PGPInitialMessageBody" xml:space="preserve">
    6.83      <value>To proceed with the Key Import, please import the attached public p≡p key and reply with a message that:  
    6.84  
    6.85 @@ -881,4 +872,39 @@
    6.86    <data name="KeySyncWizard_PGPInitialMessageSubject" xml:space="preserve">
    6.87      <value>p≡p Key Import</value>
    6.88    </data>
    6.89 +  <data name="KeySyncWizard_Start" xml:space="preserve">
    6.90 +    <value>Start</value>
    6.91 +  </data>
    6.92 +  <data name="KeySyncWizard_PEPStep1NonInitiatorExplanationText" xml:space="preserve">
    6.93 +    <value>If you initiated a key import for the following account, please click Start.
    6.94 +
    6.95 +If this was not you, please cancel.</value>
    6.96 +  </data>
    6.97 +  <data name="KeySyncWizard_PGPStep5ExplanationText" xml:space="preserve">
    6.98 +    <value>Please compare the PGP fingerprints of the below keys with the ones on your PGP device and confirm if they match.</value>
    6.99 +  </data>
   6.100 +  <data name="KeySyncWizard_PGPStep6ExplanationText" xml:space="preserve">
   6.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>
   6.102 +  </data>
   6.103 +  <data name="KeySyncWizard_PGPStep7ExplanationText" xml:space="preserve">
   6.104 +    <value>Encrypt the answer message again with the public p≡p key and send it.</value>
   6.105 +  </data>
   6.106 +  <data name="KeySyncWizard_BackButtonText" xml:space="preserve">
   6.107 +    <value>Back</value>
   6.108 +  </data>
   6.109 +  <data name="KeySyncWizard_PEPStep4ExplanationText" xml:space="preserve">
   6.110 +    <value>Key import successful!</value>
   6.111 +  </data>
   6.112 +  <data name="KeySyncWizard_ExportOwnPrivateKey" xml:space="preserve">
   6.113 +    <value>Export my private key to the other device</value>
   6.114 +  </data>
   6.115 +  <data name="KeySyncWizard_SetImportedKeyAsDefault" xml:space="preserve">
   6.116 +    <value>Use the imported key as default key</value>
   6.117 +  </data>
   6.118 +  <data name="KeySyncWizard_PEPSuccessOtherKeyUsedAsDefault" xml:space="preserve">
   6.119 +    <value>The key from your other device will now be used as your default private key.</value>
   6.120 +  </data>
   6.121 +  <data name="KeySyncWizard_PEPSuccessOtherKeyUsed" xml:space="preserve">
   6.122 +    <value>The key from your other device will now also be used to decrypt messages.</value>
   6.123 +  </data>
   6.124  </root>
   6.125 \ No newline at end of file
     7.1 --- a/ThisAddIn.cs	Thu May 10 12:38:22 2018 +0200
     7.2 +++ b/ThisAddIn.cs	Thu May 17 11:26:23 2018 +0200
     7.3 @@ -685,10 +685,12 @@
     7.4          /// <param name="validateSendingAccount">Validates that the SendingAccount matches the From identity of the given message.
     7.5          /// This can catch situations (and throw exceptions) where the default account would be used instead.</param>
     7.6          /// <param name="processMessage">Whether or not to process this message through the pEp engine.</param>
     7.7 +        /// <param name="setKeyImportHeader">Whether or not to process this message through the pEp engine.</param>
     7.8          internal void CreateAndSendMessage(PEPMessage message,
     7.9                                             bool deleteAfterSend,
    7.10                                             bool validateSendingAccount,
    7.11 -                                           bool processMessage = false)
    7.12 +                                           bool processMessage = false,
    7.13 +                                           bool setKeyImportHeader = false)
    7.14          {
    7.15              Outlook.MailItem newItem;
    7.16              Globals.ReturnStatus sts;
    7.17 @@ -721,10 +723,31 @@
    7.18                      MapiHelper.SetProperty(newItem, MapiProperty.PidLidUseTnef, false);
    7.19  
    7.20                      // If ForceUnencrypted property is set, add it to mail item
    7.21 +                    bool save = false;
    7.22                      if (message.ForceUnencrypted)
    7.23                      {
    7.24                          newItem.SetPEPProperty(MailItemExtensions.PEPProperty.ForceUnencrypted, true);
    7.25 -                        newItem.Save();
    7.26 +                        save = true;
    7.27 +                    }
    7.28 +
    7.29 +                    // Set KeyImport header if necessary
    7.30 +                    if (setKeyImportHeader)
    7.31 +                    {
    7.32 +                        newItem.SetPEPProperty(MailItemExtensions.PEPProperty.KeyImport, message.KeyImport);
    7.33 +                        save = true;
    7.34 +                    }
    7.35 +
    7.36 +                    // Save if necessary
    7.37 +                    if (save)
    7.38 +                    {
    7.39 +                        try
    7.40 +                        {
    7.41 +                            newItem.Save();
    7.42 +                        }
    7.43 +                        catch (Exception ex)
    7.44 +                        {
    7.45 +                            Log.Error("CreateAndSendMessage: Error saving new item. " + ex.ToString());
    7.46 +                        }
    7.47                      }
    7.48  
    7.49                      /* Send
     8.1 --- a/UI/HandshakeDialog.xaml.cs	Thu May 10 12:38:22 2018 +0200
     8.2 +++ b/UI/HandshakeDialog.xaml.cs	Thu May 17 11:26:23 2018 +0200
     8.3 @@ -4,7 +4,6 @@
     8.4  using System.Collections.ObjectModel;
     8.5  using System.ComponentModel;
     8.6  using System.Linq;
     8.7 -using System.Runtime.InteropServices;
     8.8  using System.Windows;
     8.9  using System.Windows.Controls;
    8.10  using System.Windows.Input;
     9.1 --- a/UI/HandshakeItemsControl.xaml	Thu May 10 12:38:22 2018 +0200
     9.2 +++ b/UI/HandshakeItemsControl.xaml	Thu May 17 11:26:23 2018 +0200
     9.3 @@ -201,7 +201,8 @@
     9.4                                    SelectedValuePath="Key"
     9.5                                    SelectedValue="{Binding Path=TrustwordsCulture, Mode=TwoWay}"
     9.6                                    IsEnabled="{Binding Path=ActiveTab, Converter={StaticResource IsActiveTabToBool}, ConverterParameter=Trustwords}"
     9.7 -                                  Foreground="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Converter={StaticResource IsEnabledToColor}}" />
     9.8 +                                  Foreground="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Converter={StaticResource IsEnabledToColor}}"
     9.9 +                                  Visibility="{Binding Path=Mode, Converter={StaticResource IsNotSyncModeToVisibility}}" />
    9.10                      </StackPanel>
    9.11  
    9.12                      <!-- Trustwords -->
    10.1 --- a/UI/HandshakeItemsControl.xaml.cs	Thu May 10 12:38:22 2018 +0200
    10.2 +++ b/UI/HandshakeItemsControl.xaml.cs	Thu May 17 11:26:23 2018 +0200
    10.3 @@ -127,5 +127,15 @@
    10.4                  handshakeItem.AreTrustwordsExpanded = ((sender as Expander)?.IsExpanded == true);
    10.5              }
    10.6          }
    10.7 +
    10.8 +        /// <summary>
    10.9 +        /// Raises the property changed event, if possible, with the given arguments.
   10.10 +        /// </summary>
   10.11 +        /// <param name="propertyName">The name of the property that changed.</param>
   10.12 +        private void RaisePropertyChangedEvent(string propertyName)
   10.13 +        {
   10.14 +            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   10.15 +            return;
   10.16 +        }
   10.17      }
   10.18  }
    11.1 --- a/UI/KeySyncWizard.xaml	Thu May 10 12:38:22 2018 +0200
    11.2 +++ b/UI/KeySyncWizard.xaml	Thu May 17 11:26:23 2018 +0200
    11.3 @@ -23,94 +23,92 @@
    11.4          <ResourceDictionary>
    11.5              <!-- Converters -->
    11.6              <BooleanToVisibilityConverter x:Key="BoolToVisibility" />
    11.7 -            <local:InvertBoolConverter x:Key="InvertBool" />
    11.8 -            <local:ValueConverterGroup x:Key="IsWizardStateToVisibility">
    11.9 -                <local:IsWizardStateConverter />
   11.10 -                <BooleanToVisibilityConverter />
   11.11 -            </local:ValueConverterGroup>
   11.12 -            <local:ValueConverterGroup x:Key="IsNotWizardStateToVisibility">
   11.13 -                <local:IsWizardStateConverter />
   11.14 +            <local:MultiBooleanToVisibilityConverter x:Key="MultiBooleanToVisibility" />
   11.15 +            <local:ValueConverterGroup x:Key="IsStringNotNullOrEmptyToVisibility">
   11.16 +                <local:IsStringEmptyConverter />
   11.17                  <local:InvertBoolConverter />
   11.18                  <BooleanToVisibilityConverter />
   11.19              </local:ValueConverterGroup>
   11.20 -            <local:ValueConverterGroup x:Key="IsNotWizardStateToBool">
   11.21 -                <local:IsWizardStateConverter />
   11.22 -                <local:InvertBoolConverter />
   11.23 -            </local:ValueConverterGroup>
   11.24 +            <local:IsWizardTypeConverter x:Key="IsWizardType" />
   11.25 +
   11.26 +            <!--Dictionary-->
   11.27 +            <ResourceDictionary.MergedDictionaries>
   11.28 +                <ResourceDictionary Source="pack://application:,,,/pEp;component/Resources/Dictionary.xaml" />
   11.29 +            </ResourceDictionary.MergedDictionaries>
   11.30          </ResourceDictionary>
   11.31      </Window.Resources>
   11.32  
   11.33 -    <!--The window content-->
   11.34 -    <StackPanel Width="470">
   11.35 -
   11.36 -        <!--Title section-->
   11.37 -        <Grid Background="White"
   11.38 -              Margin="0">
   11.39 -            <Grid.ColumnDefinitions>
   11.40 -                <ColumnDefinition Width="*" />
   11.41 -                <ColumnDefinition Width="Auto" />
   11.42 -            </Grid.ColumnDefinitions>
   11.43 -            <StackPanel Grid.Column="0">
   11.44 -                <TextBlock Margin="20,10,10,10"
   11.45 -                       Text="{Binding Path=TitleText}"
   11.46 -                       FontWeight="Bold" 
   11.47 -                       VerticalAlignment="Center"/>
   11.48 -                <TextBlock Margin="20,10,10,10"
   11.49 -                           Text="{Binding Path=SubtitleText}"
   11.50 -                           TextWrapping="Wrap"
   11.51 -                           VerticalAlignment="Center" />
   11.52 -            </StackPanel>
   11.53 -            <Image Grid.Column="1"
   11.54 -                   Stretch="Uniform"
   11.55 -                   Height="40"
   11.56 -                   VerticalAlignment="Center"
   11.57 -                   HorizontalAlignment="Right"
   11.58 -                   Margin="20,10"
   11.59 -                   Source="pack://application:,,,/pEp;component/Resources/ImageLogoMedium.png">
   11.60 -            </Image>
   11.61 -        </Grid>
   11.62 -
   11.63 -        <Separator Margin="0,0,0,20"
   11.64 -                   Background="LightGray" />
   11.65 +    <StackPanel Margin="10"
   11.66 +                Width="470">
   11.67  
   11.68          <!--Information section-->
   11.69 -        <TextBlock Text="{Binding Path=ExplanationText}"
   11.70 +        <TextBlock Text="{Binding Path=CurrentState.TitleText}"
   11.71                     TextWrapping="Wrap"
   11.72 -                   Margin="20,10" />
   11.73 +                   Margin="5,5,5,15" />
   11.74 +
   11.75 +        <!--User name section-->
   11.76 +        <TextBlock Text="{Binding Path=CurrentState.UserText}"
   11.77 +                   Padding="10"
   11.78 +                   MinHeight="80"
   11.79 +                   Background="White"
   11.80 +                   FontWeight="DemiBold"
   11.81 +                   Visibility="{Binding Path=CurrentState.IsUserTextVisible, Converter={StaticResource BoolToVisibility}}" />
   11.82  
   11.83          <!--Identities section-->
   11.84 -        <local:HandshakeItemsControl Margin="10,0"
   11.85 -                                     ItemsSource="{Binding Path=Items}"
   11.86 -                                     Visibility="{Binding Path=State, Converter={StaticResource IsWizardStateToVisibility}, ConverterParameter=Step2}" />
   11.87 +        <StackPanel Visibility="{Binding Path=CurrentState.AreTrustwordsVisible, Converter={StaticResource BoolToVisibility}}">
   11.88 +            <local:HandshakeItemsControl ItemsSource="{Binding Path=Items}" />
   11.89 +            <StackPanel Orientation="Horizontal"
   11.90 +                        Margin="5,10,5,0"
   11.91 +                        Visibility="{Binding Path=IsInitiator, Converter={StaticResource BoolToVisibility}}">
   11.92 +                <CheckBox VerticalAlignment="Center"
   11.93 +                          IsChecked="{Binding Path=SetImportedKeyAsDefault}" />
   11.94 +                <Label Content="{x:Static p:Resources.KeySyncWizard_SetImportedKeyAsDefault}"
   11.95 +                       MouseUp="LabelSetImportedKeyAsDefault_MouseUp"/>
   11.96 +            </StackPanel>
   11.97 +            <StackPanel Orientation="Horizontal"
   11.98 +                        Margin="5,0,5,5">
   11.99 +                <StackPanel.Visibility>
  11.100 +                    <MultiBinding Converter="{StaticResource MultiBooleanToVisibility}">
  11.101 +                        <Binding Path="IsInitiator" />
  11.102 +                        <Binding Path="Type" Converter="{StaticResource IsWizardType}" ConverterParameter="pEp" />
  11.103 +                    </MultiBinding>
  11.104 +                </StackPanel.Visibility>
  11.105 +                <CheckBox VerticalAlignment="Center"
  11.106 +                          IsChecked="{Binding Path=ExportPrivateKey}" />
  11.107 +                <Label Content="{x:Static p:Resources.KeySyncWizard_ExportOwnPrivateKey}" 
  11.108 +                       MouseUp="LabelExportPrivateKey_MouseUp"/>
  11.109 +            </StackPanel>
  11.110 +        </StackPanel>
  11.111  
  11.112 -        <Separator Margin="10,20,10,0" 
  11.113 -                   Background="LightGray"/>
  11.114 +        <!--Subtitle section-->
  11.115 +        <TextBlock Text="{Binding Path=CurrentState.SubtitleText}"
  11.116 +                   TextWrapping="Wrap"
  11.117 +                   Margin="5,15"
  11.118 +                   Visibility="{Binding Path=CurrentState.SubtitleText, Converter={StaticResource IsStringNotNullOrEmptyToVisibility}}" />
  11.119  
  11.120          <!--Buttons section-->
  11.121 -        <Grid>
  11.122 -            <Grid.ColumnDefinitions>
  11.123 -                <ColumnDefinition Width="*" />
  11.124 -                <ColumnDefinition Width="Auto" />
  11.125 -            </Grid.ColumnDefinitions>
  11.126 -            <StackPanel Grid.Column="1"
  11.127 -                        Margin="10"
  11.128 -                        Orientation="Horizontal">
  11.129 -                <Button x:Name="OKNextButton"
  11.130 -                        Margin="5"
  11.131 -                        Padding="5,2"
  11.132 -                        MinWidth="70"
  11.133 -                        IsEnabled="{Binding Path=State, Converter={StaticResource IsNotWizardStateToBool}, ConverterParameter=Step1|Step3}"
  11.134 -                        Click="OKNextButton_Click"
  11.135 -                        Content="{Binding Path=NextButtonText}" />
  11.136 -                <Button x:Name="CancelButton"
  11.137 -                        Margin="5"
  11.138 -                        Padding="5,2"
  11.139 -                        MinWidth="70"
  11.140 -                        Click="CancelButton_Click"
  11.141 -                        Visibility="{Binding Path=State, Converter={StaticResource IsNotWizardStateToVisibility}, ConverterParameter=Step4}"
  11.142 -                        Content="{x:Static p:Resources.Options_CancelText}" />
  11.143 -            </StackPanel>
  11.144 -        </Grid>
  11.145 +        <StackPanel Margin="0,10"
  11.146 +                    Orientation="Horizontal"
  11.147 +                    HorizontalAlignment="Right">
  11.148 +            <Button x:Name="BackButton"
  11.149 +                    Style="{StaticResource StyleCancelButton}"
  11.150 +                    Margin="0,5,5,5"
  11.151 +                    Click="BackButton_Click"
  11.152 +                    Content="{x:Static p:Resources.KeySyncWizard_BackButtonText}"
  11.153 +                    Visibility="{Binding Path=CurrentState.IsBackButtonVisible, Converter={StaticResource BoolToVisibility}}" />
  11.154 +            <Button x:Name="AcceptButton"
  11.155 +                    Style="{StaticResource StyleConfirmButton}"
  11.156 +                    Margin="5"
  11.157 +                    Click="AcceptButton_Click"
  11.158 +                    Content="{Binding Path=CurrentState.AcceptButtonText}"
  11.159 +                    Visibility="{Binding Path=CurrentState.IsAcceptButtonVisible, Converter={StaticResource BoolToVisibility}}" />
  11.160 +            <Button x:Name="CancelButton"
  11.161 +                    Margin="5,5,0,5"
  11.162 +                    Style="{StaticResource StyleWrongButton}"
  11.163 +                    Click="CancelButton_Click"
  11.164 +                    Content="{Binding Path=CurrentState.CancelButtonText}"
  11.165 +                    Visibility="{Binding Path=CurrentState.IsCancelButtonVisible, Converter={StaticResource BoolToVisibility}}" />
  11.166 +        </StackPanel>
  11.167      </StackPanel>
  11.168  </Window>
  11.169  
    12.1 --- a/UI/KeySyncWizard.xaml.cs	Thu May 10 12:38:22 2018 +0200
    12.2 +++ b/UI/KeySyncWizard.xaml.cs	Thu May 17 11:26:23 2018 +0200
    12.3 @@ -3,7 +3,10 @@
    12.4  using System.Collections.Generic;
    12.5  using System.Collections.ObjectModel;
    12.6  using System.ComponentModel;
    12.7 +using System.Threading.Tasks;
    12.8  using System.Windows;
    12.9 +using System.Windows.Input;
   12.10 +using System.Windows.Threading;
   12.11  using Outlook = Microsoft.Office.Interop.Outlook;
   12.12  
   12.13  namespace pEp.UI
   12.14 @@ -15,8 +18,23 @@
   12.15                                             INotifyPropertyChanged,
   12.16                                             Interfaces.IReset
   12.17      {
   12.18 -        public const string PEP_PGP_SYNC_MESSAGE_SUBJECT    = "p≡p Key Import";
   12.19 -        public const string PEP_PGP_SYNC_MESSAGE_BODY       = "";
   12.20 +        /// <summary>
   12.21 +        /// Defines the step this wizard is currently in.
   12.22 +        /// </summary>
   12.23 +        public enum Steps
   12.24 +        {
   12.25 +            Undefined,
   12.26 +            Success,
   12.27 +            Error,
   12.28 +            Step1,
   12.29 +            Step2,
   12.30 +            Step3,
   12.31 +            Step4,
   12.32 +            Step5,
   12.33 +            Step6,
   12.34 +            Step7,
   12.35 +            Step8
   12.36 +        }
   12.37  
   12.38          /// <summary>
   12.39          /// The message types for sync messages.
   12.40 @@ -40,66 +58,33 @@
   12.41          }
   12.42  
   12.43          /// <summary>
   12.44 -        /// Defines the state (step) this wizard is currently in.
   12.45 -        /// </summary>
   12.46 -        public enum WizardState
   12.47 -        {
   12.48 -            /// <summary>
   12.49 -            /// Undefined state. Should never occur.
   12.50 -            /// </summary>
   12.51 -            Undefined,
   12.52 -
   12.53 -            /// <summary>
   12.54 -            /// First state on the side of the device that initiated
   12.55 -            /// the process. Will send a first message and wait for
   12.56 -            /// an answer message from the other device.
   12.57 -            /// </summary>
   12.58 -            Step1,
   12.59 -
   12.60 -            /// <summary>
   12.61 -            /// Showing the Trustwords dialog, waiting for user input.
   12.62 -            /// </summary>
   12.63 -            Step2,
   12.64 -
   12.65 -            /// <summary>
   12.66 -            /// Trustwords are accepted, the private key is being sent.
   12.67 -            /// Waiting for key from other device.
   12.68 -            /// </summary>
   12.69 -            Step3,
   12.70 -
   12.71 -            /// <summary>
   12.72 -            /// Process has finished (successfully or not).
   12.73 -            /// </summary>
   12.74 -            Step4
   12.75 -        }
   12.76 -
   12.77 -        /// <summary>
   12.78          /// Event raised when a property is changed on a component.
   12.79          /// </summary>
   12.80          public event PropertyChangedEventHandler PropertyChanged;
   12.81  
   12.82 -        private string                                  _ExplanationText;
   12.83 +        private WizardState                             _CurrentState;
   12.84 +        private bool                                    _ExportPrivateKey;
   12.85 +        private bool                                    _IsInitiator;
   12.86          private ObservableCollection<HandshakeItem>     _Items;
   12.87          private PEPIdentity                             _Myself;
   12.88 -        private string                                  _NextButtonText;
   12.89          private PEPIdentity                             _Partner;
   12.90 -        private WizardState                             _State;
   12.91 -        private string                                  _SubtitleText;
   12.92 -        private bool                                    _Success;
   12.93 -        private string                                  _TitleText;
   12.94 +        private Steps                                   _Step;
   12.95 +        private bool                                    _SetImportedKeyAsDefault;
   12.96          private WizardType                              _Type;
   12.97  
   12.98 +        private bool                                    privateKeyImported = false;
   12.99 +        private List<MessageTypes>                      sentMessages                = new List<MessageTypes>();
  12.100 +        private List<PEPMessage>                        receivedSyncMessages        = new List<PEPMessage>();
  12.101 +        private List<WizardState>                       states = new List<WizardState>();
  12.102 +        private object                                  mutexReceivedSyncMessages   = new object();
  12.103 +
  12.104          public static KeySyncWizard                     Wizard = null;
  12.105  
  12.106 -        private bool                                    isInitiator         = false;
  12.107 -        private List<MessageTypes>                      sentMessages = new List<MessageTypes>();
  12.108 -
  12.109          /// <summary>
  12.110          /// Default constructor
  12.111          /// </summary>
  12.112          public KeySyncWizard()
  12.113 -        {
  12.114 -        }
  12.115 +        { }
  12.116  
  12.117          /// <summary>
  12.118          /// Constructor to create a new key sync wizard.
  12.119 @@ -118,58 +103,26 @@
  12.120                  KeySyncWizard.Wizard.Close();
  12.121              }
  12.122  
  12.123 +            // Reset all values
  12.124 +            this.Reset();
  12.125 +
  12.126              // Initialize the window
  12.127              InitializeComponent();
  12.128  
  12.129              // Set current wizard
  12.130              KeySyncWizard.Wizard = this;
  12.131  
  12.132 -            // Reset all values
  12.133 -            this.Reset();
  12.134 -
  12.135              // Initialize the wizard
  12.136 -            this.InitializeWizard(type, myself, partnerFpr);
  12.137 -
  12.138 -            // Set if wizard is the one that has started the sync process
  12.139 -            this.isInitiator = isInitiator;
  12.140 +            this.InitializeWizard(isInitiator, type, myself, partnerFpr);
  12.141  
  12.142              // Attach event handler for new sync messages
  12.143 -            CryptableMailItem.SyncMessageReceived += KeySyncWizard_SyncMessageReceived;
  12.144 +            MsgProcessor.SyncMessageReceived += KeySyncWizard_SyncMessageReceived;
  12.145  
  12.146 -            // Either send initial or answer message
  12.147 -            if (isInitiator)
  12.148 +            // Send initial message if necessary
  12.149 +            if (this.IsInitiator)
  12.150              {
  12.151 -                // Send initial message
  12.152                  this.SendSyncMessage(MessageTypes.InitialMessage);
  12.153              }
  12.154 -            else
  12.155 -            {
  12.156 -                try
  12.157 -                {
  12.158 -                    // Update own identity
  12.159 -                    this.Myself = new PEPIdentity(ThisAddIn.PEPEngine.Myself(this.Myself.ToCOMType()));
  12.160 -
  12.161 -                    // Create handshake item
  12.162 -                    if (this.CreateHandshakeItem())
  12.163 -                    {
  12.164 -                        // Send answer message with pub key
  12.165 -                        this.SendSyncMessage(MessageTypes.PublicKeyMessage);
  12.166 -
  12.167 -                        // Go to next step
  12.168 -                        this.GoToNextStep();
  12.169 -                    }
  12.170 -                    else
  12.171 -                    {
  12.172 -                        Log.Error("KeySyncWizard: Error creating handshake item.");
  12.173 -                        this.GoToLastStep(false);
  12.174 -                    }
  12.175 -                }
  12.176 -                catch (Exception ex)
  12.177 -                {
  12.178 -                    Log.Error("KeySyncWizard: Error updating Myself. " + ex.ToString());
  12.179 -                    this.GoToLastStep(false);
  12.180 -                }
  12.181 -            }
  12.182          }
  12.183  
  12.184          #region Property Accessors
  12.185 @@ -180,15 +133,42 @@
  12.186           *************************************************************/
  12.187  
  12.188          /// <summary>
  12.189 -        /// Gets or sets the explanatory text in the wizard.
  12.190 +        /// Gets or sets the Items collection.
  12.191          /// </summary>
  12.192 -        public string ExplanationText
  12.193 +        public WizardState CurrentState
  12.194          {
  12.195 -            get { return this._ExplanationText; }
  12.196 +            get { return this._CurrentState; }
  12.197              set
  12.198              {
  12.199 -                this._ExplanationText = value;
  12.200 -                this.RaisePropertyChangedEvent(nameof(this.ExplanationText));
  12.201 +                this._CurrentState = value;
  12.202 +                this.RaisePropertyChangedEvent(nameof(this.CurrentState));
  12.203 +            }
  12.204 +        }
  12.205 +
  12.206 +        /// <summary>
  12.207 +        /// Gets or sets whether to export the private key.
  12.208 +        /// </summary>
  12.209 +        public bool ExportPrivateKey
  12.210 +        {
  12.211 +            get { return this._ExportPrivateKey; }
  12.212 +            set
  12.213 +            {
  12.214 +                this._ExportPrivateKey = value;
  12.215 +                this.RaisePropertyChangedEvent(nameof(this.ExportPrivateKey));
  12.216 +            }
  12.217 +        }
  12.218 +
  12.219 +        /// <summary>
  12.220 +        /// Gets or sets whether this wizard is the one that
  12.221 +        /// initiated the Key Import process.
  12.222 +        /// </summary>
  12.223 +        public bool IsInitiator
  12.224 +        {
  12.225 +            get { return this._IsInitiator; }
  12.226 +            set
  12.227 +            {
  12.228 +                this._IsInitiator = value;
  12.229 +                this.RaisePropertyChangedEvent(nameof(this.IsInitiator));
  12.230              }
  12.231          }
  12.232  
  12.233 @@ -219,19 +199,6 @@
  12.234          }
  12.235  
  12.236          /// <summary>
  12.237 -        /// Gets or sets the Next/Finish button's text.
  12.238 -        /// </summary>
  12.239 -        public string NextButtonText
  12.240 -        {
  12.241 -            get { return this._NextButtonText; }
  12.242 -            set
  12.243 -            {
  12.244 -                this._NextButtonText = value;
  12.245 -                this.RaisePropertyChangedEvent(nameof(this.NextButtonText));
  12.246 -            }
  12.247 -        }
  12.248 -
  12.249 -        /// <summary>
  12.250          /// Gets or sets the sync partner.
  12.251          /// </summary>
  12.252          public PEPIdentity Partner
  12.253 @@ -245,56 +212,35 @@
  12.254          }
  12.255  
  12.256          /// <summary>
  12.257 -        /// Gets or sets the wizard state.
  12.258 +        /// Gets or sets the current wizard step.
  12.259          /// </summary>
  12.260 -        public WizardState State
  12.261 +        public Steps Step
  12.262          {
  12.263 -            get { return this._State; }
  12.264 +            get { return this._Step; }
  12.265              set
  12.266              {
  12.267 -                this._State = value;
  12.268 -                this.RaisePropertyChangedEvent(nameof(this.State));
  12.269 +                this._Step = value;
  12.270 +                this.RaisePropertyChangedEvent(nameof(this.Step));
  12.271              }
  12.272          }
  12.273  
  12.274          /// <summary>
  12.275 -        /// Gets or sets the subtitle text in the wizard.
  12.276 +        /// Gets or sets whether to use the imported key as default key.
  12.277          /// </summary>
  12.278 -        public string SubtitleText
  12.279 +        public bool SetImportedKeyAsDefault
  12.280          {
  12.281 -            get { return this._SubtitleText; }
  12.282 +            get { return this._SetImportedKeyAsDefault; }
  12.283              set
  12.284              {
  12.285 -                this._SubtitleText = value;
  12.286 -                this.RaisePropertyChangedEvent(nameof(this.SubtitleText));
  12.287 +                this._SetImportedKeyAsDefault = value;
  12.288 +                this.RaisePropertyChangedEvent(nameof(this.SetImportedKeyAsDefault));
  12.289              }
  12.290          }
  12.291  
  12.292          /// <summary>
  12.293          /// Gets or sets the success state.
  12.294          /// </summary>
  12.295 -        public bool Success
  12.296 -        {
  12.297 -            get { return this._Success; }
  12.298 -            set
  12.299 -            {
  12.300 -                this._Success = value;
  12.301 -                this.RaisePropertyChangedEvent(nameof(this.Success));
  12.302 -            }
  12.303 -        }
  12.304  
  12.305 -        /// <summary>
  12.306 -        /// Gets or sets the title text in the wizard.
  12.307 -        /// </summary>
  12.308 -        public string TitleText
  12.309 -        {
  12.310 -            get { return this._TitleText; }
  12.311 -            set
  12.312 -            {
  12.313 -                this._TitleText = value;
  12.314 -                this.RaisePropertyChangedEvent(nameof(this.TitleText));
  12.315 -            }
  12.316 -        }
  12.317  
  12.318          /// <summary>
  12.319          /// Gets or sets the wizard type.
  12.320 @@ -309,6 +255,35 @@
  12.321              }
  12.322          }
  12.323  
  12.324 +        /// <summary>
  12.325 +        /// Gets the user name to display in the dialog.
  12.326 +        /// </summary>
  12.327 +        public string UserName
  12.328 +        {
  12.329 +            get
  12.330 +            {
  12.331 +                string userName = string.Empty;
  12.332 +
  12.333 +                // Try to get user name in format "name (address)"
  12.334 +                if (string.IsNullOrEmpty(this.Myself?.UserName) == false)
  12.335 +                {
  12.336 +                    userName = this.Myself.UserName;
  12.337 +
  12.338 +                    if (string.IsNullOrEmpty(this.Myself?.Address) == false)
  12.339 +                    {
  12.340 +                        userName += " (" + this.Myself.Address + ")";
  12.341 +                    }
  12.342 +                }
  12.343 +                // If we have no user name, just display address
  12.344 +                else if (string.IsNullOrEmpty(this.Myself?.Address) == false)
  12.345 +                {
  12.346 +                    userName = this.Myself.Address;
  12.347 +                }
  12.348 +
  12.349 +                return userName;
  12.350 +            }
  12.351 +        }
  12.352 +
  12.353          #endregion
  12.354  
  12.355          #region Event handlers
  12.356 @@ -318,39 +293,195 @@
  12.357           * 
  12.358           *************************************************************/
  12.359  
  12.360 +        /// <summary>
  12.361 +        /// Event handler for when the OK/Next button is clicked.
  12.362 +        /// </summary>
  12.363 +        private void AcceptButton_Click(object sender, RoutedEventArgs e)
  12.364 +        {
  12.365 +            this.CurrentState.AcceptButtonClick();
  12.366 +        }
  12.367 +
  12.368 +        /// <summary>
  12.369 +        /// Event handler for when the Back button is clicked.
  12.370 +        /// </summary>
  12.371 +        private void BackButton_Click(object sender, RoutedEventArgs e)
  12.372 +        {
  12.373 +            this.CurrentState.BackButtonClick();
  12.374 +        }
  12.375 +
  12.376 +        /// <summary>
  12.377 +        /// Event handler for when the Cancel button is clicked.
  12.378 +        /// </summary>
  12.379          private void CancelButton_Click(object sender, RoutedEventArgs e)
  12.380          {
  12.381 -            this.Close();
  12.382 +            this.CurrentState.CancelButtonClick();
  12.383          }
  12.384  
  12.385 -        private void OKNextButton_Click(object sender, RoutedEventArgs e)
  12.386 +        /// <summary>
  12.387 +        /// Event handler for when a sync message arrives while the wizard is open and in progress.
  12.388 +        /// </summary>
  12.389 +        private void KeySyncWizard_SyncMessageReceived(object sender, MsgProcessor.SyncMessageEventArgs e)
  12.390          {
  12.391 -            // Navigation logic
  12.392 -            switch (this.State)
  12.393 +            // Ignore outgoing messages
  12.394 +            if (e.Message?.Direction == pEpMsgDirection.pEpDirIncoming)
  12.395              {
  12.396 -                case WizardState.Step2:
  12.397 +                try
  12.398 +                {
  12.399 +                    // Waiting for message with public key from other device
  12.400 +                    if (((this.Type == WizardType.pEp) && (this.Step == Steps.Step1)) ||
  12.401 +                        ((this.Type == WizardType.PGP) && (this.Step == Steps.Step4)))
  12.402                      {
  12.403 -                        // User accepts the fingerprint. Make channel green.
  12.404 -                        this.TrustKey();
  12.405 +                        string partnerFpr = null;
  12.406 +
  12.407 +                        // Make sure the channel is not already trusted (either attack or re-processing)
  12.408 +                        if (e.Message?.Rating >= pEpRating.pEpRatingTrusted)
  12.409 +                        {
  12.410 +                            Log.Warning("KeySyncWizard_SyncMessageReceived: Sync message for already trusted channel received.");
  12.411 +                            return;
  12.412 +                        }
  12.413 +
  12.414 +                        // In case of pEp sync, use header
  12.415 +                        if (this.Type == WizardType.pEp)
  12.416 +                        {
  12.417 +                            // Public key message received. Show trustwords.
  12.418 +                            partnerFpr = e.Message?.KeyImport;
  12.419 +
  12.420 +                            Log.Verbose("KeySyncWizard_SyncMessageReceived: pEp import, partner fingerprint is " + partnerFpr);
  12.421 +
  12.422 +                            // Doublecheck that it's not the own key
  12.423 +                            if (this.Myself?.Fingerprint?.Equals(partnerFpr) == true)
  12.424 +                            {
  12.425 +                                partnerFpr = null;
  12.426 +                            }
  12.427 +                        }
  12.428 +                        else if (this.Type == WizardType.PGP)
  12.429 +                        {
  12.430 +                            // In case of PGP import, use key list
  12.431 +                            string[] keys = e.Message?.KeyList?.Split(',');
  12.432 +                            for (int i = 0; i < keys?.Length; i++)
  12.433 +                            {
  12.434 +                                if (keys[i]?.Equals(this.Myself?.Fingerprint) == false)
  12.435 +                                {
  12.436 +                                    partnerFpr = keys[i];
  12.437 +                                    Log.Verbose("KeySyncWizard_SyncMessageReceived: PGP import, partner fingerprint is " + partnerFpr ?? "null");
  12.438 +                                    break;
  12.439 +                                }
  12.440 +                            }
  12.441 +                        }
  12.442 +                        else
  12.443 +                        {
  12.444 +                            Log.Error("KeySyncWizard_SyncMessageReceived: WizardType unknown.");
  12.445 +                        }
  12.446 +
  12.447 +                        // If we have a valid fingerprint, show Trustwords
  12.448 +                        if ((this.IsInitiator) &&
  12.449 +                            (string.IsNullOrEmpty(partnerFpr) == false))
  12.450 +                        {
  12.451 +                            // Set the partner's fingerprint
  12.452 +                            this.Partner.Fingerprint = partnerFpr;
  12.453 +
  12.454 +                            // Marshall to main thread
  12.455 +                            this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
  12.456 +                            {
  12.457 +                                // Create the handshake item 
  12.458 +                                if (this.CreateHandshakeItem())
  12.459 +                                {
  12.460 +                                    this.GoToNextStep();
  12.461 +                                }
  12.462 +                                else
  12.463 +                                {
  12.464 +                                    Log.Error("KeySyncWizard_SyncMessageReceived: Error creating handshake item.");
  12.465 +                                    this.GoToLastStep(false);
  12.466 +                                }
  12.467 +                            }));
  12.468 +                        }
  12.469 +                        else
  12.470 +                        {
  12.471 +                            Log.Error("KeySyncWizard_SyncMessageReceived: Partner fingerprint is null.");
  12.472 +                        }
  12.473                      }
  12.474 -                    break;
  12.475 -                /* 'Step 1' and 'Step 3' are not clickable. 
  12.476 -                 * 'Step 4' finishes the process. 
  12.477 -                 * 'Undefined' means an error occured.
  12.478 -                 */
  12.479 -                case WizardState.Step1:
  12.480 -                case WizardState.Step3:
  12.481 -                case WizardState.Step4:
  12.482 -                case WizardState.Undefined:
  12.483 -                default:
  12.484 +                    // Waiting for private key message
  12.485 +                    else if (((this.Type == WizardType.pEp) && (this.Step == Steps.Step3)) ||
  12.486 +                             ((this.Type == WizardType.PGP) && (this.Step == Steps.Step8)))
  12.487                      {
  12.488 -                        this.Close();
  12.489 +                        /* Finish the process under the following conditions:
  12.490 +                         *  1. PGP key import + own private key flag
  12.491 +                         *  2. pEp key import +
  12.492 +                         *      a. initiator wizard + own private key flag + partner fpr in key import header
  12.493 +                         *      b. not initiator wizard + trusted message + partner fpr in key import header
  12.494 +                         */
  12.495 +                        bool hasDecryptFlagOwnPrivateKey = e.Flags.HasFlag(pEpDecryptFlags.pEpDecryptFlagOwnPrivateKey);
  12.496 +                        if (((this.Type == WizardType.PGP) && (hasDecryptFlagOwnPrivateKey)) ||
  12.497 +                            ((this.IsInitiator) && (e.Message.KeyImport?.Equals(this.Partner?.Fingerprint) == true) && (hasDecryptFlagOwnPrivateKey)) ||
  12.498 +                            ((this.IsInitiator == false) && (e.Message.KeyImport?.Equals(this.Partner?.Fingerprint) == true) && (e.Message.Rating >= pEpRating.pEpRatingTrusted)))
  12.499 +                        {
  12.500 +                            // Set flag
  12.501 +                            this.privateKeyImported = hasDecryptFlagOwnPrivateKey;
  12.502 +
  12.503 +                            // Marshall to main thread
  12.504 +                            this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
  12.505 +                            {
  12.506 +                                // Set private key as default if needed
  12.507 +                                bool success = false;
  12.508 +                                if ((this.IsInitiator) &&
  12.509 +                                    (this.SetImportedKeyAsDefault))
  12.510 +                                {
  12.511 +                                    try
  12.512 +                                    {
  12.513 +                                        pEpIdentity partner = this.Partner.ToCOMType();
  12.514 +                                        ThisAddIn.PEPEngine.SetOwnKey(partner, partner.fpr);
  12.515 +                                        success = true;
  12.516 +                                    }
  12.517 +                                    catch (Exception ex)
  12.518 +                                    {
  12.519 +                                        success = false;
  12.520 +                                        Log.Error("AcceptButtonClick: Error setting own key. " + ex.ToString());
  12.521 +                                    }
  12.522 +                                }
  12.523 +                                else
  12.524 +                                {
  12.525 +                                    success = true;
  12.526 +                                }
  12.527 +
  12.528 +                                this.GoToLastStep(success);
  12.529 +
  12.530 +                            }));
  12.531 +                        }
  12.532 +                        else
  12.533 +                        {
  12.534 +                            Log.Verbose("KeySyncWizard_SyncMessageReceived: Message not processed. Steps: Step 3. Own private key flag is " +
  12.535 +                                        e.Flags.HasFlag(pEpDecryptFlags.pEpDecryptFlagOwnPrivateKey).ToString() + ". Rating is " +
  12.536 +                                        Enum.GetName(typeof(pEpRating), e.Message?.Rating ?? pEpRating.pEpRatingUndefined) + ". KeyImport is " +
  12.537 +                                        e.Message?.KeyImport ?? "null");
  12.538 +                        }
  12.539                      }
  12.540 -                    break;
  12.541 +                }
  12.542 +                catch (Exception ex)
  12.543 +                {
  12.544 +                    Log.Error("KeySyncWizard_SyncMessageReceived: Error processing sync message. " + ex.ToString());
  12.545 +                }
  12.546              }
  12.547          }
  12.548  
  12.549          /// <summary>
  12.550 +        /// Event handler for when the label next to the Export Private Key checkbox
  12.551 +        /// is clicked.
  12.552 +        /// </summary>
  12.553 +        private void LabelExportPrivateKey_MouseUp(object sender, MouseButtonEventArgs e)
  12.554 +        {
  12.555 +            this.ExportPrivateKey = (this.ExportPrivateKey == false);
  12.556 +        }
  12.557 +
  12.558 +        /// <summary>
  12.559 +        /// Event handler for when the label next to the Set Imported Key As Default checkbox
  12.560 +        /// is clicked.
  12.561 +        /// </summary>
  12.562 +        private void LabelSetImportedKeyAsDefault_MouseUp(object sender, MouseButtonEventArgs e)
  12.563 +        {
  12.564 +            this.SetImportedKeyAsDefault = (this.SetImportedKeyAsDefault == false);
  12.565 +        }
  12.566 +
  12.567 +        /// <summary>
  12.568          /// Raises the property changed event, if possible, with the given arguments.
  12.569          /// </summary>
  12.570          /// <param name="propertyName">The name of the property that changed.</param>
  12.571 @@ -361,127 +492,40 @@
  12.572          }
  12.573  
  12.574          /// <summary>
  12.575 -        /// Event handler for when a sync message arrives while the wizard is open and in progress.
  12.576 +        /// Shows the handshake window
  12.577          /// </summary>
  12.578 -        private void KeySyncWizard_SyncMessageReceived(object sender, CryptableMailItem.SyncMessageEventArgs e)
  12.579 +        private bool ShowHandshake()
  12.580          {
  12.581 -            // Ignore outgoing messages
  12.582 -            if (e.Message?.Direction == pEpMsgDirection.pEpDirIncoming)
  12.583 +            bool success = false;
  12.584 +
  12.585 +            try
  12.586              {
  12.587 -                try
  12.588 +                // Update own identity if necessary
  12.589 +                if (string.IsNullOrEmpty(this.Myself?.Fingerprint))
  12.590                  {
  12.591 -                    switch (this.State)
  12.592 -                    {
  12.593 -                        // Step 1: get partner fingerprint and show Trustwords
  12.594 -                        case WizardState.Step1:
  12.595 -                            {
  12.596 -                                string partnerFpr = null;
  12.597 +                    this.Myself = new PEPIdentity(ThisAddIn.PEPEngine.Myself(this.Myself.ToCOMType()));
  12.598 +                }
  12.599  
  12.600 -                                // Make sure the channel is not already trusted (either attack or re-processing)
  12.601 -                                if (e.Message?.Rating >= pEpRating.pEpRatingTrusted)
  12.602 -                                {
  12.603 -                                    Log.Warning("KeySyncWizard_SyncMessageReceived: Sync message for already trusted channel received.");
  12.604 -                                    return;
  12.605 -                                }
  12.606 +                // Create handshake item
  12.607 +                if (this.CreateHandshakeItem())
  12.608 +                {
  12.609 +                    // Set success flag
  12.610 +                    success = true;
  12.611  
  12.612 -                                // In case of pEp sync, use header
  12.613 -                                if (this.Type == WizardType.pEp)
  12.614 -                                {
  12.615 -                                    // Public key message received. Show trustwords.
  12.616 -                                    partnerFpr = e.Message?.KeyImport;
  12.617 -
  12.618 -                                    Log.Verbose("KeySyncWizard_SyncMessageReceived: pEp import, partner fingerprint is " + partnerFpr);
  12.619 -
  12.620 -                                    // Doublecheck that it's not the own key
  12.621 -                                    if (this.Myself?.Fingerprint?.Equals(partnerFpr) == true)
  12.622 -                                    {
  12.623 -                                        partnerFpr = null;
  12.624 -                                    }
  12.625 -                                }
  12.626 -                                else if (this.Type == WizardType.PGP)
  12.627 -                                {
  12.628 -                                    // In case of PGP import, use key list
  12.629 -                                    string[] keys = e.Message?.KeyList?.Split(',');
  12.630 -                                    for (int i = 0; i < keys?.Length; i++)
  12.631 -                                    {
  12.632 -                                        if (keys[i]?.Equals(this.Myself?.Fingerprint) == false)
  12.633 -                                        {
  12.634 -                                            partnerFpr = keys[i];
  12.635 -                                            Log.Verbose("KeySyncWizard_SyncMessageReceived: PGP import, partner fingerprint is " + partnerFpr ?? "null");
  12.636 -                                            break;
  12.637 -                                        }
  12.638 -                                    }
  12.639 -                                }
  12.640 -                                else
  12.641 -                                {
  12.642 -                                    Log.Error("KeySyncWizard_SyncMessageReceived: WizardType unknown.");
  12.643 -                                }
  12.644 -
  12.645 -                                // If we have a valid fingerprint, show Trustwords
  12.646 -                                if (string.IsNullOrEmpty(partnerFpr) == false)
  12.647 -                                {
  12.648 -                                    // Set the partner's fingerprint
  12.649 -                                    this.Partner.Fingerprint = partnerFpr;
  12.650 -
  12.651 -                                    // Marshall to main thread
  12.652 -                                    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() =>
  12.653 -                                    {
  12.654 -                                        // Create the handshake item 
  12.655 -                                        if (this.CreateHandshakeItem())
  12.656 -                                        {
  12.657 -                                            this.GoToNextStep();
  12.658 -                                        }
  12.659 -                                        else
  12.660 -                                        {
  12.661 -                                            Log.Error("KeySyncWizard_SyncMessageReceived: Error creating handshake item.");
  12.662 -                                            this.GoToLastStep(false);
  12.663 -                                        }
  12.664 -                                    }));
  12.665 -                                }
  12.666 -                                else
  12.667 -                                {
  12.668 -                                    Log.Error("KeySyncWizard_SyncMessageReceived: Partner fingerprint is null.");
  12.669 -                                }
  12.670 -                            }
  12.671 -                            break;
  12.672 -                        case WizardState.Step2:
  12.673 -                            {
  12.674 -                                Log.Verbose("KeySyncWizard_SyncMessageReceived: Nothing done. WizardState is Step 2.");
  12.675 -                            }
  12.676 -                            break;
  12.677 -                        case WizardState.Step3:
  12.678 -                            {
  12.679 -                                /* Finish the process if a private key has been imported and the message
  12.680 -                                 * is at least trusted.
  12.681 -                                 * For pEp key import, check also that we don't import our own key.
  12.682 -                                 */ 
  12.683 -                                if ((e.Flags.HasFlag(pEpDecryptFlags.pEpDecryptFlagOwnPrivateKey)) &&
  12.684 -                                    (e.Message.Rating >= pEpRating.pEpRatingTrusted) &&
  12.685 -                                    ((e.Message.KeyImport?.Equals(this.Partner?.Fingerprint) == true) ||
  12.686 -                                     (this.Type == WizardType.PGP)))
  12.687 -                                {
  12.688 -                                    this.CompleteWizard();
  12.689 -                                }
  12.690 -                                else
  12.691 -                                {
  12.692 -                                    Log.Verbose("KeySyncWizard_SyncMessageReceived: Message not processed. WizardState: Step 3. Own private key flag is " +
  12.693 -                                                e.Flags.HasFlag(pEpDecryptFlags.pEpDecryptFlagOwnPrivateKey).ToString() + ". Rating is " +
  12.694 -                                                Enum.GetName(typeof(pEpRating), e.Message?.Rating ?? pEpRating.pEpRatingUndefined) + ". KeyImport is " +
  12.695 -                                                e.Message?.KeyImport ?? "null");
  12.696 -                                }
  12.697 -                            }
  12.698 -                            break;
  12.699 -                        case WizardState.Step4:
  12.700 -                        case WizardState.Undefined:
  12.701 -                        default:
  12.702 -                            break;
  12.703 -                    }
  12.704 +                    // Send answer message with pub key
  12.705 +                    this.SendSyncMessage(MessageTypes.PublicKeyMessage);
  12.706                  }
  12.707 -                catch (Exception ex)
  12.708 +                else
  12.709                  {
  12.710 -                    Log.Error("KeySyncWizard_SyncMessageReceived: Error processing sync message. " + ex.ToString());
  12.711 +                    Log.Error("KeySyncWizard: Error creating handshake item.");
  12.712                  }
  12.713              }
  12.714 +            catch (Exception ex)
  12.715 +            {
  12.716 +                Log.Error("KeySyncWizard: Error updating Myself. " + ex.ToString());
  12.717 +            }
  12.718 +
  12.719 +            return success;
  12.720          }
  12.721  
  12.722          /// <summary>
  12.723 @@ -490,7 +534,7 @@
  12.724          private void Window_Closed(object sender, EventArgs e)
  12.725          {
  12.726              // Remove event handler
  12.727 -            CryptableMailItem.SyncMessageReceived += KeySyncWizard_SyncMessageReceived;
  12.728 +            MsgProcessor.SyncMessageReceived += KeySyncWizard_SyncMessageReceived;
  12.729  
  12.730              // Reset static references
  12.731              KeySyncWizard.Wizard = new KeySyncWizard();
  12.732 @@ -506,18 +550,69 @@
  12.733           *************************************************************/
  12.734  
  12.735          /// <summary>
  12.736 +        /// Adds the given PEPMessage to the list of received sync messages.
  12.737 +        /// </summary>
  12.738 +        /// <param name="message">The PEPMessage to add to the list.</param>
  12.739 +        public void AddToReceivedSyncMessages(PEPMessage message)
  12.740 +        {
  12.741 +            /* Add message to list if:
  12.742 +             *  1.  a. WizardType is PGP and message is secure
  12.743 +             *      b. WizardType is pEp, the current step is Step 2 and the
  12.744 +             *         message hasn't been sent from myself
  12.745 +             *  2. Message is not in the list yet
  12.746 +             */
  12.747 +            lock (mutexReceivedSyncMessages)
  12.748 +            {
  12.749 +                if (((this.Type == WizardType.PGP) &&
  12.750 +                     (message.IsSecure) ||
  12.751 +                     ((this.Type == WizardType.pEp) &&
  12.752 +                      (this.Step == Steps.Step2) &&
  12.753 +                      (this.Myself?.Fingerprint?.Equals(message?.KeyImport) == false))) &&
  12.754 +                    (this.receivedSyncMessages?.Find(a => (a.Id?.Equals(message.Id) == true)) == null))
  12.755 +                {
  12.756 +                    this.receivedSyncMessages?.Add(message);
  12.757 +                }
  12.758 +            }
  12.759 +        }
  12.760 +
  12.761 +        /// <summary>
  12.762 +        /// Closes the wizard and resets the partner identity in the management.db.
  12.763 +        /// </summary>
  12.764 +        private void CancelWizard()
  12.765 +        {
  12.766 +            try
  12.767 +            {
  12.768 +                pEpIdentity partner = this.Partner.Copy().ToCOMType();
  12.769 +
  12.770 +                if (string.IsNullOrEmpty(partner.fpr) == false)
  12.771 +                {
  12.772 +                    Task.Factory.StartNew(new Action(() =>
  12.773 +                    {
  12.774 +                        ThisAddIn.PEPEngine.KeyResetTrust(partner);
  12.775 +                    }), TaskCreationOptions.LongRunning);
  12.776 +                }
  12.777 +            }
  12.778 +            catch (Exception ex)
  12.779 +            {
  12.780 +                Log.Error("CancelWizard: Error resetting identity. " + ex.ToString());
  12.781 +            }
  12.782 +
  12.783 +            this.Close();
  12.784 +        }
  12.785 +
  12.786 +        /// <summary>
  12.787          /// Completes the process and moves wizard to last step.
  12.788          /// Sets the imported private key as own key, if needed.
  12.789          /// </summary>
  12.790          private void CompleteWizard()
  12.791          {
  12.792              // Marshall to main thread
  12.793 -            this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() =>
  12.794 +            this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
  12.795              {
  12.796                  bool success = false;
  12.797  
  12.798                  // Private key message received. Set key as default if needed.
  12.799 -                if (this.isInitiator)
  12.800 +                if (this.IsInitiator)
  12.801                  {
  12.802                      try
  12.803                      {
  12.804 @@ -553,9 +648,10 @@
  12.805              HandshakeItem item;
  12.806              if (HandshakeItem.Create(this.Myself, this.Partner, false, out item) == Globals.ReturnStatus.Success)
  12.807              {
  12.808 -                item.AreTabControlsVisible = (this.Type == WizardType.PGP);
  12.809 +                item.AreTabControlsVisible = false;
  12.810                  item.ActiveTab = (this.Type == WizardType.pEp) ? HandshakeItem.Tabs.Trustwords : HandshakeItem.Tabs.Fingerprint;
  12.811                  item.AreHandshakeButtonsVisible = false;
  12.812 +                item.Mode = HandshakeItem.HandshakeMode.Sync;
  12.813                  this.Items.Add(item);
  12.814  
  12.815                  success = true;
  12.816 @@ -566,17 +662,658 @@
  12.817          }
  12.818  
  12.819          /// <summary>
  12.820 +        /// Creates a list of wizard states that serve as model for the wizard.
  12.821 +        /// The pEp Key Import process consists of the following steps:
  12.822 +        ///     Step 1:
  12.823 +        ///         a. Is initiator(user opened wizard): Info message that sync message has been sent.
  12.824 +        ///            Waiting for answer message from other device.
  12.825 +        ///         b. Is not initiator (wizard opened through sync message): Info message that key import has been started.
  12.826 +        ///            Waiting for user decision to continue or abort.
  12.827 +        ///     Step 2:
  12.828 +        ///         - Show trustwords. User interaction: confirm or cancel.
  12.829 +        ///     Step 3: 
  12.830 +        ///         - Private keys have been sent. Waiting for answer message from other device.
  12.831 +        ///     Step 4: 
  12.832 +        ///         - Only on initiator side: Ask user if they want to set imported key as default. Next or Cancel.
  12.833 +        ///     Success:
  12.834 +        ///         - Key Import successfully finished.
  12.835 +        ///     Error:
  12.836 +        ///         - An error occured during the Key Import process.
  12.837 +        /// </summary>
  12.838 +        /// <returns>The list of wizard states.</returns>
  12.839 +        private List<WizardState> CreatePEPWizardStates()
  12.840 +        {
  12.841 +            List<WizardState> states = new List<WizardState>();
  12.842 +
  12.843 +            try
  12.844 +            {
  12.845 +                // Step 1
  12.846 +                states.Add(new WizardState
  12.847 +                {
  12.848 +                    // Step
  12.849 +                    Step = Steps.Step1,
  12.850 +
  12.851 +                    // Title text
  12.852 +                    TitleText = this.IsInitiator ? Properties.Resources.KeySyncWizard_PEPStep1ExplanationText : Properties.Resources.KeySyncWizard_PEPStep1NonInitiatorExplanationText,
  12.853 +
  12.854 +                    // Central area
  12.855 +                    AreTrustwordsVisible = false,
  12.856 +                    IsUserTextVisible = true,
  12.857 +                    UserText = this.UserName,
  12.858 +
  12.859 +                    // Back button
  12.860 +                    IsBackButtonVisible = false,
  12.861 +
  12.862 +                    // Accept button
  12.863 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Start,
  12.864 +                    IsAcceptButtonVisible = (this.IsInitiator == false),
  12.865 +                    AcceptButtonClick = new Action(() =>
  12.866 +                    {
  12.867 +                        if (this.ShowHandshake())
  12.868 +                        {
  12.869 +                            this.GoToNextStep();
  12.870 +                        }
  12.871 +                        else
  12.872 +                        {
  12.873 +                            this.GoToLastStep(false);
  12.874 +                        }
  12.875 +                    }),
  12.876 +
  12.877 +                    // Cancel button
  12.878 +                    CancelButtonText = Properties.Resources.Options_CancelText,
  12.879 +                    IsCancelButtonVisible = true,
  12.880 +                    CancelButtonClick = new Action(() =>
  12.881 +                    {
  12.882 +                        this.CancelWizard();
  12.883 +                    }),
  12.884 +
  12.885 +                    // Subtitle area
  12.886 +                    SubtitleText = this.IsInitiator ? Properties.Resources.KeySyncWizard_WaitingForResponseText : null
  12.887 +                });
  12.888 +
  12.889 +                // Step 2
  12.890 +                states.Add(new WizardState
  12.891 +                {
  12.892 +                    // Step
  12.893 +                    Step = Steps.Step2,
  12.894 +
  12.895 +                    // Title text
  12.896 +                    TitleText = Properties.Resources.KeySyncWizard_PEPStep2ExplanationText,
  12.897 +
  12.898 +                    // Central area
  12.899 +                    AreTrustwordsVisible = true,
  12.900 +                    IsUserTextVisible = false,
  12.901 +
  12.902 +                    // Back button
  12.903 +                    IsBackButtonVisible = false,
  12.904 +
  12.905 +                    // Accept button
  12.906 +                    AcceptButtonText = Properties.Resources.Handshake_ConfirmTrustwords,
  12.907 +                    IsAcceptButtonVisible = true,
  12.908 +                    AcceptButtonClick = new Action(() =>
  12.909 +                    {
  12.910 +                        this.GoToNextStep();
  12.911 +                        this.TrustKey();
  12.912 +                    }),
  12.913 +
  12.914 +                    // Cancel button
  12.915 +                    CancelButtonText = Properties.Resources.Handshake_WrongTrustwords,
  12.916 +                    IsCancelButtonVisible = true,
  12.917 +                    CancelButtonClick = new Action(() =>
  12.918 +                    {
  12.919 +                        this.CancelWizard();
  12.920 +                    }),
  12.921 +
  12.922 +                    // Subtitle area
  12.923 +                    SubtitleText = null
  12.924 +                });
  12.925 +
  12.926 +                // Step 3
  12.927 +                states.Add(new WizardState
  12.928 +                {
  12.929 +                    // Step
  12.930 +                    Step = Steps.Step3,
  12.931 +
  12.932 +                    // Title text
  12.933 +                    TitleText = Properties.Resources.KeySyncWizard_PEPStep3ExplanationText,
  12.934 +
  12.935 +                    // Central area
  12.936 +                    AreTrustwordsVisible = false,
  12.937 +                    IsUserTextVisible = true,
  12.938 +                    UserText = this.UserName,
  12.939 +
  12.940 +                    // Back button
  12.941 +                    IsBackButtonVisible = false,
  12.942 +
  12.943 +                    // Accept button
  12.944 +                    IsAcceptButtonVisible = false,
  12.945 +
  12.946 +                    // Cancel button
  12.947 +                    CancelButtonText = Properties.Resources.Options_CancelText,
  12.948 +                    IsCancelButtonVisible = true,
  12.949 +                    CancelButtonClick = new Action(() =>
  12.950 +                    {
  12.951 +                        this.CancelWizard();
  12.952 +                    }),
  12.953 +
  12.954 +                    // Subtitle area
  12.955 +                    SubtitleText = Properties.Resources.KeySyncWizard_WaitingForResponseText
  12.956 +                });
  12.957 +
  12.958 +                // Success
  12.959 +                states.Add(new WizardState
  12.960 +                {
  12.961 +                    // Step
  12.962 +                    Step = Steps.Success,
  12.963 +
  12.964 +                    // Title text
  12.965 +                    TitleText = null,
  12.966 +
  12.967 +                    // Central area
  12.968 +                    AreTrustwordsVisible = false,
  12.969 +                    IsUserTextVisible = true,
  12.970 +                    UserText = this.UserName,
  12.971 +
  12.972 +                    // Back button
  12.973 +                    IsBackButtonVisible = false,
  12.974 +
  12.975 +                    // Accept button
  12.976 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Finish,
  12.977 +                    IsAcceptButtonVisible = true,
  12.978 +                    AcceptButtonClick = new Action(() =>
  12.979 +                    {
  12.980 +                        this.Close();
  12.981 +                    }),
  12.982 +
  12.983 +                    // Cancel button
  12.984 +                    IsCancelButtonVisible = false,
  12.985 +
  12.986 +                    // Subtitle area
  12.987 +                    SubtitleText = null
  12.988 +                });
  12.989 +
  12.990 +                // Error
  12.991 +                states.Add(new WizardState
  12.992 +                {
  12.993 +                    // Step
  12.994 +                    Step = Steps.Error,
  12.995 +
  12.996 +                    // Title text
  12.997 +                    TitleText = Properties.Resources.KeySyncWizard_ErrorExplanationText,
  12.998 +
  12.999 +                    // Central area
 12.1000 +                    AreTrustwordsVisible = false,
 12.1001 +                    IsUserTextVisible = true,
 12.1002 +                    UserText = this.UserName,
 12.1003 +
 12.1004 +                    // Back button
 12.1005 +                    IsBackButtonVisible = false,
 12.1006 +
 12.1007 +                    // Accept button
 12.1008 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Finish,
 12.1009 +                    IsAcceptButtonVisible = true,
 12.1010 +                    AcceptButtonClick = new Action(() =>
 12.1011 +                    {
 12.1012 +                        this.CancelWizard();
 12.1013 +                    }),
 12.1014 +
 12.1015 +                    // Cancel button
 12.1016 +                    IsCancelButtonVisible = false,
 12.1017 +
 12.1018 +                    // Subtitle area
 12.1019 +                    SubtitleText = null
 12.1020 +                });
 12.1021 +            }
 12.1022 +            catch (Exception ex)
 12.1023 +            {
 12.1024 +                states = null;
 12.1025 +                Log.Error("CreateWizardStates: Error creating wizard states. " + ex.ToString());
 12.1026 +            }
 12.1027 +
 12.1028 +            return states;
 12.1029 +        }
 12.1030 +
 12.1031 +        /// <summary>
 12.1032 +        /// Creates a list of wizard states that serve as model for the wizard.
 12.1033 +        /// The PGP Key Import process consists of the following steps:
 12.1034 +        ///     Steps 1-3:
 12.1035 +        ///         - Instructions on how to prepare the answer message with pub key.
 12.1036 +        ///     Step 4: 
 12.1037 +        ///         - Waiting for answer message from other device.
 12.1038 +        ///     Step 5: 
 12.1039 +        ///         - Show fingerprints. Confirm or deny them.        
 12.1040 +        ///     Step 6 - 7: 
 12.1041 +        ///         - Instructions on how to prepare the answer message with private key.
 12.1042 +        ///     Success:
 12.1043 +        ///         - Key Import successfully finished.
 12.1044 +        ///     Error:
 12.1045 +        ///         - An error occured during the Key Import process.
 12.1046 +        /// </summary>
 12.1047 +        /// <returns>The list of wizard states.</returns>
 12.1048 +        private List<WizardState> CreatePGPWizardStates()
 12.1049 +        {
 12.1050 +            List<WizardState> states = new List<WizardState>();
 12.1051 +
 12.1052 +            try
 12.1053 +            {
 12.1054 +                // Step 1
 12.1055 +                states.Add(new WizardState
 12.1056 +                {
 12.1057 +                    // Step
 12.1058 +                    Step = Steps.Step1,
 12.1059 +
 12.1060 +                    // Title text
 12.1061 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep1ExplanationText,
 12.1062 +
 12.1063 +                    // Central area
 12.1064 +                    AreTrustwordsVisible = false,
 12.1065 +                    IsUserTextVisible = true,
 12.1066 +                    UserText = this.UserName,
 12.1067 +
 12.1068 +                    // Back button
 12.1069 +                    IsBackButtonVisible = false,
 12.1070 +
 12.1071 +                    // Accept button
 12.1072 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Next,
 12.1073 +                    IsAcceptButtonVisible = true,
 12.1074 +                    AcceptButtonClick = new Action(() =>
 12.1075 +                    {
 12.1076 +                        this.GoToNextStep();
 12.1077 +                    }),
 12.1078 +
 12.1079 +                    // Cancel button
 12.1080 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 12.1081 +                    IsCancelButtonVisible = true,
 12.1082 +                    CancelButtonClick = new Action(() =>
 12.1083 +                    {
 12.1084 +                        this.CancelWizard();
 12.1085 +                    }),
 12.1086 +
 12.1087 +                    // Subtitle area
 12.1088 +                    SubtitleText = null
 12.1089 +                });
 12.1090 +
 12.1091 +                // Step 2
 12.1092 +                states.Add(new WizardState
 12.1093 +                {
 12.1094 +                    // Step
 12.1095 +                    Step = Steps.Step2,
 12.1096 +
 12.1097 +                    // Title text
 12.1098 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep2ExplanationText,
 12.1099 +
 12.1100 +                    // Central area
 12.1101 +                    AreTrustwordsVisible = false,
 12.1102 +                    IsUserTextVisible = true,
 12.1103 +                    UserText = this.UserName,
 12.1104 +
 12.1105 +                    // Back button
 12.1106 +                    IsBackButtonVisible = true,
 12.1107 +                    BackButtonClick = new Action(() =>
 12.1108 +                    {
 12.1109 +                        this.GoToPreviousStep();
 12.1110 +                    }),
 12.1111 +
 12.1112 +                    // Accept button
 12.1113 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Next,
 12.1114 +                    IsAcceptButtonVisible = true,
 12.1115 +                    AcceptButtonClick = new Action(() =>
 12.1116 +                    {
 12.1117 +                        this.GoToNextStep();
 12.1118 +                    }),
 12.1119 +
 12.1120 +                    // Cancel button
 12.1121 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 12.1122 +                    IsCancelButtonVisible = true,
 12.1123 +                    CancelButtonClick = new Action(() =>
 12.1124 +                    {
 12.1125 +                        this.CancelWizard();
 12.1126 +                    }),
 12.1127 +
 12.1128 +                    // Subtitle area
 12.1129 +                    SubtitleText = null
 12.1130 +                });
 12.1131 +
 12.1132 +                // Step 3
 12.1133 +                states.Add(new WizardState
 12.1134 +                {
 12.1135 +                    // Step
 12.1136 +                    Step = Steps.Step3,
 12.1137 +
 12.1138 +                    // Title text
 12.1139 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep3ExplanationText,
 12.1140 +
 12.1141 +                    // Central area
 12.1142 +                    AreTrustwordsVisible = false,
 12.1143 +                    IsUserTextVisible = true,
 12.1144 +                    UserText = this.UserName,
 12.1145 +
 12.1146 +                    // Back button
 12.1147 +                    IsBackButtonVisible = true,
 12.1148 +                    BackButtonClick = new Action(() =>
 12.1149 +                    {
 12.1150 +                        this.GoToPreviousStep();
 12.1151 +                    }),
 12.1152 +
 12.1153 +                    // Accept button
 12.1154 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Next,
 12.1155 +                    IsAcceptButtonVisible = true,
 12.1156 +                    AcceptButtonClick = new Action(() =>
 12.1157 +                    {
 12.1158 +                        this.GoToNextStep();
 12.1159 +                        this.ProcessReceivedSyncMessages();
 12.1160 +                    }),
 12.1161 +
 12.1162 +                    // Cancel button
 12.1163 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 12.1164 +                    IsCancelButtonVisible = true,
 12.1165 +                    CancelButtonClick = new Action(() =>
 12.1166 +                    {
 12.1167 +                        this.CancelWizard();
 12.1168 +                    }),
 12.1169 +
 12.1170 +                    // Subtitle area
 12.1171 +                    SubtitleText = null
 12.1172 +                });
 12.1173 +
 12.1174 +                // Step 4
 12.1175 +                states.Add(new WizardState
 12.1176 +                {
 12.1177 +                    // Step
 12.1178 +                    Step = Steps.Step4,
 12.1179 +
 12.1180 +                    // Title text
 12.1181 +                    TitleText = Properties.Resources.KeySyncWizard_WaitingForResponseText,
 12.1182 +
 12.1183 +                    // Central area
 12.1184 +                    AreTrustwordsVisible = false,
 12.1185 +                    IsUserTextVisible = true,
 12.1186 +                    UserText = this.UserName,
 12.1187 +
 12.1188 +                    // Back button
 12.1189 +                    // Back button
 12.1190 +                    IsBackButtonVisible = true,
 12.1191 +                    BackButtonClick = new Action(() =>
 12.1192 +                    {
 12.1193 +                        this.GoToPreviousStep();
 12.1194 +                    }),
 12.1195 +
 12.1196 +                    // Accept button
 12.1197 +                    IsAcceptButtonVisible = false,
 12.1198 +
 12.1199 +                    // Cancel button
 12.1200 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 12.1201 +                    IsCancelButtonVisible = true,
 12.1202 +                    CancelButtonClick = new Action(() =>
 12.1203 +                    {
 12.1204 +                        this.CancelWizard();
 12.1205 +                    }),
 12.1206 +
 12.1207 +                    // Subtitle area
 12.1208 +                    SubtitleText = null
 12.1209 +                });
 12.1210 +
 12.1211 +                // Step 5
 12.1212 +                states.Add(new WizardState
 12.1213 +                {
 12.1214 +                    // Step
 12.1215 +                    Step = Steps.Step5,
 12.1216 +
 12.1217 +                    // Title text
 12.1218 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep5ExplanationText,
 12.1219 +
 12.1220 +                    // Central area
 12.1221 +                    AreTrustwordsVisible = true,
 12.1222 +                    IsUserTextVisible = false,
 12.1223 +
 12.1224 +                    // Back button
 12.1225 +                    IsBackButtonVisible = false,
 12.1226 +
 12.1227 +                    // Accept button
 12.1228 +                    AcceptButtonText = Properties.Resources.Handshake_ConfirmFingerprint,
 12.1229 +                    IsAcceptButtonVisible = true,
 12.1230 +                    AcceptButtonClick = new Action(() =>
 12.1231 +                    {
 12.1232 +                        this.GoToNextStep();
 12.1233 +                        this.TrustKey();
 12.1234 +                    }),
 12.1235 +
 12.1236 +                    // Cancel button
 12.1237 +                    CancelButtonText = Properties.Resources.Handshake_WrongFingerprint,
 12.1238 +                    IsCancelButtonVisible = true,
 12.1239 +                    CancelButtonClick = new Action(() =>
 12.1240 +                    {
 12.1241 +                        this.CancelWizard();
 12.1242 +                    }),
 12.1243 +
 12.1244 +                    // Subtitle area
 12.1245 +                    SubtitleText = null
 12.1246 +                });
 12.1247 +
 12.1248 +                // Step 6
 12.1249 +                states.Add(new WizardState
 12.1250 +                {
 12.1251 +                    // Step
 12.1252 +                    Step = Steps.Step6,
 12.1253 +
 12.1254 +                    // Title text
 12.1255 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep6ExplanationText,
 12.1256 +
 12.1257 +                    // Central area
 12.1258 +                    AreTrustwordsVisible = false,
 12.1259 +                    IsUserTextVisible = true,
 12.1260 +                    UserText = this.UserName,
 12.1261 +
 12.1262 +                    // Back button
 12.1263 +                    IsBackButtonVisible = false,
 12.1264 +
 12.1265 +                    // Accept button
 12.1266 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Next,
 12.1267 +                    IsAcceptButtonVisible = true,
 12.1268 +                    AcceptButtonClick = new Action(() =>
 12.1269 +                    {
 12.1270 +                        this.GoToNextStep();
 12.1271 +                    }),
 12.1272 +
 12.1273 +                    // Cancel button
 12.1274 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 12.1275 +                    IsCancelButtonVisible = true,
 12.1276 +                    CancelButtonClick = new Action(() =>
 12.1277 +                    {
 12.1278 +                        this.CancelWizard();
 12.1279 +                    }),
 12.1280 +
 12.1281 +                    // Subtitle area
 12.1282 +                    SubtitleText = null
 12.1283 +                });
 12.1284 +
 12.1285 +                // Step 7
 12.1286 +                states.Add(new WizardState
 12.1287 +                {
 12.1288 +                    // Step
 12.1289 +                    Step = Steps.Step7,
 12.1290 +
 12.1291 +                    // Title text
 12.1292 +                    TitleText = Properties.Resources.KeySyncWizard_PGPStep7ExplanationText,
 12.1293 +
 12.1294 +                    // Central area
 12.1295 +                    AreTrustwordsVisible = false,
 12.1296 +                    IsUserTextVisible = true,
 12.1297 +                    UserText = this.UserName,
 12.1298 +
 12.1299 +                    // Back button
 12.1300 +                    IsBackButtonVisible = true,
 12.1301 +                    BackButtonClick = new Action(() =>
 12.1302 +                    {
 12.1303 +                        this.GoToPreviousStep();
 12.1304 +                    }),
 12.1305 +
 12.1306 +                    // Accept button
 12.1307 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Next,
 12.1308 +                    IsAcceptButtonVisible = true,
 12.1309 +                    AcceptButtonClick = new Action(() =>
 12.1310 +                    {
 12.1311 +                        this.GoToNextStep();
 12.1312 +                        this.ProcessReceivedSyncMessages();
 12.1313 +                    }),
 12.1314 +
 12.1315 +                    // Cancel button
 12.1316 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 12.1317 +                    IsCancelButtonVisible = true,
 12.1318 +                    CancelButtonClick = new Action(() =>
 12.1319 +                    {
 12.1320 +                        this.CancelWizard();
 12.1321 +                    }),
 12.1322 +
 12.1323 +                    // Subtitle area
 12.1324 +                    SubtitleText = null
 12.1325 +                });
 12.1326 +
 12.1327 +                // Step 8
 12.1328 +                states.Add(new WizardState
 12.1329 +                {
 12.1330 +                    // Step
 12.1331 +                    Step = Steps.Step8,
 12.1332 +
 12.1333 +                    // Title text
 12.1334 +                    TitleText = Properties.Resources.KeySyncWizard_WaitingForResponseText,
 12.1335 +
 12.1336 +                    // Central area
 12.1337 +                    AreTrustwordsVisible = false,
 12.1338 +                    IsUserTextVisible = true,
 12.1339 +                    UserText = this.UserName,
 12.1340 +
 12.1341 +                    // Back button
 12.1342 +                    IsBackButtonVisible = true,
 12.1343 +                    BackButtonClick = new Action(() =>
 12.1344 +                    {
 12.1345 +                        this.GoToPreviousStep();
 12.1346 +                    }),
 12.1347 +
 12.1348 +                    // Accept button
 12.1349 +                    IsAcceptButtonVisible = false,
 12.1350 +
 12.1351 +                    // Cancel button
 12.1352 +                    CancelButtonText = Properties.Resources.Options_CancelText,
 12.1353 +                    IsCancelButtonVisible = true,
 12.1354 +                    CancelButtonClick = new Action(() =>
 12.1355 +                    {
 12.1356 +                        this.CancelWizard();
 12.1357 +                    }),
 12.1358 +
 12.1359 +                    // Subtitle area
 12.1360 +                    SubtitleText = null
 12.1361 +                });
 12.1362 +
 12.1363 +                // Success
 12.1364 +                states.Add(new WizardState
 12.1365 +                {
 12.1366 +                    // Step
 12.1367 +                    Step = Steps.Success,
 12.1368 +
 12.1369 +                    // Title text
 12.1370 +                    TitleText = Properties.Resources.KeySyncWizard_PGPSuccessExplanationText,
 12.1371 +
 12.1372 +                    // Central area
 12.1373 +                    AreTrustwordsVisible = false,
 12.1374 +                    IsUserTextVisible = true,
 12.1375 +                    UserText = this.UserName,
 12.1376 +
 12.1377 +                    // Back button
 12.1378 +                    IsBackButtonVisible = false,
 12.1379 +
 12.1380 +                    // Accept button
 12.1381 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Finish,
 12.1382 +                    IsAcceptButtonVisible = true,
 12.1383 +                    AcceptButtonClick = new Action(() =>
 12.1384 +                    {
 12.1385 +                        this.Close();
 12.1386 +                    }),
 12.1387 +
 12.1388 +                    // Cancel button
 12.1389 +                    IsCancelButtonVisible = false,
 12.1390 +
 12.1391 +                    // Subtitle area
 12.1392 +                    SubtitleText = null
 12.1393 +                });
 12.1394 +
 12.1395 +                // Error
 12.1396 +                states.Add(new WizardState
 12.1397 +                {
 12.1398 +                    // Step
 12.1399 +                    Step = Steps.Error,
 12.1400 +
 12.1401 +                    // Title text
 12.1402 +                    TitleText = Properties.Resources.KeySyncWizard_ErrorExplanationText,
 12.1403 +
 12.1404 +                    // Central area
 12.1405 +                    AreTrustwordsVisible = false,
 12.1406 +                    IsUserTextVisible = true,
 12.1407 +                    UserText = this.UserName,
 12.1408 +
 12.1409 +                    // Back button
 12.1410 +                    IsBackButtonVisible = false,
 12.1411 +
 12.1412 +                    // Accept button
 12.1413 +                    AcceptButtonText = Properties.Resources.KeySyncWizard_Finish,
 12.1414 +                    IsAcceptButtonVisible = true,
 12.1415 +                    AcceptButtonClick = new Action(() =>
 12.1416 +                    {
 12.1417 +                        this.CancelWizard();
 12.1418 +                    }),
 12.1419 +
 12.1420 +                    // Cancel button
 12.1421 +                    IsCancelButtonVisible = false,
 12.1422 +
 12.1423 +                    // Subtitle area
 12.1424 +                    SubtitleText = null
 12.1425 +                });
 12.1426 +            }
 12.1427 +            catch (Exception ex)
 12.1428 +            {
 12.1429 +                states = null;
 12.1430 +                Log.Error("CreateWizardStates: Error creating wizard states. " + ex.ToString());
 12.1431 +            }
 12.1432 +
 12.1433 +            return states;
 12.1434 +        }
 12.1435 +
 12.1436 +        /// <summary>
 12.1437          /// Navigates to the last step of the wizard.
 12.1438          /// </summary>
 12.1439          /// <param name="success">Whether or not the wizard has been completed successfully.</param>
 12.1440          private void GoToLastStep(bool success)
 12.1441          {
 12.1442              // Go to last step
 12.1443 -            this.State = WizardState.Step4;
 12.1444 -            this.Success = success;
 12.1445 +            this.Step = success ? Steps.Success : Steps.Error;
 12.1446  
 12.1447 -            // Update content
 12.1448 -            this.UpdateContent();
 12.1449 +            // Update wording and state
 12.1450 +            var lastState = this.states.Find(a => a.Step == this.Step);
 12.1451 +            if (this.IsInitiator)
 12.1452 +            {
 12.1453 +                if (this.SetImportedKeyAsDefault)
 12.1454 +                {
 12.1455 +                    lastState.TitleText = Properties.Resources.KeySyncWizard_PEPSuccessImport + "\n\n" + Properties.Resources.KeySyncWizard_PEPSuccessOtherKeyUsedAsDefault;
 12.1456 +                }
 12.1457 +                else
 12.1458 +                {
 12.1459 +                    lastState.TitleText = Properties.Resources.KeySyncWizard_PEPSuccessImport + "\n\n" + Properties.Resources.KeySyncWizard_PEPSuccessOtherKeyUsed;
 12.1460 +                }
 12.1461 +            }
 12.1462 +            else
 12.1463 +            {
 12.1464 +                if (this.privateKeyImported)
 12.1465 +                {
 12.1466 +                    lastState.TitleText = Properties.Resources.KeySyncWizard_PEPSuccessExport + "\n\n" + Properties.Resources.KeySyncWizard_PEPSuccessOtherKeyUsed;
 12.1467 +                }
 12.1468 +                else
 12.1469 +                {
 12.1470 +                    lastState.TitleText = Properties.Resources.KeySyncWizard_PEPSuccessExport;
 12.1471 +                }
 12.1472 +            }
 12.1473 +
 12.1474 +            // Apply state
 12.1475 +            this.CurrentState = lastState;
 12.1476  
 12.1477              Log.Verbose("GoToLastStep: Process finished. Success is " + success.ToString());
 12.1478          }
 12.1479 @@ -587,26 +1324,42 @@
 12.1480          private void GoToNextStep()
 12.1481          {
 12.1482              // Go to next step
 12.1483 -            this.State++;
 12.1484 +            this.Step++;
 12.1485  
 12.1486 -            // Update content
 12.1487 -            this.UpdateContent();
 12.1488 +            // Set current state
 12.1489 +            this.CurrentState = states.Find(a => a.Step == this.Step);
 12.1490  
 12.1491 -            Log.Verbose("GoToNextStep: New state: " + Enum.GetName(typeof(WizardState), this.State));
 12.1492 +            Log.Verbose("GoToNextStep: New state: " + Enum.GetName(typeof(Steps), this.Step));
 12.1493 +        }
 12.1494 +
 12.1495 +        /// <summary>
 12.1496 +        /// Navigates to the previous state of the wizard.
 12.1497 +        /// </summary>
 12.1498 +        private void GoToPreviousStep()
 12.1499 +        {
 12.1500 +            // Go to next step
 12.1501 +            this.Step--;
 12.1502 +
 12.1503 +            // Set current state
 12.1504 +            this.CurrentState = states.Find(a => a.Step == this.Step);
 12.1505 +
 12.1506 +            Log.Verbose("GoToPreviousStep: New state: " + Enum.GetName(typeof(Steps), this.Step));
 12.1507          }
 12.1508  
 12.1509          /// <summary>
 12.1510          /// Initializes the wizard.
 12.1511          /// </summary>
 12.1512 -        private void InitializeWizard(WizardType type,
 12.1513 +        private void InitializeWizard(bool isInitiator,
 12.1514 +                                      WizardType type,
 12.1515                                        PEPIdentity myself,
 12.1516                                        string partnerFpr)
 12.1517          {
 12.1518              // Set initial state
 12.1519              this.DataContext = this;
 12.1520              this.Myself = myself;
 12.1521 -            this.State = WizardState.Step1;
 12.1522 +            this.Step = Steps.Step1;
 12.1523              this.Type = type;
 12.1524 +            this.IsInitiator = isInitiator;
 12.1525  
 12.1526              // If own identity is null, get default account
 12.1527              if (this.Myself == null)
 12.1528 @@ -699,8 +1452,39 @@
 12.1529                  this.Partner.Fingerprint = partnerFpr;
 12.1530              }
 12.1531  
 12.1532 -            // Update dialog content
 12.1533 -            this.UpdateContent();
 12.1534 +            // Define states
 12.1535 +            this.states = (this.Type == WizardType.pEp) ? this.CreatePEPWizardStates() : this.CreatePGPWizardStates();
 12.1536 +
 12.1537 +            // Set current state
 12.1538 +            this.CurrentState = states?.Find(a => a.Step == Steps.Step1);
 12.1539 +        }
 12.1540 +
 12.1541 +        /// <summary>
 12.1542 +        /// Runs through all received sync messages.
 12.1543 +        /// </summary>
 12.1544 +        private void ProcessReceivedSyncMessages()
 12.1545 +        {
 12.1546 +            lock (mutexReceivedSyncMessages)
 12.1547 +            {
 12.1548 +                if (this.receivedSyncMessages != null)
 12.1549 +                {
 12.1550 +                    foreach (var message in this.receivedSyncMessages)
 12.1551 +                    {
 12.1552 +                        try
 12.1553 +                        {
 12.1554 +                            Task.Factory.StartNew(new Action(() =>
 12.1555 +                            {
 12.1556 +                                MsgProcessor msgProcessor = new MsgProcessor();
 12.1557 +                                msgProcessor.Decrypt(message);
 12.1558 +                            }));
 12.1559 +                        }
 12.1560 +                        catch (Exception ex)
 12.1561 +                        {
 12.1562 +                            Log.Error("ProcessReceivedSyncMessages: Error processing sync message. " + ex.ToString());
 12.1563 +                        }
 12.1564 +                    }
 12.1565 +                }
 12.1566 +            }
 12.1567          }
 12.1568  
 12.1569          /// <summary>
 12.1570 @@ -714,93 +1498,117 @@
 12.1571              {
 12.1572                  try
 12.1573                  {
 12.1574 -                    // If we have no partner at this point, use a copy of myself
 12.1575 -                    if (this.Partner == null)
 12.1576 +                    // Start sending in background
 12.1577 +                    Task.Factory.StartNew(new Action(() =>
 12.1578                      {
 12.1579 -                        this.Partner = this.Myself.Copy();
 12.1580 -                        Log.Verbose("SendSyncMessage: Partner was null. Using copy of myself.");
 12.1581 -                    }
 12.1582 +                        // If we have no partner at this point, use a copy of myself
 12.1583 +                        if (this.Partner == null)
 12.1584 +                        {
 12.1585 +                            this.Partner = this.Myself.Copy();
 12.1586 +                            this.Partner.Fingerprint = null;
 12.1587 +                            Log.Verbose("SendSyncMessage: Partner was null. Using copy of myself.");
 12.1588 +                        }
 12.1589  
 12.1590 -                    // Create basic message
 12.1591 -                    bool processMessage = true;
 12.1592 -                    PEPMessage message = new PEPMessage
 12.1593 -                    {
 12.1594 -                        From = this.Myself,
 12.1595 -                        ShortMsg = (messageType == MessageTypes.InitialMessage && this.Type == WizardType.PGP) ? Properties.Resources.KeySyncWizard_PGPInitialMessageSubject : PEPMessage.PEP_HIDDEN_SYNC_MESSAGE_SUBJECT,
 12.1596 -                        LongMsg = (messageType == MessageTypes.InitialMessage && this.Type == WizardType.PGP) ? Properties.Resources.KeySyncWizard_PGPInitialMessageBody : PEPMessage.PEP_HIDDEN_SYNC_MESSAGE_BODY,
 12.1597 -                        AutoConsume = (this.Type == WizardType.pEp) ? "yes" : null,
 12.1598 -                        Direction = pEpMsgDirection.pEpDirOutgoing,
 12.1599 -                        ForceUnencrypted = (messageType == MessageTypes.InitialMessage ? true : false),
 12.1600 -                        KeyImport = (this.Type == WizardType.pEp ? this.Myself.Fingerprint : null)
 12.1601 -                    };
 12.1602 -                    message.To.Add(this.Partner);
 12.1603 +                        // Create basic message
 12.1604 +                        bool processMessage = true;
 12.1605 +                        PEPMessage message = new PEPMessage
 12.1606 +                        {
 12.1607 +                            From = this.Myself,
 12.1608 +                            ShortMsg = (messageType == MessageTypes.InitialMessage && this.Type == WizardType.PGP) ? Properties.Resources.KeySyncWizard_PGPInitialMessageSubject : PEPMessage.PEP_HIDDEN_SYNC_MESSAGE_SUBJECT,
 12.1609 +                            LongMsg = (messageType == MessageTypes.InitialMessage && this.Type == WizardType.PGP) ? Properties.Resources.KeySyncWizard_PGPInitialMessageBody : PEPMessage.PEP_HIDDEN_SYNC_MESSAGE_BODY,
 12.1610 +                            AutoConsume = (this.Type == WizardType.pEp) ? "yes" : null,
 12.1611 +                            Direction = pEpMsgDirection.pEpDirOutgoing,
 12.1612 +                            ForceUnencrypted = (messageType == MessageTypes.InitialMessage ? true : false),
 12.1613 +                            KeyImport = (this.Type == WizardType.pEp ? this.Myself.Fingerprint : null)
 12.1614 +                        };
 12.1615 +                        message.To.Add(this.Partner);
 12.1616  
 12.1617 -                    Log.Verbose("SendSyncMessage: Basic message successfully created.");
 12.1618 +                        Log.Verbose("SendSyncMessage: Basic message successfully created.");
 12.1619  
 12.1620 -                    // If the message is the private key transport message, add own private key
 12.1621 -                    PEPMessage msg;
 12.1622 -                    if (messageType == MessageTypes.PrivateKeyMessage)
 12.1623 -                    {
 12.1624 +                        // If message type isn't InitialMessage, encrypt it accordingly
 12.1625 +                        PEPMessage msg;
 12.1626                          MsgProcessor msgProcessor = new MsgProcessor();
 12.1627 -                        if (msgProcessor.EncryptAndAddPrivateKey(message, this.Partner.Fingerprint, out msg))
 12.1628 +                        if ((messageType == MessageTypes.PrivateKeyMessage) &&
 12.1629 +                            (this.ExportPrivateKey))
 12.1630                          {
 12.1631 -                            Log.Verbose("SendSyncMessage: Private key message successfully created.");
 12.1632 -                            message = msg;
 12.1633 -                            processMessage = false;
 12.1634 +                            // Encrypt and add private key
 12.1635 +                            if (msgProcessor.EncryptAndAddPrivateKey(message, this.Partner.Fingerprint, out msg))
 12.1636 +                            {
 12.1637 +                                Log.Verbose("SendSyncMessage: Private key message successfully created.");
 12.1638 +                                message = msg;
 12.1639 +                                processMessage = false;
 12.1640 +                            }
 12.1641 +                            else
 12.1642 +                            {
 12.1643 +                                Log.Error("SendSyncMessage: Error encrypting private key message.");
 12.1644 +                                message = null;
 12.1645 +                            }
 12.1646 +                        }
 12.1647 +                        else if (((messageType == MessageTypes.PrivateKeyMessage) &&
 12.1648 +                                  (this.ExportPrivateKey == false)) ||
 12.1649 +                                 (messageType == MessageTypes.PublicKeyMessage))
 12.1650 +                        {
 12.1651 +                            // Encrypt using partner fpr as extra key
 12.1652 +                            if (msgProcessor.Encrypt(message, new string[] { this.Partner.Fingerprint }, out msg))
 12.1653 +                            {
 12.1654 +                                Log.Verbose("SendSyncMessage: Public key message successfully created.");
 12.1655 +                                message = msg;
 12.1656 +                                processMessage = false;
 12.1657 +                            }
 12.1658 +                            else
 12.1659 +                            {
 12.1660 +                                Log.Error("SendSyncMessage: Error encrypting public key message.");
 12.1661 +                                message = null;
 12.1662 +                            }
 12.1663 +                        }
 12.1664 +
 12.1665 +                        // If we have a message, send it
 12.1666 +                        if (message != null)
 12.1667 +                        {
 12.1668 +                            Log.Verbose("SendSyncMessage: Sending message...");
 12.1669 +
 12.1670 +                            // Disable passive mode if needed
 12.1671 +                            bool reenablePassiveMode = false;
 12.1672 +                            if ((messageType == MessageTypes.InitialMessage) &&
 12.1673 +                                (Globals.ThisAddIn.Settings.IsPassiveModeEnabled))
 12.1674 +                            {
 12.1675 +                                try
 12.1676 +                                {
 12.1677 +                                    ThisAddIn.PEPEngine.PassiveMode(false);
 12.1678 +                                    reenablePassiveMode = true;
 12.1679 +                                    Log.Verbose("SendSyncMessage: Passive mode temporarily disabled.");
 12.1680 +                                }
 12.1681 +                                catch (Exception ex)
 12.1682 +                                {
 12.1683 +                                    Log.Error("SendSyncMessage: Error disabling passive mode. " + ex.ToString());
 12.1684 +                                }
 12.1685 +                            }
 12.1686 +
 12.1687 +                            // Send message
 12.1688 +                            Globals.ThisAddIn.CreateAndSendMessage(message, true, true, processMessage, true);
 12.1689 +
 12.1690 +                            // Log that message has been sent
 12.1691 +                            this.sentMessages?.Add(messageType);
 12.1692 +
 12.1693 +                            // Reenable passive mode if needed
 12.1694 +                            if (reenablePassiveMode)
 12.1695 +                            {
 12.1696 +                                try
 12.1697 +                                {
 12.1698 +                                    ThisAddIn.PEPEngine.PassiveMode(Globals.ThisAddIn.Settings.IsPassiveModeEnabled);
 12.1699 +                                    Log.Verbose("SendSyncMessage: Passive mode reenabled.");
 12.1700 +                                }
 12.1701 +                                catch (Exception ex)
 12.1702 +                                {
 12.1703 +                                    Log.Error("SendSyncMessage: Error reenabling passive mode. " + ex.ToString());
 12.1704 +                                }
 12.1705 +                            }
 12.1706                          }
 12.1707                          else
 12.1708                          {
 12.1709 -                            Log.Error("SendSyncMessage: Error encrypting private key message.");
 12.1710 -                            message = null;
 12.1711 +                            Log.Error("SendSyncMessage: Myself identity is null.");
 12.1712                          }
 12.1713 -                    }
 12.1714 -
 12.1715 -                    // If we have a message, send it
 12.1716 -                    if (message != null)
 12.1717 -                    {
 12.1718 -                        Log.Verbose("SendSyncMessage: Sending message...");
 12.1719 -
 12.1720 -                        // Disable passive mode if needed
 12.1721 -                        bool reenablePassiveMode = false;
 12.1722 -                        if ((messageType == MessageTypes.InitialMessage) &&
 12.1723 -                            (Globals.ThisAddIn.Settings.IsPassiveModeEnabled))
 12.1724 -                        {
 12.1725 -                            try
 12.1726 -                            {
 12.1727 -                                ThisAddIn.PEPEngine.PassiveMode(false);
 12.1728 -                                reenablePassiveMode = true;
 12.1729 -                                Log.Verbose("SendSyncMessage: Passive mode temporarily disabled.");
 12.1730 -                            }
 12.1731 -                            catch (Exception ex)
 12.1732 -                            {
 12.1733 -                                Log.Error("SendSyncMessage: Error disabling passive mode. " + ex.ToString());
 12.1734 -                            }
 12.1735 -                        }
 12.1736 -
 12.1737 -                        // Send message
 12.1738 -                        Globals.ThisAddIn.CreateAndSendMessage(message, true, true, processMessage);
 12.1739 -
 12.1740 -                        // Log that message has been sent
 12.1741 -                        this.sentMessages?.Add(messageType);
 12.1742 -
 12.1743 -                        // Reenable passive mode if needed
 12.1744 -                        if (reenablePassiveMode)
 12.1745 -                        {
 12.1746 -                            try
 12.1747 -                            {
 12.1748 -                                ThisAddIn.PEPEngine.PassiveMode(Globals.ThisAddIn.Settings.IsPassiveModeEnabled);
 12.1749 -                                Log.Verbose("SendSyncMessage: Passive mode reenabled.");
 12.1750 -                            }
 12.1751 -                            catch (Exception ex)
 12.1752 -                            {
 12.1753 -                                Log.Error("SendSyncMessage: Error reenabling passive mode. " + ex.ToString());
 12.1754 -                            }
 12.1755 -                        }
 12.1756 -                    }
 12.1757 -                    else
 12.1758 -                    {
 12.1759 -                        Log.Error("SendSyncMessage: Myself identity is null.");
 12.1760 -                    }
 12.1761 +                    }), TaskCreationOptions.LongRunning);
 12.1762                  }
 12.1763                  catch (Exception ex)
 12.1764                  {
 12.1765 @@ -810,7 +1618,7 @@
 12.1766          }
 12.1767  
 12.1768          /// <summary>
 12.1769 -        /// Trusts the communication partner key (makes the channel green)
 12.1770 +        /// Trusts the communication partner key (makes the channel green).
 12.1771          /// </summary>
 12.1772          private void TrustKey()
 12.1773          {
 12.1774 @@ -818,31 +1626,28 @@
 12.1775              {
 12.1776                  try
 12.1777                  {
 12.1778 -                    Log.Verbose("TrustKey: Trusting partner key...");
 12.1779 +                    // Run in background
 12.1780 +                    Task.Factory.StartNew(new Action(() =>
 12.1781 +                    {
 12.1782 +                        Log.Verbose("TrustKey: Trusting partner key...");
 12.1783  
 12.1784 -                    this._Partner = this.Items[0].Partner;
 12.1785 -                    pEpIdentity partner = this._Partner.ToCOMType();
 12.1786 -                    ThisAddIn.PEPEngine.TrustPersonalKey(partner);
 12.1787 +                        // Trust the partner's key
 12.1788 +                        this._Partner = this.Items[0].Partner;
 12.1789 +                        pEpIdentity partner = this._Partner.ToCOMType();
 12.1790 +                        ThisAddIn.PEPEngine.TrustPersonalKey(partner);
 12.1791  
 12.1792 -                    // If Trustwords are being accepted after having received
 12.1793 -                    // the private key, finish process.
 12.1794 -                    if (this.State == WizardState.Step3)
 12.1795 +                        // Process messages that might have been received
 12.1796 +                        this.ProcessReceivedSyncMessages();
 12.1797 +
 12.1798 +                    }), TaskCreationOptions.LongRunning).ContinueWith(new Action<Task>((result) =>
 12.1799                      {
 12.1800 -                        Log.Verbose("TrustKey: Private key already received. Completing wizard.");
 12.1801 -                        this.CompleteWizard();
 12.1802 -                    }
 12.1803 -                    else
 12.1804 -                    {
 12.1805 -                        Log.Verbose("TrustKey: No private key received yet. Going to next step.");
 12.1806 -                        this.GoToNextStep();
 12.1807 -                    }
 12.1808 -
 12.1809 -                    // In pEp sync mode, send private key to partner
 12.1810 -                    if (this.Type == WizardType.pEp)
 12.1811 -                    {
 12.1812 -                        Log.Verbose("TrustKey: Sending private key to partner.");
 12.1813 -                        this.SendSyncMessage(MessageTypes.PrivateKeyMessage);
 12.1814 -                    }
 12.1815 +                        // In pEp sync mode, send private key message to partner
 12.1816 +                        if (this.Type == WizardType.pEp)
 12.1817 +                        {
 12.1818 +                            Log.Verbose("TrustKey: Sending private key to partner.");
 12.1819 +                            this.SendSyncMessage(MessageTypes.PrivateKeyMessage);
 12.1820 +                        }
 12.1821 +                    }));
 12.1822                  }
 12.1823                  catch (Exception ex)
 12.1824                  {
 12.1825 @@ -858,108 +1663,42 @@
 12.1826          }
 12.1827  
 12.1828          /// <summary>
 12.1829 -        /// Updates the dialog content according to its current state.
 12.1830 -        /// </summary>
 12.1831 -        private void UpdateContent()
 12.1832 -        {
 12.1833 -            // Set title
 12.1834 -            if (string.IsNullOrEmpty(this._TitleText))
 12.1835 -            {
 12.1836 -                this.TitleText = this.TitleText = this.Myself?.Address;
 12.1837 -            }
 12.1838 -
 12.1839 -            // Set content according to state
 12.1840 -            switch (this.State)
 12.1841 -            {
 12.1842 -                case WizardState.Step1:
 12.1843 -                    {
 12.1844 -                        this.NextButtonText = Properties.Resources.KeySyncWizard_Next;
 12.1845 -                        this.ExplanationText = (this.Type == WizardType.pEp) ? Properties.Resources.KeySyncWizard_Step1PEPExplanationText : Properties.Resources.KeySyncWizard_Step1PGPExplanationText;
 12.1846 -                        this.SubtitleText = (this.Type == WizardType.pEp) ? Properties.Resources.KeySyncWizard_WaitingForResponseText : Properties.Resources.KeySyncWizard_Step1PGPSubtitleText;
 12.1847 -                    }
 12.1848 -                    break;
 12.1849 -                case WizardState.Step2:
 12.1850 -                    {
 12.1851 -                        this.NextButtonText = (this.Type == WizardType.pEp) ? Properties.Resources.Handshake_ConfirmTrustwords : Properties.Resources.Handshake_ConfirmFingerprint;
 12.1852 -                        this.ExplanationText = (this.Type == WizardType.pEp) ? Properties.Resources.KeySyncWizard_Step2PEPExplanationText : Properties.Resources.KeySyncWizard_Step2PGPExplanationText;
 12.1853 -                        this.SubtitleText = (this.Type == WizardType.pEp) ? Properties.Resources.Handshake_ConfirmTrustwords : Properties.Resources.Handshake_ConfirmFingerprint;
 12.1854 -                    }
 12.1855 -                    break;
 12.1856 -                case WizardState.Step3:
 12.1857 -                    {
 12.1858 -                        this.NextButtonText = Properties.Resources.KeySyncWizard_Next;
 12.1859 -                        this.ExplanationText = (this.Type == WizardType.pEp) ? Properties.Resources.KeySyncWizard_Step3PEPExplanationText : Properties.Resources.KeySyncWizard_Step3PGPExplanationText;
 12.1860 -                        this.SubtitleText = Properties.Resources.KeySyncWizard_WaitingForResponseText;
 12.1861 -                    }
 12.1862 -                    break;
 12.1863 -                case WizardState.Step4:
 12.1864 -                    {
 12.1865 -                        this.NextButtonText = Properties.Resources.KeySyncWizard_Finish;
 12.1866 -
 12.1867 -                        if (this.Success)
 12.1868 -                        {
 12.1869 -                            this.SubtitleText = Properties.Resources.KeySyncWizard_SuccessText;
 12.1870 -
 12.1871 -                            switch (this.Type)
 12.1872 -                            {
 12.1873 -                                case WizardType.PGP:
 12.1874 -                                    {
 12.1875 -                                        this.ExplanationText = Properties.Resources.KeySyncWizard_Step4SuccessExplanationText;
 12.1876 -                                    }
 12.1877 -                                    break;
 12.1878 -                                case WizardType.pEp:
 12.1879 -                                    {
 12.1880 -                                        if (this.isInitiator)
 12.1881 -                                        {
 12.1882 -                                            this.ExplanationText = Properties.Resources.KeySyncWizard_Step4PEPSuccessInitiatorExplanationText;
 12.1883 -                                        }
 12.1884 -                                        else
 12.1885 -                                        {
 12.1886 -                                            this.ExplanationText = Properties.Resources.KeySyncWizard_Step4PEPSuccessNonInitiatorExplanationText;
 12.1887 -                                        }
 12.1888 -                                    }
 12.1889 -                                    break;
 12.1890 -                                case WizardType.Undefined:
 12.1891 -                                default:
 12.1892 -                                    {
 12.1893 -                                        this.ExplanationText = string.Empty;
 12.1894 -                                    }
 12.1895 -                                    break;
 12.1896 -                            }
 12.1897 -                        }
 12.1898 -                        else
 12.1899 -                        {
 12.1900 -                            this.ExplanationText = Properties.Resources.KeySyncWizard_Step4ErrorExplanationText;
 12.1901 -                            this.SubtitleText = Properties.Resources.KeySyncWizard_ErrorText;
 12.1902 -                        }
 12.1903 -                    }
 12.1904 -                    break;
 12.1905 -                case WizardState.Undefined:
 12.1906 -                default:
 12.1907 -                    this.NextButtonText = Properties.Resources.KeySyncWizard_Finish;
 12.1908 -                    this.ExplanationText = string.Empty;
 12.1909 -                    this.SubtitleText = string.Empty;
 12.1910 -                    break;
 12.1911 -            }
 12.1912 -        }
 12.1913 -
 12.1914 -        /// <summary>
 12.1915          /// Resets the object to its defaults.
 12.1916          /// </summary>
 12.1917          public void Reset()
 12.1918          {
 12.1919 -            this._ExplanationText = null;
 12.1920 +            this._CurrentState = new WizardState();
 12.1921 +            this._ExportPrivateKey = true;
 12.1922 +            this._IsInitiator = false;
 12.1923              this._Items = new ObservableCollection<HandshakeItem>();
 12.1924              this._Myself = null;
 12.1925 -            this._NextButtonText = null;
 12.1926              this._Partner = null;
 12.1927 -            this._State = WizardState.Undefined;
 12.1928 -            this._SubtitleText = null;
 12.1929 -            this._Success = false;
 12.1930 +            this._Step = Steps.Undefined;
 12.1931 +            this._SetImportedKeyAsDefault = true;
 12.1932              this._Type = WizardType.Undefined;
 12.1933 -            this._TitleText = null;
 12.1934          }
 12.1935  
 12.1936          #endregion
 12.1937 +
 12.1938 +        /// <summary>
 12.1939 +        /// Container to define a wizard state.
 12.1940 +        /// </summary>
 12.1941 +        public class WizardState
 12.1942 +        {
 12.1943 +            public Action                   AcceptButtonClick           { get; set; }   =   null;
 12.1944 +            public string                   AcceptButtonText            { get; set; }   =   null;
 12.1945 +            public bool                     AreTrustwordsVisible        { get; set; }   =   false;
 12.1946 +            public Action                   BackButtonClick             { get; set; }   =   null;
 12.1947 +            public Action                   CancelButtonClick           { get; set; }   =   null;
 12.1948 +            public string                   CancelButtonText            { get; set; }   =   null;
 12.1949 +            public bool                     IsAcceptButtonVisible       { get; set; }   =   true;
 12.1950 +            public bool                     IsBackButtonVisible         { get; set; }   =   false;
 12.1951 +            public bool                     IsCancelButtonVisible       { get; set; }   =   true;
 12.1952 +            public bool                     IsUserTextVisible           { get; set; }   =   true;
 12.1953 +            public KeySyncWizard.Steps      Step                        { get; set; }   =   Steps.Undefined;
 12.1954 +            public string                   SubtitleText                { get; set; }   =   null;
 12.1955 +            public string                   TitleText                   { get; set; }   =   null;
 12.1956 +            public string                   UserText                    { get; set; }   =   null;
 12.1957 +        }
 12.1958      }
 12.1959  }
    13.1 --- a/UI/ValueConverters.cs	Thu May 10 12:38:22 2018 +0200
    13.2 +++ b/UI/ValueConverters.cs	Thu May 17 11:26:23 2018 +0200
    13.3 @@ -276,61 +276,6 @@
    13.4      }
    13.5  
    13.6      /// <summary>
    13.7 -    /// Returns a bool value indicating if the wizard state matches any of the given parameter.
    13.8 -    /// </summary>
    13.9 -    public class IsWizardStateConverter : IValueConverter
   13.10 -    {
   13.11 -        public object Convert(object value,
   13.12 -                              Type targetType,
   13.13 -                              object parameter,
   13.14 -                              CultureInfo culture)
   13.15 -        {
   13.16 -            bool success;
   13.17 -            KeySyncWizard.WizardState param;
   13.18 -
   13.19 -            if ((value is KeySyncWizard.WizardState) &&
   13.20 -                (parameter is string))
   13.21 -            {
   13.22 -                string[] parameters = (parameter as string).Split('|');
   13.23 -
   13.24 -                if (parameters?.Length > 0)
   13.25 -                {
   13.26 -                    foreach (var p in parameters)
   13.27 -                    {
   13.28 -                        success = Enum.TryParse(p, out param);
   13.29 -
   13.30 -                        if (success)
   13.31 -                        {
   13.32 -                            if (((KeySyncWizard.WizardState)value) == param)
   13.33 -                            {
   13.34 -                                return true;
   13.35 -                            }
   13.36 -                        }
   13.37 -                        else
   13.38 -                        {
   13.39 -                            throw new ArgumentException();
   13.40 -                        }
   13.41 -                    }
   13.42 -                }
   13.43 -
   13.44 -                return false;
   13.45 -            }
   13.46 -            else
   13.47 -            {
   13.48 -                throw new ArgumentException();
   13.49 -            }
   13.50 -        }
   13.51 -
   13.52 -        public object ConvertBack(object value,
   13.53 -                                  Type targetType,
   13.54 -                                  object parameter,
   13.55 -                                  CultureInfo culture)
   13.56 -        {
   13.57 -            throw new NotImplementedException();
   13.58 -        }
   13.59 -    }
   13.60 -
   13.61 -    /// <summary>
   13.62      /// Converter to check if a list is empty.
   13.63      /// </summary>
   13.64      public class IsListEmptyConverter : IValueConverter
   13.65 @@ -530,6 +475,38 @@
   13.66      }
   13.67  
   13.68      /// <summary>
   13.69 +    /// Returns true if the Wizard is in the given state.
   13.70 +    /// </summary>
   13.71 +    public class IsWizardTypeConverter : IValueConverter
   13.72 +    {
   13.73 +        public object Convert(object value,
   13.74 +                              Type targetType,
   13.75 +                              object parameter,
   13.76 +                              CultureInfo culture)
   13.77 +        {
   13.78 +            string val = null;
   13.79 +            string param = parameter as string;
   13.80 +
   13.81 +            try
   13.82 +            {
   13.83 +                val = Enum.GetName(typeof(KeySyncWizard.WizardType), value);
   13.84 +            }
   13.85 +            catch
   13.86 +            {
   13.87 +                val = null;
   13.88 +            }
   13.89 +
   13.90 +            return (param?.Equals(val) == true);
   13.91 +        }
   13.92 +
   13.93 +        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   13.94 +        {
   13.95 +            throw new NotImplementedException();
   13.96 +        }
   13.97 +    }
   13.98 +
   13.99 +
  13.100 +    /// <summary>
  13.101      /// Converter to AND several bool values and convert to Visibility.
  13.102      /// </summary>
  13.103      public class MultiBooleanToVisibilityConverter : IMultiValueConverter