public ArcFourStream(Stream sBaseStream, bool bEncrypting, byte[] pbKey, byte[] pbIV) { Debug.Assert(sBaseStream != null); if (sBaseStream == null) { throw new ArgumentNullException("sBaseStream"); } m_sBaseStream = sBaseStream; m_bEncrypting = bEncrypting; MemoryStream ms = new MemoryStream(); if (pbIV != null) { ms.Write(pbIV, 0, pbIV.Length); } else { Debug.Assert(false); } if (pbKey != null) { ms.Write(pbKey, 0, pbKey.Length); } else { Debug.Assert(false); } SHA256Managed sha256 = new SHA256Managed(); byte[] pbFinalKey = sha256.ComputeHash(ms.ToArray()); m_crs = new CryptoRandomStream(CrsAlgorithm.ArcFour, pbFinalKey); }
public static PwgError Generate(ProtectedString psOutBuffer, PwProfile pwProfile, byte[] pbUserEntropy) { Debug.Assert(psOutBuffer != null); if (psOutBuffer == null) { throw new ArgumentNullException("psOutBuffer"); } Debug.Assert(pwProfile != null); if (pwProfile == null) { throw new ArgumentNullException("pwProfile"); } psOutBuffer.Clear(); CryptoRandomStream crs = CreateCryptoStream(pbUserEntropy); PwgError e = PwgError.Unknown; if (pwProfile.GeneratorType == PasswordGeneratorType.CharSet) { e = CharSetBasedGenerator.Generate(psOutBuffer, pwProfile, crs); } else if (pwProfile.GeneratorType == PasswordGeneratorType.Pattern) { e = PatternBasedGenerator.Generate(psOutBuffer, pwProfile, crs); } else { Debug.Assert(false); } return(e); }
private void TestGetRandomInt64(CryptoRandomStream stream) { var value1 = stream.GetRandomUInt64(); var value2 = stream.GetRandomUInt64(); Assert.That(value2, Is.Not.EqualTo(value1)); }
public static PwgError Generate(ProtectedString psOutBuffer, PwProfile pwProfile, CryptoRandomStream crsRandomSource) { if (pwProfile.Length == 0) { return(PwgError.Success); } PwCharSet pcs = new PwCharSet(pwProfile.CharSet.ToString()); char[] vGenerated = new char[pwProfile.Length]; PwGenerator.PrepareCharSet(pcs, pwProfile); for (int nIndex = 0; nIndex < (int)pwProfile.Length; ++nIndex) { char ch = PwGenerator.GenerateCharacter(pwProfile, pcs, crsRandomSource); if (ch == char.MinValue) { Array.Clear(vGenerated, 0, vGenerated.Length); return(PwgError.TooFewCharacters); } vGenerated[nIndex] = ch; } byte[] pbUTF8 = Encoding.UTF8.GetBytes(vGenerated); psOutBuffer.SetString(Encoding.UTF8.GetString(pbUTF8, 0, pbUTF8.Length)); Array.Clear(pbUTF8, 0, pbUTF8.Length); Array.Clear(vGenerated, 0, vGenerated.Length); return(PwgError.Success); }
private void TestGetRandomInt64(CryptoRandomStream stream) { var value1 = stream.GetRandomUInt64(); var value2 = stream.GetRandomUInt64(); Assert.NotEqual(value2, value1); }
internal static void ShufflePassword(char[] pPassword, CryptoRandomStream crsRandomSource) { Debug.Assert(pPassword != null); if (pPassword == null) { return; } Debug.Assert(crsRandomSource != null); if (crsRandomSource == null) { return; } if (pPassword.Length <= 1) { return; // Nothing to shuffle } for (int nSelect = 0; nSelect < pPassword.Length; ++nSelect) { ulong uRandomIndex = crsRandomSource.GetRandomUInt64(); uRandomIndex %= (ulong)(pPassword.Length - nSelect); char chTemp = pPassword[nSelect]; pPassword[nSelect] = pPassword[nSelect + (int)uRandomIndex]; pPassword[nSelect + (int)uRandomIndex] = chTemp; } }
public override ProtectedString Generate(PwProfile prf, CryptoRandomStream crsRandomSource) { var profile = prf; if (profile == null) { profile = new PwProfile(); } // Load the phrase template from config. var conf = new Config(profile.CustomAlgorithmOptions); // Create and cache the dictionary. // Important note: do not cache the CryptoRandomStream or ReadablePassphraseGenerator // If you do, the CryptoRandomStream is disposed after the method returns, and you end up with very deterministic random numbers. // This can manifest itself as the name sandom words are generated in the Preview tab in KeeyPass's Generate Password form. // OR in more recent version of KeePass, you get an ObjectDisposedException var dict = GetDictionary(conf); var generator = new MurrayGrant.ReadablePassphrase.ReadablePassphraseGenerator(dict, new KeePassRandomSource(crsRandomSource)); if (conf.Mutator != MutatorOption.None) { return(GenerateForMutators(generator, conf)); } else if (Environment.OSVersion.Platform == PlatformID.Win32NT) { return(GenerateSecure(generator, conf)); } else { return(GenerateNotSoSecure(generator, conf)); } }
public static PwgError Generate(ProtectedString psOutBuffer, PwProfile pwProfile, CryptoRandomStream crsRandomSource) { if(pwProfile.Length == 0) return PwgError.Success; PwCharSet pcs = new PwCharSet(pwProfile.CharSet.ToString()); char[] vGenerated = new char[pwProfile.Length]; PwGenerator.PrepareCharSet(pcs, pwProfile); for(int nIndex = 0; nIndex < (int)pwProfile.Length; ++nIndex) { char ch = PwGenerator.GenerateCharacter(pwProfile, pcs, crsRandomSource); if(ch == char.MinValue) { Array.Clear(vGenerated, 0, vGenerated.Length); return PwgError.TooFewCharacters; } vGenerated[nIndex] = ch; } byte[] pbUTF8 = Encoding.UTF8.GetBytes(vGenerated); psOutBuffer.SetString(Encoding.UTF8.GetString(pbUTF8, 0, pbUTF8.Length)); Array.Clear(pbUTF8, 0, pbUTF8.Length); Array.Clear(vGenerated, 0, vGenerated.Length); return PwgError.Success; }
/// <summary> /// Read the protected data and return it protected with a sequence /// of bytes generated by a random stream. The object's data will be /// invisible in process memory only if the object has been initialized /// using a <c>XorredBuffer</c>. If no <c>XorredBuffer</c> has been used /// or the binary has been read once already (in plain-text), the /// operation won't be secure and the protected string will be visible /// in process memory. /// </summary> /// <param name="crsRandomSource">Random number source.</param> /// <returns>Protected data.</returns> /// <exception cref="System.ArgumentNullException">Thrown if the input /// parameter is <c>null</c>.</exception> public byte[] ReadXorredData(CryptoRandomStream crsRandomSource) { Debug.Assert(crsRandomSource != null); if (crsRandomSource == null) { throw new ArgumentNullException("crsRandomSource"); } if (m_xbEncrypted != null) { uint uLen = m_xbEncrypted.Length; byte[] randomPad = crsRandomSource.GetRandomBytes(uLen); return(m_xbEncrypted.ChangeKey(randomPad)); } else { byte[] pbData = ReadData(); uint uLen = (uint)pbData.Length; byte[] randomPad = crsRandomSource.GetRandomBytes(uLen); Debug.Assert(randomPad.Length == uLen); for (uint i = 0; i < uLen; i++) { pbData[i] ^= randomPad[i]; } return(pbData); } }
internal static PwgError Generate(out ProtectedString psOut, PwProfile pwProfile, CryptoRandomStream crsRandomSource) { psOut = ProtectedString.Empty; if(pwProfile.Length == 0) return PwgError.Success; PwCharSet pcs = new PwCharSet(pwProfile.CharSet.ToString()); char[] vGenerated = new char[pwProfile.Length]; PwGenerator.PrepareCharSet(pcs, pwProfile); for(int nIndex = 0; nIndex < (int)pwProfile.Length; ++nIndex) { char ch = PwGenerator.GenerateCharacter(pwProfile, pcs, crsRandomSource); if(ch == char.MinValue) { Array.Clear(vGenerated, 0, vGenerated.Length); return PwgError.TooFewCharacters; } vGenerated[nIndex] = ch; } byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vGenerated); psOut = new ProtectedString(true, pbUtf8); MemUtil.ZeroByteArray(pbUtf8); Array.Clear(vGenerated, 0, vGenerated.Length); return PwgError.Success; }
internal static void ShufflePassword(char[] password, CryptoRandomStream crsRandomSource) { if (string.IsNullOrEmpty(password.ToString())) { return; } if (crsRandomSource == null) { return; } if (password.Length <= 1) { return; // Nothing to shuffle } for (var nSelect = 0; nSelect < password.Length; ++nSelect) { var randomIndex = crsRandomSource.GetRandomUInt64(); randomIndex %= (ulong)(password.Length - nSelect); char chTemp = password[nSelect]; password[nSelect] = password[nSelect + (int)randomIndex]; password[nSelect + (int)randomIndex] = chTemp; } }
public override ProtectedString Generate(PwProfile prf, CryptoRandomStream crsRandomSource) { if (prf == null) { Debug.Assert(false); } else { Debug.Assert(prf.CustomAlgorithmUuid == Convert.ToBase64String( m_uuid.UuidBytes, Base64FormattingOptions.None)); } var persistence = new ConfigurationPersistence(); var config = persistence.LoadFromUserFile(); InitWuerfelwareFileReaderIfNecessary(); // no entries? if (WuerfelwareFileReader.MaxValidIndex < 0) { throw new IndexOutOfRangeException("Word list ist empty"); } var resultingWords = new List <string>(); for (var i = 0; i < Math.Min(Math.Max(Constants.MinWordsPerPassphrase, config.WordCount), Constants.MaxWordsPerPassphrase); i++) { var index = GetRandomIndex(crsRandomSource, (ulong)WuerfelwareFileReader.EntryCount); // note: we checked earlier that entryCount is >= 0 // index cannot be higher than int.MaxValue since MaxIndex is of type int resultingWords.Add(WuerfelwareFileReader.GetEntry((int)index)); } return(new ProtectedString(false, string.Join(" ", resultingWords.ToArray()))); }
public static PwgError Generate(out ProtectedString psOut, PwProfile pwProfile, byte[] pbUserEntropy, CustomPwGeneratorPool pwAlgorithmPool) { Debug.Assert(pwProfile != null); if (pwProfile == null) { throw new ArgumentNullException("pwProfile"); } CryptoRandomStream crs = CreateCryptoStream(pbUserEntropy); PwgError e = PwgError.Unknown; if (pwProfile.GeneratorType == PasswordGeneratorType.CharSet) { e = CharSetBasedGenerator.Generate(out psOut, pwProfile, crs); } else if (pwProfile.GeneratorType == PasswordGeneratorType.Pattern) { e = PatternBasedGenerator.Generate(out psOut, pwProfile, crs); } else if (pwProfile.GeneratorType == PasswordGeneratorType.Custom) { e = GenerateCustom(out psOut, pwProfile, crs, pwAlgorithmPool); } else { Debug.Assert(false); psOut = ProtectedString.Empty; } return(e); }
public KeePassRandomSource() { var randomness = System.Security.Cryptography.RandomNumberGenerator.Create(); var bytes = new byte[32]; randomness.GetBytes(bytes); this._Crs = new CryptoRandomStream(CrsAlgorithm.Salsa20, bytes); }
void TestGetRandomBytes(CryptoRandomStream stream) { const uint length = 16; var bytes1 = stream.GetRandomBytes(length); Assert.That(bytes1.Length, Is.EqualTo(length)); var bytes2 = stream.GetRandomBytes(length); Assert.That(bytes2, Is.Not.EqualTo(bytes1)); }
private void TestGetRandomBytes(CryptoRandomStream stream) { const uint length = 16; var bytes1 = stream.GetRandomBytes(length); Assert.That((int)length, Is.EqualTo(bytes1.Length)); var bytes2 = stream.GetRandomBytes(length); Assert.That(MemUtil.ArraysEqual(bytes2, bytes1), Is.False); }
/// <summary> /// Make an instance of the <see cref="RandomUtil">RandomUtil</see> class. /// </summary> /// <returns>A <see cref="RandomUtil">RandomUtil</see> instance.</returns> public static RandomUtil Make() { var bytes = new byte[32]; var rnd = new Random(); rnd.NextBytes(bytes); var stream = new CryptoRandomStream(CrsAlgorithm.ChaCha20, bytes); return(new RandomUtil(stream)); }
/// <summary> /// Generates and returns a password as a protected string. /// </summary> /// <param name="prf">Password profile.</param> /// <param name="crsRandomSource">Cryptographic random source.</param> /// <returns>The generated password.</returns> public override ProtectedString Generate(PwProfile prf, CryptoRandomStream crsRandomSource) { UserConfig config = UserConfig.Deserialize(prf.CustomAlgorithmOptions); SystemConfig sysConfig = new SystemConfig(); RandomUtil random = new RandomUtil(crsRandomSource); IRepositoryFactory factory = new FileRepositoryFactory(config, sysConfig); IPhraseRepository repo = factory.Make(random); ISpecialCharsRepository specialCharsRepo = factory.MakeSpecialChars(random); IPhraseGenerator generator = new PhraseGenerator(config, repo, specialCharsRepo); return(generator.Generate()); }
/// <summary> /// Get a random value from 0..maxValue_Exclusive-1. /// /// This methods prevents mod bias - see here for more details: https://stackoverflow.com/a/10989061/56658 /// /// </summary> /// <param name="crsRandomSource">Keepass random number generator</param> /// <param name="maxValue_Exclusive">Upper range for random numbers; result will be in range 0..<paramref name="maxValue_Exclusive"/>-1</param> /// <returns></returns> private ulong GetRandomIndex(CryptoRandomStream crsRandomSource, ulong maxValue_Exclusive) { var RAND_MAX = UInt64.MaxValue; ulong maxValid = RAND_MAX - (RAND_MAX % maxValue_Exclusive); UInt64 x; // Keep searching for an x in a range divisible by maxValid do { x = crsRandomSource.GetRandomUInt64(); } while (x >= maxValid); return(x % maxValue_Exclusive); }
internal static char GenerateCharacter(PwCharSet pwCharSet, CryptoRandomStream crsRandomSource) { uint cc = pwCharSet.Size; if (cc == 0) { return(char.MinValue); } uint i = (uint)crsRandomSource.GetRandomUInt64(cc); return(pwCharSet[i]); }
public static PwgError Generate(out ProtectedString psOut, PwProfile pwProfile, byte[] pbUserEntropy, CustomPwGeneratorPool pwAlgorithmPool) { Debug.Assert(pwProfile != null); if (pwProfile == null) { throw new ArgumentNullException("pwProfile"); } PwgError e = PwgError.Unknown; CryptoRandomStream crs = null; byte[] pbKey = null; try { crs = CreateRandomStream(pbUserEntropy, out pbKey); if (pwProfile.GeneratorType == PasswordGeneratorType.CharSet) { e = CharSetBasedGenerator.Generate(out psOut, pwProfile, crs); } else if (pwProfile.GeneratorType == PasswordGeneratorType.Pattern) { e = PatternBasedGenerator.Generate(out psOut, pwProfile, crs); } else if (pwProfile.GeneratorType == PasswordGeneratorType.Custom) { e = GenerateCustom(out psOut, pwProfile, crs, pwAlgorithmPool); } else { Debug.Assert(false); psOut = ProtectedString.Empty; } } finally { if (crs != null) { crs.Dispose(); } if (pbKey != null) { MemUtil.ZeroByteArray(pbKey); } } return(e); }
/// <summary> /// Decrypts the protected fields. /// </summary> /// <param name="crypto">The crypto random stream.</param> public void Decrypt(CryptoRandomStream crypto) { if (crypto == null) { throw new ArgumentNullException("crypto"); } var values = GetProtectedValues(); foreach (var item in values) { item.Value = crypto .Decrypt(item.Value); } }
internal static char GenerateCharacter(PwProfile pwProfile, PwCharSet pwCharSet, CryptoRandomStream crsRandomSource) { if(pwCharSet.Size == 0) return char.MinValue; ulong uIndex = crsRandomSource.GetRandomUInt64(); uIndex %= (ulong)pwCharSet.Size; char ch = pwCharSet[(uint)uIndex]; if(pwProfile.NoRepeatingCharacters) pwCharSet.Remove(ch); return ch; }
public override ProtectedString Generate(PwProfile prf, CryptoRandomStream crsRandomSource) { if (prf == null) { Debug.Assert(false); } else { Debug.Assert(prf.CustomAlgorithmUuid == Convert.ToBase64String( m_uuid.UuidBytes, Base64FormattingOptions.None)); } Random keylen = new Random((int)crsRandomSource.GetRandomUInt64()); int k = keylen.Next(3, 7); return(new ProtectedString(false, cockPwdGenerator(k, keylen))); }
/// <summary> /// Generates a random integer between <paramref name="min"/> and <paramref name="max"/>. /// </summary> /// <param name="random">A <see cref="CryptoRandomStream"/> instance.</param> /// <param name="min">The minimum value.</param> /// <param name="max">The maximum value.</param> /// <returns>A random value between <paramref name="min"/> and <paramref name="max"/>.</returns> public static int Next(this CryptoRandomStream random, int min, int max) { if (min >= max) { throw new ArgumentOutOfRangeException("min" /*nameof(min)*/); } var diff = (long)max - min; var upperBound = uint.MaxValue / diff * diff; uint ui; do { ui = (uint)random.GetRandomUInt64(); }while (ui >= upperBound); return((int)(min + (ui % diff))); }
internal static PwgError Generate(out ProtectedString psOut, PwProfile pwProfile, CryptoRandomStream crsRandomSource) { psOut = ProtectedString.Empty; if (pwProfile.Length == 0) { return(PwgError.Success); } PwCharSet pcs = new PwCharSet(pwProfile.CharSet.ToString()); if (!PwGenerator.PrepareCharSet(pcs, pwProfile)) { return(PwgError.InvalidCharSet); } char[] v = new char[pwProfile.Length]; try { for (int i = 0; i < v.Length; ++i) { char ch = PwGenerator.GenerateCharacter(pcs, crsRandomSource); if (ch == char.MinValue) { return(PwgError.TooFewCharacters); } v[i] = ch; if (pwProfile.NoRepeatingCharacters) { pcs.Remove(ch); } } byte[] pbUtf8 = StrUtil.Utf8.GetBytes(v); psOut = new ProtectedString(true, pbUtf8); MemUtil.ZeroByteArray(pbUtf8); } finally { MemUtil.ZeroArray <char>(v); } return(PwgError.Success); }
/// <summary> /// Read the protected string and return it protected with a sequence /// of bytes generated by a random stream. /// </summary> /// <param name="crsRandomSource">Random number source.</param> /// <returns>Protected string.</returns> public byte[] ReadXorredString(CryptoRandomStream crsRandomSource) { Debug.Assert(crsRandomSource != null); if (crsRandomSource == null) { throw new ArgumentNullException("crsRandomSource"); } byte[] pbData = ReadUtf8(); uint uLen = (uint)pbData.Length; byte[] randomPad = crsRandomSource.GetRandomBytes(uLen); Debug.Assert(randomPad.Length == pbData.Length); for (uint i = 0; i < uLen; ++i) { pbData[i] ^= randomPad[i]; } return(pbData); }
/// <inheritdoc/> public override ProtectedString Generate(CryptoRandomStream random, Settings settings) { if (random == null) { throw new ArgumentNullException("random" /*nameof(random)*/); } if (settings == null) { throw new ArgumentNullException("settings" /*nameof(settings)*/); } var wordlist = GetWordlist(settings); var result = new List <string>(); do { result.Add(wordlist[random.Next(0, wordlist.Length)]); }while (QualityEstimation.EstimatePasswordBits(string.Join(string.Empty, result.ToArray()).ToCharArray()) < Count); return(new ProtectedString(true, string.Join(Separator, result.ToArray()))); }
public static IEnumerable <T> GetRandomPermutation <T>(this CryptoRandomStream crs, IEnumerable <T> enumerable) { var len = enumerable.Count(); var set = new bool[len]; var ret = new T[len]; foreach (var elem in enumerable) { var index = GetRandomInt(crs, len); while (set[index]) { index = (index + 1) % len; } ret[index] = elem; set[index] = true; } return(ret); }
internal static void Shuffle(char[] v, CryptoRandomStream crsRandomSource) { if (v == null) { Debug.Assert(false); return; } if (crsRandomSource == null) { Debug.Assert(false); return; } for (int i = v.Length - 1; i >= 1; --i) { int j = (int)crsRandomSource.GetRandomUInt64((ulong)(i + 1)); char t = v[i]; v[i] = v[j]; v[j] = t; } }
/// <summary> /// Generates a password with a given profile. /// </summary> /// <param name="prf">A password generator profile.</param> /// <param name="crsRandomSource">A <see cref="CryptoRandomStream"/> instance for generating random numbers.</param> /// <returns>A <see cref="ProtectedString"/> containing a generated password.</returns> public override ProtectedString Generate(PwProfile prf, CryptoRandomStream crsRandomSource) { if (prf == null) { throw new ArgumentNullException("prf" /*nameof(prf)*/); } if (crsRandomSource == null) { throw new ArgumentNullException("crsRandomSource" /*nameof(crsRandomSource)*/); } //if (prf == null) // Debug.Assert(false); //else // Debug.Assert(prf.CustomAlgorithmUuid == Convert.ToBase64String(Uuid.UuidBytes, Base64FormattingOptions.None)); var settings = Settings.Deserialize(prf.CustomAlgorithmOptions) ?? Settings.Default; return(settings.Generate(crsRandomSource)); }
public XmlParser(CryptoRandomStream crypto, Stream stream, Dispatcher dispatcher) { if (crypto == null) { throw new ArgumentNullException("crypto"); } if (stream == null) { throw new ArgumentNullException("stream"); } if (dispatcher == null) { throw new ArgumentNullException("dispatcher"); } _crypto = crypto; _stream = stream; _dispatcher = dispatcher; }
public void ExpandPattern() { // arrange var psOutBuffer = new ProtectedString(); var pwProfile = new PwProfile(); pwProfile.Pattern = "g{5}"; var pbKey = new byte[] { 0x00 }; var crsRandomSource = new CryptoRandomStream(CrsAlgorithm.Salsa20, pbKey); var error = PatternBasedGenerator.Generate(psOutBuffer, pwProfile, crsRandomSource); // act // nothing to do as ExpandPattern() would have been called by calling Generate() // assert Assert.AreEqual(PwgError.Success, error); var actual = psOutBuffer.ReadString(); Assert.AreEqual("ggggg", actual); }
private static PwgError GenerateCustom(out ProtectedString psOut, PwProfile pwProfile, CryptoRandomStream crs, CustomPwGeneratorPool pwAlgorithmPool) { psOut = ProtectedString.Empty; Debug.Assert(pwProfile.GeneratorType == PasswordGeneratorType.Custom); if(pwAlgorithmPool == null) return PwgError.UnknownAlgorithm; string strID = pwProfile.CustomAlgorithmUuid; if(string.IsNullOrEmpty(strID)) { Debug.Assert(false); return PwgError.UnknownAlgorithm; } byte[] pbUuid = Convert.FromBase64String(strID); PwUuid uuid = new PwUuid(pbUuid); CustomPwGenerator pwg = pwAlgorithmPool.Find(uuid); if(pwg == null) { Debug.Assert(false); return PwgError.UnknownAlgorithm; } ProtectedString pwd = pwg.Generate(pwProfile.CloneDeep(), crs); if(pwd == null) return PwgError.Unknown; psOut = pwd; return PwgError.Success; }
internal static void ShufflePassword(char[] pPassword, CryptoRandomStream crsRandomSource) { Debug.Assert(pPassword != null); if(pPassword == null) return; Debug.Assert(crsRandomSource != null); if(crsRandomSource == null) return; if(pPassword.Length <= 1) return; // Nothing to shuffle for(int nSelect = 0; nSelect < pPassword.Length; ++nSelect) { ulong uRandomIndex = crsRandomSource.GetRandomUInt64(); uRandomIndex %= (ulong)(pPassword.Length - nSelect); char chTemp = pPassword[nSelect]; pPassword[nSelect] = pPassword[nSelect + (int)uRandomIndex]; pPassword[nSelect + (int)uRandomIndex] = chTemp; } }
public static PwgError Generate(ProtectedString psOutBuffer, PwProfile pwProfile, CryptoRandomStream crsRandomSource) { LinkedList<char> vGenerated = new LinkedList<char>(); PwCharSet pcsCurrent = new PwCharSet(); PwCharSet pcsCustom = new PwCharSet(); PwCharSet pcsUsed = new PwCharSet(); bool bInCharSetDef = false; string strPattern = ExpandPattern(pwProfile.Pattern); if(strPattern.Length == 0) return PwgError.Success; CharStream csStream = new CharStream(strPattern); char ch = csStream.ReadChar(); while(ch != char.MinValue) { pcsCurrent.Clear(); bool bGenerateChar = false; if(ch == '\\') { ch = csStream.ReadChar(); if(ch == char.MinValue) // Backslash at the end { vGenerated.AddLast('\\'); break; } if(bInCharSetDef) pcsCustom.Add(ch); else { vGenerated.AddLast(ch); pcsUsed.Add(ch); } } else if(ch == '[') { pcsCustom.Clear(); bInCharSetDef = true; } else if(ch == ']') { pcsCurrent.Add(pcsCustom.ToString()); bInCharSetDef = false; bGenerateChar = true; } else if(bInCharSetDef) { if(pcsCustom.AddCharSet(ch) == false) pcsCustom.Add(ch); } else if(pcsCurrent.AddCharSet(ch) == false) { vGenerated.AddLast(ch); pcsUsed.Add(ch); } else bGenerateChar = true; if(bGenerateChar) { PwGenerator.PrepareCharSet(pcsCurrent, pwProfile); if(pwProfile.NoRepeatingCharacters) pcsCurrent.Remove(pcsUsed.ToString()); char chGen = PwGenerator.GenerateCharacter(pwProfile, pcsCurrent, crsRandomSource); if(chGen == char.MinValue) return PwgError.TooFewCharacters; vGenerated.AddLast(chGen); pcsUsed.Add(chGen); } ch = csStream.ReadChar(); } if(vGenerated.Count == 0) return PwgError.Success; char[] vArray = new char[vGenerated.Count]; vGenerated.CopyTo(vArray, 0); if(pwProfile.PatternPermutePassword) PwGenerator.ShufflePassword(vArray, crsRandomSource); byte[] pbUtf8 = Encoding.UTF8.GetBytes(vArray); psOutBuffer.SetString(Encoding.UTF8.GetString(pbUtf8, 0, pbUtf8.Length)); Array.Clear(pbUtf8, 0, pbUtf8.Length); Array.Clear(vArray, 0, vArray.Length); vGenerated.Clear(); return PwgError.Success; }
/// <summary> /// Password generation function. /// </summary> /// <param name="prf">Password generation options chosen /// by the user. This may be <c>null</c>, if the default /// options should be used.</param> /// <param name="crsRandomSource">Source that the algorithm /// can use to generate random numbers.</param> /// <returns>Generated password or <c>null</c> in case /// of failure. If returning <c>null</c>, the caller assumes /// that an error message has already been shown to the user.</returns> public abstract ProtectedString Generate(PwProfile prf, CryptoRandomStream crsRandomSource);