Ejemplo n.º 1
0
        /// <summary>
        /// Write the data as xml into an XmlWriter
        /// </summary>
        /// <param name="writer">XmlWriter to write config</param>
        public void WriteXmlString(XmlWriter writer, bool includeFilename = false, bool includeSettings = true)
        {
            writer.WriteStartDocument(true);
            //
            if (includeFilename == true && string.IsNullOrEmpty(this.Filename) == false)
            {
                writer.WriteComment(this.Filename);
            }
            //
            writer.WriteStartElement("WinAuth");
            writer.WriteAttributeString("version", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(2));
            //
            writer.WriteStartElement("alwaysontop");
            writer.WriteValue(this.AlwaysOnTop);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("usetrayicon");
            writer.WriteValue(this.UseTrayIcon);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("notifyaction");
            writer.WriteValue(Enum.GetName(typeof(NotifyActions), this.NotifyAction));
            writer.WriteEndElement();
            //
            writer.WriteStartElement("startwithwindows");
            writer.WriteValue(this.StartWithWindows);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("autosize");
            writer.WriteValue(this.AutoSize);
            writer.WriteEndElement();
            //
            if (this.Position.IsEmpty == false)
            {
                writer.WriteStartElement("left");
                writer.WriteValue(this.Position.X);
                writer.WriteEndElement();
                writer.WriteStartElement("top");
                writer.WriteValue(this.Position.Y);
                writer.WriteEndElement();
            }
            //
            writer.WriteStartElement("width");
            writer.WriteValue(this.Width);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("height");
            writer.WriteValue(this.Height);
            writer.WriteEndElement();
            //
            if (string.IsNullOrEmpty(this.ShadowType) == false)
            {
                writer.WriteStartElement("shadowtype");
                writer.WriteValue(this.ShadowType);
                writer.WriteEndElement();
            }
            //
            if (string.IsNullOrEmpty(this.PGPKey) == false)
            {
                writer.WriteStartElement("pgpkey");
                writer.WriteCData(this.PGPKey);
                writer.WriteEndElement();
            }

            if (PasswordType != Authenticator.PasswordTypes.None)
            {
                writer.WriteStartElement("data");

                StringBuilder encryptedTypes = new StringBuilder();
                if ((PasswordType & Authenticator.PasswordTypes.Explicit) != 0)
                {
                    encryptedTypes.Append("y");
                }
                if ((PasswordType & Authenticator.PasswordTypes.User) != 0)
                {
                    encryptedTypes.Append("u");
                }
                if ((PasswordType & Authenticator.PasswordTypes.Machine) != 0)
                {
                    encryptedTypes.Append("m");
                }
                if ((PasswordType & Authenticator.PasswordTypes.YubiKeySlot1) != 0)
                {
                    encryptedTypes.Append("a");
                }
                if ((PasswordType & Authenticator.PasswordTypes.YubiKeySlot2) != 0)
                {
                    encryptedTypes.Append("b");
                }
                writer.WriteAttributeString("encrypted", encryptedTypes.ToString());

                byte[] data;
                using (MemoryStream ms = new MemoryStream())
                {
                    XmlWriterSettings settings = new XmlWriterSettings();
                    settings.Indent   = true;
                    settings.Encoding = Encoding.UTF8;
                    using (XmlWriter encryptedwriter = XmlWriter.Create(ms, settings))
                    {
                        encryptedwriter.WriteStartElement("config");
                        foreach (WinAuthAuthenticator wa in this)
                        {
                            wa.WriteXmlString(encryptedwriter);
                        }
                        encryptedwriter.WriteEndElement();
                    }

                    data = ms.ToArray();
                }

                using (var hasher = new MD5CryptoServiceProvider())
                {
                    string encdata = Authenticator.EncryptSequence(Authenticator.ByteArrayToString(data), PasswordType, Password, this.Yubi);
                    string enchash = Authenticator.ByteArrayToString(hasher.ComputeHash(Authenticator.StringToByteArray(encdata)));
                    writer.WriteAttributeString("md5", enchash);
                    writer.WriteString(encdata);
                }

                writer.WriteEndElement();
            }
            else
            {
                foreach (WinAuthAuthenticator wa in this)
                {
                    wa.WriteXmlString(writer);
                }
            }

            if (includeSettings == true && _settings.Count != 0)
            {
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add(string.Empty, string.Empty);
                XmlSerializer serializer = new XmlSerializer(typeof(setting[]), new XmlRootAttribute()
                {
                    ElementName = "settings"
                });
                serializer.Serialize(writer, _settings.Select(e => new setting {
                    Key = e.Key, Value = e.Value
                }).ToArray(), ns);
            }

            // close WinAuth
            writer.WriteEndElement();

            // end document
            writer.WriteEndDocument();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Configure the Yubikey
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void yubiSecretUpdateButton_Click(object sender, EventArgs e)
        {
            if (yubiSecretField.Text.Trim().Length == 0)
            {
                WinAuthForm.ErrorDialog(this, "Please enter a secret phase or password");
                return;
            }

            if (WinAuthForm.ConfirmDialog(this,
                                          "This will overwrite any existing data on your YubiKey.\n\nAre you sure you want to continue?",
                                          MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) != System.Windows.Forms.DialogResult.Yes)
            {
                return;
            }

            int  slot  = (yubiSlotToggle.Checked == true ? 2 : 1);
            bool press = yubiPressToggle.Checked;

            // bug in YubiKey 3.2.x (and below?) where using keypress doesn't always work
            // see http://forum.yubico.com/viewtopic.php?f=26&t=1571
            if (press == true &&
                (this.Yubikey.Info.Status.VersionMajor < 3 ||
                 (this.Yubikey.Info.Status.VersionMajor == 3 && this.Yubikey.Info.Status.VersionMinor <= 3)))
            {
                if (WinAuthForm.ConfirmDialog(this,
                                              "This is a known issue using \"Require button press\" with YubiKeys that have firmware version 3.3 and below. It can cause intermittent problems when reading the Challenge-Response. You can contact Yubico and may be able to get a free replacement.\n\nDo you want to continue anyway?",
                                              MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) != System.Windows.Forms.DialogResult.Yes)
                {
                    return;
                }
            }

            // calculate the actual key. This is a byte version of the string, salt="mnemonic"(+user password TBD), PBKDF 2048 times, return 20byte/160bit key
            byte[] bytes = Encoding.UTF8.GetBytes(yubiSecretField.Text.Trim());
            string salt  = "mnemonic";

            byte[]             saltbytes = Encoding.UTF8.GetBytes(salt);
            Rfc2898DeriveBytes kg        = new Rfc2898DeriveBytes(bytes, saltbytes, YUBIKEY_PBKDF2_ITERATIONS);

            byte[] key = kg.GetBytes(YUBIKEY_PBKDF2_KEYSIZE);

            try
            {
                this.Yubikey.SetChallengeResponse(slot, key, key.Length, press);
            }
            catch (YubKeyException ex)
            {
                WinAuthForm.ErrorDialog(this, ex.Message, ex);
                return;
            }

            if (press == true)
            {
                if (WinAuthForm.ConfirmDialog(this,
                                              "Your YubiKey slot will now be verified. Please click its button when it flashes." + Environment.NewLine + Environment.NewLine + "Continue?",
                                              MessageBoxButtons.YesNo,
                                              MessageBoxIcon.Warning) != System.Windows.Forms.DialogResult.Yes)
                {
                    WinAuthForm.ErrorDialog(this, "Your YubiKey has been updated. Please verify it before continuing.");
                    return;
                }
            }

            // perform the test encryption/decryption using the yubi
            try
            {
                string challenge = "WinAuth";
                string plain     = Authenticator.ByteArrayToString(Encoding.ASCII.GetBytes(challenge));
                Authenticator.PasswordTypes passwordType = (slot == 1 ? Authenticator.PasswordTypes.YubiKeySlot1 : Authenticator.PasswordTypes.YubiKeySlot2);
                string encrypted = Authenticator.EncryptSequence(plain, passwordType, null, this.Yubikey);
                plain = Authenticator.DecryptSequence(encrypted, passwordType, null, this.Yubikey);
                string response = Encoding.ASCII.GetString(Authenticator.StringToByteArray(plain));
                if (challenge != response)
                {
                    throw new ApplicationException("verification failed");
                }
            }
            catch (ApplicationException ex)
            {
                WinAuthForm.ErrorDialog(this, "The YubiKey test failed. Please try configuring it again or doing it manually. (" + ex.Message + ")");
                return;
            }

            YubikeySlot = slot;

            WinAuthForm.ErrorDialog(this, "Your YubiKey has been successfully updated.");
        }