/// <summary> /// Write this authenticator into an XmlWriter /// </summary> /// <param name="writer">XmlWriter to receive authenticator</param> public void WriteToWriter(XmlWriter writer) { writer.WriteStartElement("authenticatordata"); //writer.WriteAttributeString("type", this.GetType().FullName); var encrypted = EncodePasswordTypes(PasswordType); if (string.IsNullOrEmpty(encrypted) == false) { writer.WriteAttributeString("encrypted", encrypted); } if (PasswordType != PasswordTypes.None) { writer.WriteRaw(EncryptedData.ThrowIsNull(nameof(EncryptedData))); } else { writer.WriteStartElement("servertimediff"); writer.WriteString(ServerTimeDiff.ToString()); writer.WriteEndElement(); // writer.WriteStartElement("lastservertime"); writer.WriteString(LastServerTime.ToString()); writer.WriteEndElement(); // writer.WriteStartElement("secretdata"); writer.WriteString(SecretData); writer.WriteEndElement(); WriteExtraXml(writer); } /* * if (passwordType != Authenticator.PasswordTypes.None) * { * //string data = this.EncryptedData; * //if (data == null) * //{ * // using (MemoryStream ms = new MemoryStream()) * // { * // XmlWriterSettings settings = new XmlWriterSettings(); * // settings.Indent = true; * // settings.Encoding = Encoding.UTF8; * // using (XmlWriter encryptedwriter = XmlWriter.Create(ms, settings)) * // { * // Authenticator.PasswordTypes savedpasswordType = PasswordType; * // PasswordType = Authenticator.PasswordTypes.None; * // WriteToWriter(encryptedwriter); * // PasswordType = savedpasswordType; * // } * // data = Authenticator.ByteArrayToString(ms.ToArray()); * // } * * // data = Authenticator.EncryptSequence(data, PasswordType, Password); * //} * * writer.WriteString(this.EncryptedData); * writer.WriteEndElement(); * * return; * } * * // * writer.WriteStartElement("servertimediff"); * writer.WriteString(ServerTimeDiff.ToString()); * writer.WriteEndElement(); * // * writer.WriteStartElement("secretdata"); * writer.WriteString(SecretData); * writer.WriteEndElement(); * * WriteExtraXml(writer); */ writer.WriteEndElement(); }
public bool Unprotect(string?password) { var passwordType = PasswordType; if (passwordType == PasswordTypes.None) { throw new InvalidOperationException("Cannot Unprotect a non-encrypted authenticator"); } // decrypt var changed = false; try { var data = DecryptSequence( EncryptedData.ThrowIsNull(nameof(EncryptedData)), PasswordType, password); using (var ms = new MemoryStream(StringToByteArray(data))) { var reader = XmlReader.Create(ms); changed = ReadXml(reader, password) || changed; } RequiresPassword = false; // calculate hash of current secretdata using (var sha1 = SHA1.Create()) { SecretHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(SecretData.ThrowIsNull(nameof(SecretData)))); } // keep the password until we reprotect in case data changes Password = password; if (changed == true) { // we need to encrypt changed secret data using var ms = new MemoryStream(); // get the plain version var settings = new XmlWriterSettings { Indent = true, Encoding = Encoding.UTF8 }; using (var encryptedwriter = XmlWriter.Create(ms, settings)) { WriteToWriter(encryptedwriter); } var encrypteddata = ByteArrayToString(ms.ToArray()); // update secret hash using (var sha1 = SHA1.Create()) { SecretHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(SecretData.ThrowIsNull(nameof(SecretData)))); } // encrypt EncryptedData = EncryptSequence(encrypteddata, passwordType, password); } return(changed); } catch (WinAuthEncryptedSecretDataException) { RequiresPassword = true; throw; } finally { PasswordType = passwordType; } }