Ejemplo n.º 1
0
 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));
 }
        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));

            if (string.IsNullOrEmpty(settings.WordListLocation))
            {
                System.Windows.Forms.MessageBox.Show("No word list location");
                GetSettingsFromUser();
                return null;
            }

            if (!System.IO.File.Exists(settings.WordListLocation))
            {
                System.Windows.Forms.MessageBox.Show(string.Format("Word List doesn't exist at location {0}", settings.WordListLocation));
                GetSettingsFromUser();
                return null;
            }

            try
            {
                if (words == null)
                    words = System.IO.File.ReadAllLines(settings.WordListLocation);

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < settings.NumberOfWords; i++)
                {
                    ulong u = crsRandomSource.GetRandomUInt64();
                    u %= (ulong)(words.Length - 1);

                    if (i > 0) sb.Append(settings.Separator);

                    string word = words[u];
                    if (i == 0 && word.Length > 1)
                        word = word.Substring(0, 1).ToUpper() + word.Substring(1, word.Length - 1);

                    sb.Append(word);
                }
                sb.Append(settings.TrailingTrash);
                return new ProtectedString(false, sb.ToString());
            }

            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(string.Format("Encountered this error while generating password: {0}", ex.Message));
            }
            return null;
        }
Ejemplo n.º 3
0
        private static int BenchTime(CrsAlgorithm cra, int nRounds, int nDataSize)
        {
            byte[] pbKey = new byte[4] {
                0x00, 0x01, 0x02, 0x03
            };

            int nStart = Environment.TickCount;

            for (int i = 0; i < nRounds; ++i)
            {
                CryptoRandomStream c = new CryptoRandomStream(cra, pbKey);
                c.GetRandomBytes((uint)nDataSize);
            }
            int nEnd = Environment.TickCount;

            return(nEnd - nStart);
        }
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);
}
Ejemplo n.º 5
0
        public override ProtectedString Generate(PwProfile prf, CryptoRandomStream crsRandomSource)
        {
            Random r = new Random((int)crsRandomSource.GetRandomUInt64());
            var opt = new DiceWareOptions(prf.CustomAlgorithmOptions);

            string result = "";
            int word = 0;

            for (int i = 0; i < 5 * opt.WordCount; i++)
            {
                word *= 10;
                word += (1 + r.Next(6));

                if ((i + 1) % 5 == 0 && i > 0)
                {
                    result += words[word];
                    result += " ";

                    word = 0;
                }
            }

            return new ProtectedString(true, result.Trim());
        }
Ejemplo n.º 6
0
		/// <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;
		}
Ejemplo n.º 7
0
 /// <summary>
 /// Initializes a new RandomNumber
 /// </summary>
 /// <param name="stream">The random stream.</param>
 public RandomNumber(CryptoRandomStream stream)
 {
     _stream = stream;
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Generate a random dictionary password.
        /// </summary>
        /// <param name="prf">The password profile to use.</param>
        /// <param name="crsRandomSource">The cryptographic stream.</param>
        /// <returns>A generated ProtectedString password.</returns>
        public override ProtectedString Generate(PwProfile prf, CryptoRandomStream crsRandomSource)
        {
            // Get the generator options.
            GeneratorOptions options = new GeneratorOptions(prf.CustomAlgorithmOptions);

            // Check if a word dictionary has already been loaded, if not, load it.
            if (_wordDictionary == null || _currentWordLength != options.WordLength)
            {
                _wordDictionary = ExtractWordDictionary(options.WordLength);
                _currentWordLength = options.WordLength;
            }

            // Get a random word from the dictionary
            RandomNumber randomNumber = new RandomNumber(crsRandomSource);
            string password = _wordDictionary.Count > 0 ? _wordDictionary[randomNumber.Next(_wordDictionary.Count)] : string.Empty;
            _wordDictionary.Remove(password);

            // Substitute characters if specified.
            if (options.SubstituteCharacters && !string.IsNullOrEmpty(options.SubstitutionList))
                password = SubstituteCharacters(password, options.SubstitutionList);

            // Capitalize if necessary
            if (options.CapitalizationType != CapitalizationTypes.None)
                password = CapitalizePassword(password, options.CapitalizationType, randomNumber);

            return new ProtectedString(false, password);
        }
Ejemplo n.º 9
0
        // public void Save(string strFile, PwGroup pgDataSource, KdbxFormat format,
        //    IStatusLogger slLogger)
        // {
        //    bool bMadeUnhidden = UrlUtil.UnhideFile(strFile);
        //
        //    IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);
        //    this.Save(IOConnection.OpenWrite(ioc), pgDataSource, format, slLogger);
        //
        //    if(bMadeUnhidden) UrlUtil.HideFile(strFile, true); // Hide again
        // }
        /// <summary>
        /// Save the contents of the current <c>PwDatabase</c> to a KDBX file.
        /// </summary>
        /// <param name="sSaveTo">Stream to write the KDBX file into.</param>
        /// <param name="pgDataSource">Group containing all groups and
        /// entries to write. If <c>null</c>, the complete database will
        /// be written.</param>
        /// <param name="format">Format of the file to create.</param>
        /// <param name="slLogger">Logger that recieves status information.</param>
        public void Save(Stream sSaveTo, PwGroup pgDataSource, KdbxFormat format,
			IStatusLogger slLogger)
        {
            Debug.Assert(sSaveTo != null);
            if(sSaveTo == null) throw new ArgumentNullException("sSaveTo");

            m_format = format;
            m_slLogger = slLogger;

            HashingStreamEx hashedStream = new HashingStreamEx(sSaveTo, true, null);

            UTF8Encoding encNoBom = StrUtil.Utf8;
            CryptoRandom cr = CryptoRandom.Instance;

            try
            {
                m_pbMasterSeed = cr.GetRandomBytes(32);
                m_pbTransformSeed = cr.GetRandomBytes(32);
                m_pbEncryptionIV = cr.GetRandomBytes(16);

                m_pbProtectedStreamKey = cr.GetRandomBytes(32);
                m_craInnerRandomStream = CrsAlgorithm.Salsa20;
                m_randomStream = new CryptoRandomStream(m_craInnerRandomStream,
                    m_pbProtectedStreamKey);

                m_pbStreamStartBytes = cr.GetRandomBytes(32);

                Stream writerStream;
                if(m_format == KdbxFormat.Default)
                {
                    WriteHeader(hashedStream); // Also flushes the stream

                    Stream sEncrypted = AttachStreamEncryptor(hashedStream);
                    if((sEncrypted == null) || (sEncrypted == hashedStream))
                        throw new SecurityException(KLRes.CryptoStreamFailed);

                    sEncrypted.Write(m_pbStreamStartBytes, 0, m_pbStreamStartBytes.Length);

                    Stream sHashed = new HashedBlockStream(sEncrypted, true);

                    if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
                        writerStream = new GZipStream(sHashed, CompressionMode.Compress);
                    else
                        writerStream = sHashed;
                }
                else if(m_format == KdbxFormat.PlainXml)
                    writerStream = hashedStream;
                else { Debug.Assert(false); throw new FormatException("KdbFormat"); }

            #if KeePassUAP
                XmlWriterSettings xws = new XmlWriterSettings();
                xws.Encoding = encNoBom;
                xws.Indent = true;
                xws.IndentChars = "\t";
                xws.NewLineOnAttributes = false;

                XmlWriter xw = XmlWriter.Create(writerStream, xws);
            #else
                XmlTextWriter xw = new XmlTextWriter(writerStream, encNoBom);

                xw.Formatting = Formatting.Indented;
                xw.IndentChar = '\t';
                xw.Indentation = 1;
            #endif

                m_xmlWriter = xw;

                WriteDocument(pgDataSource);

                m_xmlWriter.Flush();
                m_xmlWriter.Close();
                writerStream.Close();
            }
            finally { CommonCleanUpWrite(sSaveTo, hashedStream); }
        }
Ejemplo n.º 10
0
        // public void Save(string strFile, PwGroup pgDataSource, Kdb4Format format,
        //    IStatusLogger slLogger)
        // {
        //    bool bMadeUnhidden = UrlUtil.UnhideFile(strFile);
        //
        //    IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);
        //    this.Save(IOConnection.OpenWrite(ioc), pgDataSource, format, slLogger);
        //
        //    if(bMadeUnhidden) UrlUtil.HideFile(strFile, true); // Hide again
        // }
        /// <summary>
        /// Save the contents of the current <c>PwDatabase</c> to a KDBX file.
        /// </summary>
        /// <param name="sSaveTo">Stream to write the KDBX file into.</param>
        /// <param name="pgDataSource">Group containing all groups and
        /// entries to write. If <c>null</c>, the complete database will
        /// be written.</param>
        /// <param name="format">Format of the file to create.</param>
        /// <param name="slLogger">Logger that recieves status information.</param>
        public void Save(Stream sSaveTo, PwGroup pgDataSource, Kdb4Format format,
            IStatusLogger slLogger)
        {
            Debug.Assert(sSaveTo != null);
            if(sSaveTo == null) throw new ArgumentNullException("sSaveTo");

            m_format = format;
            m_slLogger = slLogger;

            HashingStreamEx hashedStream = new HashingStreamEx(sSaveTo, true, null);

            UTF8Encoding encNoBom = StrUtil.Utf8;
            CryptoRandom cr = CryptoRandom.Instance;

            try
            {
                m_pbMasterSeed = cr.GetRandomBytes(32);
                m_pbTransformSeed = cr.GetRandomBytes(32);
                m_pbEncryptionIV = cr.GetRandomBytes(16);

                m_pbProtectedStreamKey = cr.GetRandomBytes(32);
                m_craInnerRandomStream = CrsAlgorithm.Salsa20;
                m_randomStream = new CryptoRandomStream(m_craInnerRandomStream,
                    m_pbProtectedStreamKey);

                m_pbStreamStartBytes = cr.GetRandomBytes(32);

                Stream writerStream;
                BinaryWriter bw = null;
                if(m_format == Kdb4Format.Default)
                {
                    bw = new BinaryWriter(hashedStream, encNoBom);
                    WriteHeader(bw); // Also flushes bw

                    Stream sEncrypted = AttachStreamEncryptor(hashedStream);
                    if((sEncrypted == null) || (sEncrypted == hashedStream))
                        throw new SecurityException(KLRes.CryptoStreamFailed);

                    sEncrypted.Write(m_pbStreamStartBytes, 0, m_pbStreamStartBytes.Length);

                    Stream sHashed = new HashedBlockStream(sEncrypted, true);

                    if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
                        writerStream = new GZipStream(sHashed, CompressionMode.Compress);
                    else
                        writerStream = sHashed;
                }
                else if(m_format == Kdb4Format.PlainXml)
                    writerStream = hashedStream;
                else { Debug.Assert(false); throw new FormatException("KdbFormat"); }

                m_xmlWriter = new XmlTextWriter(writerStream, encNoBom);
                WriteDocument(pgDataSource);

                m_xmlWriter.Flush();
                m_xmlWriter.Close();
                writerStream.Close();

                GC.KeepAlive(bw);
            }
            finally { CommonCleanUpWrite(sSaveTo, hashedStream); }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Load a KDB file from a stream.
        /// </summary>
        /// <param name="sSource">Stream to read the data from. Must contain
        /// a KDB4 stream.</param>
        /// <param name="kdbFormat">Format specifier.</param>
        /// <param name="slLogger">Status logger (optional).</param>
        public void Load(Stream sSource, Kdb4Format kdbFormat, IStatusLogger slLogger)
        {
            Debug.Assert(sSource != null);
            if(sSource == null) throw new ArgumentNullException("sSource");

            m_format = kdbFormat;
            m_slLogger = slLogger;

            HashingStreamEx hashedStream = new HashingStreamEx(sSource, false, null);

            UTF8Encoding encNoBom = new UTF8Encoding(false, false);

            try
            {
                BinaryReader br = null;
                BinaryReader brDecrypted = null;
                Stream readerStream = null;

                if(kdbFormat == Kdb4Format.Default)
                {
                    br = new BinaryReader(hashedStream, encNoBom);
                    ReadHeader(br);

                    Stream sDecrypted = AttachStreamDecryptor(hashedStream);
                    if((sDecrypted == null) || (sDecrypted == hashedStream))
                        throw new SecurityException(KLRes.CryptoStreamFailed);

                    brDecrypted = new BinaryReader(sDecrypted, encNoBom);
                    byte[] pbStoredStartBytes = brDecrypted.ReadBytes(32);

                    if((pbStoredStartBytes == null) || (pbStoredStartBytes.Length != 32) ||
                        (m_pbStreamStartBytes == null) || (m_pbStreamStartBytes.Length != 32))
                    {
                        throw new InvalidDataException();
                    }

                    for(int iStart = 0; iStart < 32; ++iStart)
                    {
                        if(pbStoredStartBytes[iStart] != m_pbStreamStartBytes[iStart])
                            throw new InvalidCompositeKeyException();
                    }

                    Stream sHashed = new HashedBlockStream(sDecrypted, false);

                    if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
                        readerStream = new GZipStream(sHashed, CompressionMode.Decompress);
                    else readerStream = sHashed;
                }
                else if(kdbFormat == Kdb4Format.PlainXml)
                    readerStream = hashedStream;
                else { Debug.Assert(false); throw new FormatException("KdbFormat"); }

                if(kdbFormat != Kdb4Format.PlainXml) // Is an encrypted format
                {
                    if(m_pbProtectedStreamKey == null)
                    {
                        Debug.Assert(false);
                        throw new SecurityException("Invalid protected stream key!");
                    }

                    m_randomStream = new CryptoRandomStream(CrsAlgorithm.ArcFour, m_pbProtectedStreamKey);
                }
                else m_randomStream = null; // No random stream for plain text files

                ReadXmlStreamed(readerStream, hashedStream);
                // ReadXmlDom(readerStream);

                GC.KeepAlive(brDecrypted);
                GC.KeepAlive(br);

                CommonCleanUpRead(sSource, hashedStream);
            }
            catch(Exception)
            {
                CommonCleanUpRead(sSource, hashedStream);
                throw;
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Load a KDB file from a stream.
        /// </summary>
        /// <param name="sSource">Stream to read the data from. Must contain
        /// a KDBX stream.</param>
        /// <param name="kdbFormat">Format specifier.</param>
        /// <param name="slLogger">Status logger (optional).</param>
        public void Load(Stream sSource, KdbxFormat kdbFormat, IStatusLogger slLogger)
        {
            Debug.Assert(sSource != null);
            if(sSource == null) throw new ArgumentNullException("sSource");

            m_format = kdbFormat;
            m_slLogger = slLogger;

            HashingStreamEx hashedStream = new HashingStreamEx(sSource, false, null);

            UTF8Encoding encNoBom = StrUtil.Utf8;
            try
            {
                BinaryReaderEx br = null;
                BinaryReaderEx brDecrypted = null;
                Stream readerStream = null;

                if(kdbFormat == KdbxFormat.Default || kdbFormat == KdbxFormat.ProtocolBuffers)
                {
                    br = new BinaryReaderEx(hashedStream, encNoBom, KLRes.FileCorrupted);
                    ReadHeader(br);

                    Stream sDecrypted = AttachStreamDecryptor(hashedStream);
                    if((sDecrypted == null) || (sDecrypted == hashedStream))
                        throw new SecurityException(KLRes.CryptoStreamFailed);

                    if (m_slLogger != null)
                        m_slLogger.SetText("KP2AKEY_TransformingKey", LogStatusType.AdditionalInfo);

                    brDecrypted = new BinaryReaderEx(sDecrypted, encNoBom, KLRes.FileCorrupted);
                    byte[] pbStoredStartBytes = brDecrypted.ReadBytes(32);

                    if((m_pbStreamStartBytes == null) || (m_pbStreamStartBytes.Length != 32))
                        throw new InvalidDataException();

                    if (m_slLogger != null)
                        m_slLogger.SetText("KP2AKEY_DecodingDatabase", LogStatusType.AdditionalInfo);

                    for(int iStart = 0; iStart < 32; ++iStart)
                    {
                        if(pbStoredStartBytes[iStart] != m_pbStreamStartBytes[iStart])
                            throw new InvalidCompositeKeyException();
                    }

                    Stream sHashed = new HashedBlockStream(sDecrypted, false, 0,
                        !m_bRepairMode);

                    if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
                        readerStream = new Ionic.Zlib.GZipStream(sHashed, Ionic.Zlib.CompressionMode.Decompress);
                    else readerStream = sHashed;
                }
                else if(kdbFormat == KdbxFormat.PlainXml)
                    readerStream = hashedStream;
                else { Debug.Assert(false); throw new FormatException("KdbFormat"); }

                if(kdbFormat != KdbxFormat.PlainXml) // Is an encrypted format
                {
                    if(m_pbProtectedStreamKey == null)
                    {
                        Debug.Assert(false);
                        throw new SecurityException("Invalid protected stream key!");
                    }

                    m_randomStream = new CryptoRandomStream(m_craInnerRandomStream,
                        m_pbProtectedStreamKey);
                }
                else m_randomStream = null; // No random stream for plain-text files
                if (m_slLogger != null)
                    m_slLogger.SetText("KP2AKEY_ParsingDatabase", LogStatusType.AdditionalInfo);
                var stopWatch = Stopwatch.StartNew();

                if (kdbFormat == KdbxFormat.ProtocolBuffers)
                {
                    KdbpFile.ReadDocument(m_pwDatabase, readerStream, m_pbProtectedStreamKey, m_pbHashOfHeader);

                    Kp2aLog.Log(String.Format("KdbpFile.ReadDocument: {0}ms", stopWatch.ElapsedMilliseconds));

                }
                else
                {
                    ReadXmlStreamed(readerStream, hashedStream);

                    Kp2aLog.Log(String.Format("ReadXmlStreamed: {0}ms", stopWatch.ElapsedMilliseconds));
                }

                readerStream.Close();
                // GC.KeepAlive(br);
                // GC.KeepAlive(brDecrypted);
            }
            catch(CryptographicException) // Thrown on invalid padding
            {
                throw new CryptographicException(KLRes.FileCorrupted);
            }
            finally { CommonCleanUpRead(sSource, hashedStream); }
        }
Ejemplo n.º 13
0
        private static ProtectedString PatternGenerate(string strPattern,
                                                       bool bReturnProtected, byte[] pbAdditionalEntropy)
        {
            LinkedList <char>  vGenerated = new LinkedList <char>();
            CryptoRandomStream crs        = CreateCryptoStream(pbAdditionalEntropy);

            byte[] pbRandom   = crs.GetRandomBytes(1024);
            int    nRandomPos = 0;

            StringBuilder sb = new StringBuilder();

            for (char chAdd = '~'; chAdd < 255; ++chAdd)
            {
                sb.Append(chAdd);
            }
            string strCharSetHighANSI = sb.ToString();

            strPattern = PasswordGenerator.ExpandPattern(strPattern);
            CharStream csStream = new CharStream(strPattern);
            char       ch       = csStream.ReadChar();

            while (ch != char.MinValue)
            {
                string strCurrentCharSet = string.Empty;

                switch (ch)
                {
                case '\\':
                    ch = csStream.ReadChar();
                    if (ch == char.MinValue)                            // Backslash at the end
                    {
                        vGenerated.AddLast('\\');
                        break;
                    }

                    vGenerated.AddLast(ch);
                    break;

                case 'a': strCurrentCharSet = CharSetLower + CharSetNumeric; break;

                case 'A': strCurrentCharSet = CharSetLower + CharSetUpper +
                                              CharSetNumeric; break;

                case '\u00C2': strCurrentCharSet = CharSetUpper + CharSetNumeric; break;

                case 'c': strCurrentCharSet = CharSetLowerConsonants; break;

                case 'C': strCurrentCharSet = CharSetLowerConsonants +
                                              CharSetUpperConsonants; break;

                case '\u0108': strCurrentCharSet = CharSetUpperConsonants; break;

                case 'd': strCurrentCharSet = CharSetNumeric; break;                         // Digit

                case 'h': strCurrentCharSet = CharSetHexLower; break;

                case 'H': strCurrentCharSet = CharSetHexUpper; break;

                case 'l': strCurrentCharSet = CharSetLower; break;

                case 'L': strCurrentCharSet = CharSetLower + CharSetUpper; break;

                case '\u013D': strCurrentCharSet = CharSetUpper; break;

                case 'p': strCurrentCharSet = CharSetPunctuation; break;

                case 'v': strCurrentCharSet = CharSetLowerVowel; break;

                case 'V': strCurrentCharSet = CharSetLowerVowel +
                                              CharSetUpperVowel; break;

                case '\u0177': strCurrentCharSet = CharSetUpperVowel; break;

                case 'x': strCurrentCharSet = strCharSetHighANSI; break;

                default: vGenerated.AddLast(ch); break;
                }

                if (strCurrentCharSet.Length > 0)
                {
                    while (true)
                    {
                        byte bt = pbRandom[nRandomPos];

                        ++nRandomPos;
                        if (nRandomPos == pbRandom.Length)
                        {
                            pbRandom   = crs.GetRandomBytes(1024);
                            nRandomPos = 0;
                        }

                        if (bt < (byte)strCurrentCharSet.Length)
                        {
                            vGenerated.AddLast(strCurrentCharSet[(int)bt]);
                            break;
                        }
                    }
                }

                ch = csStream.ReadChar();
            }

            char[] vArray = new char[vGenerated.Count];
            vGenerated.CopyTo(vArray, 0);
            UTF8Encoding    utf8 = new UTF8Encoding();
            ProtectedString ps   = new ProtectedString(bReturnProtected, utf8.GetBytes(vArray));

            Array.Clear(vArray, 0, vArray.Length);
            vGenerated.Clear();
            return(ps);
        }
Ejemplo n.º 14
0
        private static ProtectedString CustomCharSetGenerate(CustomCharSet charSet, uint uPasswordLength,
                                                             bool bReturnProtected, byte[] pbAdditionalEntropy)
        {
            Debug.Assert(charSet != null); if (charSet == null)
            {
                throw new ArgumentNullException();
            }
            if (charSet.UCount == 0)
            {
                return(new ProtectedString(false, string.Empty));
            }
            if (uPasswordLength == 0)
            {
                return(new ProtectedString(false, string.Empty));
            }

            CryptoRandomStream crs = CreateCryptoStream(pbAdditionalEntropy);
            UTF8Encoding       utf8 = new UTF8Encoding();
            uint uGeneratedCount = 0, uNewCharIndex, uRandomPos = 0;

            byte[] pbRandom    = crs.GetRandomBytes(1024);
            bool   b16BitIndex = (charSet.UCount > 256);

            char[] vGenerated = new char[uPasswordLength];
            Array.Clear(vGenerated, 0, vGenerated.Length);

            while (uGeneratedCount < uPasswordLength)
            {
                uNewCharIndex = pbRandom[uRandomPos];
                ++uRandomPos;

                if (b16BitIndex)
                {
                    uNewCharIndex *= 256;
                    uNewCharIndex += pbRandom[uRandomPos];
                    ++uRandomPos;
                }

                if (uRandomPos >= (uint)pbRandom.Length)
                {
                    pbRandom   = CryptoRandom.GetRandomBytes(1024);
                    uRandomPos = 0;
                }

                if (uNewCharIndex < charSet.UCount)
                {
                    vGenerated[uGeneratedCount] = charSet[uNewCharIndex];
                    ++uGeneratedCount;
                }
            }

            if (Array.IndexOf <char>(vGenerated, char.MinValue) >= 0)
            {
                Debug.Assert(false);
                throw new System.Security.SecurityException();
            }

            byte[]          pbUTF8 = utf8.GetBytes(vGenerated);
            ProtectedString ps     = new ProtectedString(bReturnProtected, pbUTF8);

            Array.Clear(pbUTF8, 0, pbUTF8.Length);
            Array.Clear(vGenerated, 0, vGenerated.Length);
            return(ps);
        }
Ejemplo n.º 15
0
        private static int BenchTime(CrsAlgorithm cra, int nRounds, int nDataSize)
        {
            byte[] pbKey = new byte[4] { 0x00, 0x01, 0x02, 0x03 };

            int nStart = Environment.TickCount;
            for(int i = 0; i < nRounds; ++i)
            {
                CryptoRandomStream c = new CryptoRandomStream(cra, pbKey);
                c.GetRandomBytes((uint)nDataSize);
            }
            int nEnd = Environment.TickCount;

            return (nEnd - nStart);
        }
Ejemplo n.º 16
0
		// public void Save(string strFile, PwGroup pgDataSource, KdbxFormat fmt,
		//	IStatusLogger slLogger)
		// {
		//	bool bMadeUnhidden = UrlUtil.UnhideFile(strFile);
		//
		//	IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);
		//	this.Save(IOConnection.OpenWrite(ioc), pgDataSource, format, slLogger);
		//
		//	if(bMadeUnhidden) UrlUtil.HideFile(strFile, true); // Hide again
		// }

		/// <summary>
		/// Save the contents of the current <c>PwDatabase</c> to a KDBX file.
		/// </summary>
		/// <param name="sSaveTo">Stream to write the KDBX file into.</param>
		/// <param name="pgDataSource">Group containing all groups and
		/// entries to write. If <c>null</c>, the complete database will
		/// be written.</param>
		/// <param name="fmt">Format of the file to create.</param>
		/// <param name="slLogger">Logger that recieves status information.</param>
		public void Save(Stream sSaveTo, PwGroup pgDataSource, KdbxFormat fmt,
			IStatusLogger slLogger)
		{
			Debug.Assert(sSaveTo != null);
			if(sSaveTo == null) throw new ArgumentNullException("sSaveTo");

			if(m_bUsedOnce)
				throw new InvalidOperationException("Do not reuse KdbxFile objects!");
			m_bUsedOnce = true;

			m_format = fmt;
			m_slLogger = slLogger;

			PwGroup pgRoot = (pgDataSource ?? m_pwDatabase.RootGroup);
			UTF8Encoding encNoBom = StrUtil.Utf8;
			CryptoRandom cr = CryptoRandom.Instance;
			byte[] pbCipherKey = null;
			byte[] pbHmacKey64 = null;

			m_pbsBinaries.Clear();
			m_pbsBinaries.AddFrom(pgRoot);

			List<Stream> lStreams = new List<Stream>();
			lStreams.Add(sSaveTo);

			HashingStreamEx sHashing = new HashingStreamEx(sSaveTo, true, null);
			lStreams.Add(sHashing);

			try
			{
				m_uFileVersion = GetMinKdbxVersion();

				int cbEncKey, cbEncIV;
				ICipherEngine iCipher = GetCipher(out cbEncKey, out cbEncIV);

				m_pbMasterSeed = cr.GetRandomBytes(32);
				m_pbEncryptionIV = cr.GetRandomBytes((uint)cbEncIV);

				// m_pbTransformSeed = cr.GetRandomBytes(32);
				PwUuid puKdf = m_pwDatabase.KdfParameters.KdfUuid;
				KdfEngine kdf = KdfPool.Get(puKdf);
				if(kdf == null)
					throw new Exception(KLRes.UnknownKdf + MessageService.NewParagraph +
						// KLRes.FileNewVerOrPlgReq + MessageService.NewParagraph +
						"UUID: " + puKdf.ToHexString() + ".");
				kdf.Randomize(m_pwDatabase.KdfParameters);

				if(m_format == KdbxFormat.Default)
				{
					if(m_uFileVersion < FileVersion32_4)
					{
						m_craInnerRandomStream = CrsAlgorithm.Salsa20;
						m_pbInnerRandomStreamKey = cr.GetRandomBytes(32);
					}
					else // KDBX >= 4
					{
						m_craInnerRandomStream = CrsAlgorithm.ChaCha20;
						m_pbInnerRandomStreamKey = cr.GetRandomBytes(64);
					}

					m_randomStream = new CryptoRandomStream(m_craInnerRandomStream,
						m_pbInnerRandomStreamKey);
				}

				if(m_uFileVersion < FileVersion32_4)
					m_pbStreamStartBytes = cr.GetRandomBytes(32);

				Stream sXml;
				if(m_format == KdbxFormat.Default)
				{
					byte[] pbHeader = GenerateHeader();
					m_pbHashOfHeader = CryptoUtil.HashSha256(pbHeader);

					MemUtil.Write(sHashing, pbHeader);
					sHashing.Flush();

					ComputeKeys(out pbCipherKey, cbEncKey, out pbHmacKey64);

					Stream sPlain;
					if(m_uFileVersion < FileVersion32_4)
					{
						Stream sEncrypted = EncryptStream(sHashing, iCipher,
							pbCipherKey, cbEncIV, true);
						if((sEncrypted == null) || (sEncrypted == sHashing))
							throw new SecurityException(KLRes.CryptoStreamFailed);
						lStreams.Add(sEncrypted);

						MemUtil.Write(sEncrypted, m_pbStreamStartBytes);

						sPlain = new HashedBlockStream(sEncrypted, true);
					}
					else // KDBX >= 4
					{
						// For integrity checking (without knowing the master key)
						MemUtil.Write(sHashing, m_pbHashOfHeader);

						byte[] pbHeaderHmac = ComputeHeaderHmac(pbHeader, pbHmacKey64);
						MemUtil.Write(sHashing, pbHeaderHmac);

						Stream sBlocks = new HmacBlockStream(sHashing, true,
							true, pbHmacKey64);
						lStreams.Add(sBlocks);

						sPlain = EncryptStream(sBlocks, iCipher, pbCipherKey,
							cbEncIV, true);
						if((sPlain == null) || (sPlain == sBlocks))
							throw new SecurityException(KLRes.CryptoStreamFailed);
					}
					lStreams.Add(sPlain);

					if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
					{
						sXml = new GZipStream(sPlain, CompressionMode.Compress);
						lStreams.Add(sXml);
					}
					else sXml = sPlain;

					if(m_uFileVersion >= FileVersion32_4)
						WriteInnerHeader(sXml); // Binary header before XML
				}
				else if(m_format == KdbxFormat.PlainXml)
					sXml = sHashing;
				else
				{
					Debug.Assert(false);
					throw new ArgumentOutOfRangeException("fmt");
				}

#if KeePassUAP
				XmlWriterSettings xws = new XmlWriterSettings();
				xws.Encoding = encNoBom;
				xws.Indent = true;
				xws.IndentChars = "\t";
				xws.NewLineOnAttributes = false;

				XmlWriter xw = XmlWriter.Create(sXml, xws);
#else
				XmlTextWriter xw = new XmlTextWriter(sXml, encNoBom);

				xw.Formatting = Formatting.Indented;
				xw.IndentChar = '\t';
				xw.Indentation = 1;
#endif
				m_xmlWriter = xw;

				WriteDocument(pgRoot);

				m_xmlWriter.Flush();
				m_xmlWriter.Close();
			}
			finally
			{
				if(pbCipherKey != null) MemUtil.ZeroByteArray(pbCipherKey);
				if(pbHmacKey64 != null) MemUtil.ZeroByteArray(pbHmacKey64);

				CommonCleanUpWrite(lStreams, sHashing);
			}
		}
Ejemplo n.º 17
0
		/// <summary>
		/// Read the protected string 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 string 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 string.</returns>
		/// <exception cref="System.ArgumentNullException">Thrown if the input
		/// parameter is <c>null</c>.</exception>
		public byte[] ReadXorredString(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 // Not using XorredBuffer
			{
				byte[] pbData = ReadUtf8();
				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;
			}
		}
Ejemplo n.º 18
0
        // public void Save(string strFile, PwGroup pgDataSource, KdbxFormat format,
        //    IStatusLogger slLogger)
        // {
        //    bool bMadeUnhidden = UrlUtil.UnhideFile(strFile);
        //
        //    IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);
        //    this.Save(IOConnection.OpenWrite(ioc), pgDataSource, format, slLogger);
        //
        //    if(bMadeUnhidden) UrlUtil.HideFile(strFile, true); // Hide again
        // }
        /// <summary>
        /// Save the contents of the current <c>PwDatabase</c> to a KDBX file.
        /// </summary>
        /// <param name="sSaveTo">Stream to write the KDBX file into.</param>
        /// <param name="pgDataSource">Group containing all groups and
        /// entries to write. If <c>null</c>, the complete database will
        /// be written.</param>
        /// <param name="format">Format of the file to create.</param>
        /// <param name="slLogger">Logger that recieves status information.</param>
        public void Save(Stream sSaveTo, PwGroup pgDataSource, KdbxFormat format,
			IStatusLogger slLogger)
        {
            Debug.Assert(sSaveTo != null);
            if(sSaveTo == null) throw new ArgumentNullException("sSaveTo");

            m_format = format;
            m_slLogger = slLogger;

            HashingStreamEx hashedStream = new HashingStreamEx(sSaveTo, true, null);

            UTF8Encoding encNoBom = StrUtil.Utf8;
            CryptoRandom cr = CryptoRandom.Instance;

            try
            {
                m_pbMasterSeed = cr.GetRandomBytes(32);
                m_pbTransformSeed = cr.GetRandomBytes(32);
                m_pbEncryptionIV = cr.GetRandomBytes(16);

                m_pbProtectedStreamKey = cr.GetRandomBytes(32);
                m_craInnerRandomStream = CrsAlgorithm.Salsa20;
                m_randomStream = new CryptoRandomStream(m_craInnerRandomStream,
                    m_pbProtectedStreamKey);

                m_pbStreamStartBytes = cr.GetRandomBytes(32);

                Stream writerStream;
                if(m_format == KdbxFormat.Default || m_format == KdbxFormat.ProtocolBuffers)
                {
                    WriteHeader(hashedStream); // Also flushes the stream

                    Stream sEncrypted = AttachStreamEncryptor(hashedStream);
                    if((sEncrypted == null) || (sEncrypted == hashedStream))
                        throw new SecurityException(KLRes.CryptoStreamFailed);

                    sEncrypted.Write(m_pbStreamStartBytes, 0, m_pbStreamStartBytes.Length);

                    Stream sHashed = new HashedBlockStream(sEncrypted, true);

                    if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
                        writerStream = new Ionic.Zlib.GZipStream(sHashed, Ionic.Zlib.CompressionMode.Compress);
                    else
                        writerStream = sHashed;
                }
                else if(m_format == KdbxFormat.PlainXml)
                    writerStream = hashedStream;
                else { Debug.Assert(false); throw new FormatException("KdbFormat"); }

                var stopWatch = Stopwatch.StartNew();

                if (m_format == KdbxFormat.ProtocolBuffers)
                {
                    KdbpFile.WriteDocument(m_pwDatabase, writerStream, m_pbProtectedStreamKey, m_pbHashOfHeader);
                }
                else
                {
                    m_xmlWriter = new XmlTextWriter(writerStream, encNoBom);
                    WriteDocument(pgDataSource);

                    m_xmlWriter.Flush();
                    m_xmlWriter.Close();
                }

                writerStream.Close();

                Kp2aLog.Log(String.Format("{1}: {0}ms", stopWatch.ElapsedMilliseconds, m_format == KdbxFormat.ProtocolBuffers ? "KdbpFile.WriteDocument" : "Xml WriteDocument"));
            }
            finally { CommonCleanUpWrite(sSaveTo, hashedStream); }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Load a KDB file from a stream.
        /// </summary>
        /// <param name="sSource">Stream to read the data from. Must contain
        /// a KDBX stream.</param>
        /// <param name="kdbFormat">Format specifier.</param>
        /// <param name="slLogger">Status logger (optional).</param>
        public void Load(Stream sSource, KdbxFormat kdbFormat, IStatusLogger slLogger)
        {
            Debug.Assert(sSource != null);
            if(sSource == null) throw new ArgumentNullException("sSource");

            m_format = kdbFormat;
            m_slLogger = slLogger;

            HashingStreamEx hashedStream = new HashingStreamEx(sSource, false, null);

            UTF8Encoding encNoBom = StrUtil.Utf8;
            try
            {
                BinaryReaderEx br = null;
                BinaryReaderEx brDecrypted = null;
                Stream readerStream = null;

                if(kdbFormat == KdbxFormat.Default)
                {
                    br = new BinaryReaderEx(hashedStream, encNoBom, KLRes.FileCorrupted);
                    ReadHeader(br);

                    Stream sDecrypted = AttachStreamDecryptor(hashedStream);
                    if((sDecrypted == null) || (sDecrypted == hashedStream))
                        throw new SecurityException(KLRes.CryptoStreamFailed);

                    brDecrypted = new BinaryReaderEx(sDecrypted, encNoBom, KLRes.FileCorrupted);
                    byte[] pbStoredStartBytes = brDecrypted.ReadBytes(32);

                    if((m_pbStreamStartBytes == null) || (m_pbStreamStartBytes.Length != 32))
                        throw new InvalidDataException();

                    for(int iStart = 0; iStart < 32; ++iStart)
                    {
                        if(pbStoredStartBytes[iStart] != m_pbStreamStartBytes[iStart])
                            throw new InvalidCompositeKeyException();
                    }

                    Stream sHashed = new HashedBlockStream(sDecrypted, false, 0,
                        !m_bRepairMode);

                    if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
                        readerStream = new GZipStream(sHashed, CompressionMode.Decompress);
                    else readerStream = sHashed;
                }
                else if(kdbFormat == KdbxFormat.PlainXml)
                    readerStream = hashedStream;
                else { Debug.Assert(false); throw new FormatException("KdbFormat"); }

                if(kdbFormat != KdbxFormat.PlainXml) // Is an encrypted format
                {
                    if(m_pbProtectedStreamKey == null)
                    {
                        Debug.Assert(false);
                        throw new SecurityException("Invalid protected stream key!");
                    }

                    m_randomStream = new CryptoRandomStream(m_craInnerRandomStream,
                        m_pbProtectedStreamKey);
                }
                else m_randomStream = null; // No random stream for plain-text files

            #if KeePassDebug_WriteXml
                // FileStream fsOut = new FileStream("Raw.xml", FileMode.Create,
                //	FileAccess.Write, FileShare.None);
                // try
                // {
                //	while(true)
                //	{
                //		int b = readerStream.ReadByte();
                //		if(b == -1) break;
                //		fsOut.WriteByte((byte)b);
                //	}
                // }
                // catch(Exception) { }
                // fsOut.Close();
            #endif

                ReadXmlStreamed(readerStream, hashedStream);
                // ReadXmlDom(readerStream);

                readerStream.Close();
                // GC.KeepAlive(br);
                // GC.KeepAlive(brDecrypted);
            }
            catch(CryptographicException) // Thrown on invalid padding
            {
                throw new CryptographicException(KLRes.FileCorrupted);
            }
            finally { CommonCleanUpRead(sSource, hashedStream); }
        }
Ejemplo n.º 20
0
		/// <summary>
		/// Load a KDBX file from a stream.
		/// </summary>
		/// <param name="sSource">Stream to read the data from. Must contain
		/// a KDBX stream.</param>
		/// <param name="fmt">Format.</param>
		/// <param name="slLogger">Status logger (optional).</param>
		public void Load(Stream sSource, KdbxFormat fmt, IStatusLogger slLogger)
		{
			Debug.Assert(sSource != null);
			if(sSource == null) throw new ArgumentNullException("sSource");

			if(m_bUsedOnce)
				throw new InvalidOperationException("Do not reuse KdbxFile objects!");
			m_bUsedOnce = true;

#if KDBX_BENCHMARK
			Stopwatch swTime = Stopwatch.StartNew();
#endif

			m_format = fmt;
			m_slLogger = slLogger;

			m_pbsBinaries.Clear();

			UTF8Encoding encNoBom = StrUtil.Utf8;
			byte[] pbCipherKey = null;
			byte[] pbHmacKey64 = null;

			List<Stream> lStreams = new List<Stream>();
			lStreams.Add(sSource);

			HashingStreamEx sHashing = new HashingStreamEx(sSource, false, null);
			lStreams.Add(sHashing);

			try
			{
				Stream sXml;
				if(fmt == KdbxFormat.Default)
				{
					BinaryReaderEx br = new BinaryReaderEx(sHashing,
						encNoBom, KLRes.FileCorrupted);
					byte[] pbHeader = LoadHeader(br);
					m_pbHashOfHeader = CryptoUtil.HashSha256(pbHeader);

					int cbEncKey, cbEncIV;
					ICipherEngine iCipher = GetCipher(out cbEncKey, out cbEncIV);

					ComputeKeys(out pbCipherKey, cbEncKey, out pbHmacKey64);

					string strIncomplete = KLRes.FileHeaderCorrupted + " " +
						KLRes.FileIncomplete;

					Stream sPlain;
					if(m_uFileVersion < FileVersion32_4)
					{
						Stream sDecrypted = EncryptStream(sHashing, iCipher,
							pbCipherKey, cbEncIV, false);
						if((sDecrypted == null) || (sDecrypted == sHashing))
							throw new SecurityException(KLRes.CryptoStreamFailed);
						lStreams.Add(sDecrypted);

						BinaryReaderEx brDecrypted = new BinaryReaderEx(sDecrypted,
							encNoBom, strIncomplete);
						byte[] pbStoredStartBytes = brDecrypted.ReadBytes(32);

						if((m_pbStreamStartBytes == null) || (m_pbStreamStartBytes.Length != 32))
							throw new EndOfStreamException(strIncomplete);
						if(!MemUtil.ArraysEqual(pbStoredStartBytes, m_pbStreamStartBytes))
							throw new InvalidCompositeKeyException();

						sPlain = new HashedBlockStream(sDecrypted, false, 0, !m_bRepairMode);
					}
					else // KDBX >= 4
					{
						byte[] pbStoredHash = MemUtil.Read(sHashing, 32);
						if((pbStoredHash == null) || (pbStoredHash.Length != 32))
							throw new EndOfStreamException(strIncomplete);
						if(!MemUtil.ArraysEqual(m_pbHashOfHeader, pbStoredHash))
							throw new InvalidDataException(KLRes.FileHeaderCorrupted);

						byte[] pbHeaderHmac = ComputeHeaderHmac(pbHeader, pbHmacKey64);
						byte[] pbStoredHmac = MemUtil.Read(sHashing, 32);
						if((pbStoredHmac == null) || (pbStoredHmac.Length != 32))
							throw new EndOfStreamException(strIncomplete);
						if(!MemUtil.ArraysEqual(pbHeaderHmac, pbStoredHmac))
							throw new InvalidCompositeKeyException();

						HmacBlockStream sBlocks = new HmacBlockStream(sHashing,
							false, !m_bRepairMode, pbHmacKey64);
						lStreams.Add(sBlocks);

						sPlain = EncryptStream(sBlocks, iCipher, pbCipherKey,
							cbEncIV, false);
						if((sPlain == null) || (sPlain == sBlocks))
							throw new SecurityException(KLRes.CryptoStreamFailed);
					}
					lStreams.Add(sPlain);

					if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
					{
						sXml = new GZipStream(sPlain, CompressionMode.Decompress);
						lStreams.Add(sXml);
					}
					else sXml = sPlain;

					if(m_uFileVersion >= FileVersion32_4)
						LoadInnerHeader(sXml); // Binary header before XML
				}
				else if(fmt == KdbxFormat.PlainXml)
					sXml = sHashing;
				else { Debug.Assert(false); throw new ArgumentOutOfRangeException("fmt"); }

				if(fmt == KdbxFormat.Default)
				{
					if(m_pbInnerRandomStreamKey == null)
					{
						Debug.Assert(false);
						throw new SecurityException("Invalid inner random stream key!");
					}

					m_randomStream = new CryptoRandomStream(m_craInnerRandomStream,
						m_pbInnerRandomStreamKey);
				}

#if KeePassDebug_WriteXml
				// FileStream fsOut = new FileStream("Raw.xml", FileMode.Create,
				//	FileAccess.Write, FileShare.None);
				// try
				// {
				//	while(true)
				//	{
				//		int b = sXml.ReadByte();
				//		if(b == -1) break;
				//		fsOut.WriteByte((byte)b);
				//	}
				// }
				// catch(Exception) { }
				// fsOut.Close();
#endif

				ReadXmlStreamed(sXml, sHashing);
				// ReadXmlDom(sXml);
			}
			catch(CryptographicException) // Thrown on invalid padding
			{
				throw new CryptographicException(KLRes.FileCorrupted);
			}
			finally
			{
				if(pbCipherKey != null) MemUtil.ZeroByteArray(pbCipherKey);
				if(pbHmacKey64 != null) MemUtil.ZeroByteArray(pbHmacKey64);

				CommonCleanUpRead(lStreams, sHashing);
			}

#if KDBX_BENCHMARK
			swTime.Stop();
			MessageService.ShowInfo("Loading KDBX took " +
				swTime.ElapsedMilliseconds.ToString() + " ms.");
#endif
		}