Пример #1
0
        public override void Import(PwDatabase pwStorage, Stream sInput,
                                    IStatusLogger slLogger)
        {
            if (m_dAutoTypeConv == null)
            {
                Dictionary <string, string> d = new Dictionary <string, string>();

                d[@"{login}"]          = @"{USERNAME}";
                d[@"{password}"]       = @"{PASSWORD}";
                d[@"{additional key}"] = @"{S:" + Password2Key + @"}";
                d[@"{url}"]            = @"{URL}";
                d[@"{memo}"]           = @"{NOTES}";
                d[@"[tab]"]            = @"{TAB}";
                d[@"[enter]"]          = @"{ENTER}";

                m_dAutoTypeConv = d;
            }

            MemoryStream ms = new MemoryStream();

            MemUtil.CopyStream(sInput, ms);
            byte[] pbData = ms.ToArray();
            ms.Close();

            string strFmt = KLRes.FileLoadFailed + StrUtil.NewParagraph +
                            KPRes.NoEncNoCompress;

            // The file must start with "<?xml"
            if ((pbData.Length < 6) || (pbData[0] != 0x3C) || (pbData[1] != 0x3F) ||
                (pbData[2] != 0x78) || (pbData[3] != 0x6D) || (pbData[4] != 0x6C))
            {
                throw new FormatException(strFmt);
            }

            string strData = Encoding.Default.GetString(pbData);

            strData = strData.Replace(@"&", @"&amp;");

            byte[] pbDataUtf8 = StrUtil.Utf8.GetBytes(strData);
            ms = new MemoryStream(pbDataUtf8, false);
            StreamReader sr = new StreamReader(ms, StrUtil.Utf8);

            XmlDocument xmlDoc = XmlUtilEx.CreateXmlDocument();

            xmlDoc.Load(sr);

            XmlNode xmlRoot = xmlDoc.DocumentElement;

            foreach (XmlNode xmlChild in xmlRoot.ChildNodes)
            {
                if (xmlChild.Name == ElemGroup)
                {
                    ReadGroup(xmlChild, pwStorage.RootGroup, pwStorage);
                }
                else if (xmlChild.Name == ElemEntry)
                {
                    ReadEntry(xmlChild, pwStorage.RootGroup, pwStorage);
                }
                else if (xmlChild.Name == ElemUnsupp0)
                {
                }
                else
                {
                    Debug.Assert(false);
                }
            }
        }
Пример #2
0
        public bool EqualsEntry(PwEntry pe, PwCompareOptions pwOpt,
                                MemProtCmpMode mpCmpStr)
        {
            if (pe == null)
            {
                Debug.Assert(false); return(false);
            }

            bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) !=
                             PwCompareOptions.None);
            bool bIgnoreLastAccess = ((pwOpt & PwCompareOptions.IgnoreLastAccess) !=
                                      PwCompareOptions.None);
            bool bIgnoreLastMod = ((pwOpt & PwCompareOptions.IgnoreLastMod) !=
                                   PwCompareOptions.None);

            if (!m_uuid.Equals(pe.m_uuid))
            {
                return(false);
            }
            if ((pwOpt & PwCompareOptions.IgnoreParentGroup) == PwCompareOptions.None)
            {
                if (m_pParentGroup != pe.m_pParentGroup)
                {
                    return(false);
                }
                if (!bIgnoreLastMod && !TimeUtil.EqualsFloor(m_tParentGroupLastMod,
                                                             pe.m_tParentGroupLastMod))
                {
                    return(false);
                }
                if (!m_puPrevParentGroup.Equals(pe.m_puPrevParentGroup))
                {
                    return(false);
                }
            }

            if (!m_dStrings.EqualsDictionary(pe.m_dStrings, pwOpt, mpCmpStr))
            {
                return(false);
            }
            if (!m_dBinaries.EqualsDictionary(pe.m_dBinaries))
            {
                return(false);
            }

            if (!m_cfgAutoType.Equals(pe.m_cfgAutoType))
            {
                return(false);
            }

            if ((pwOpt & PwCompareOptions.IgnoreHistory) == PwCompareOptions.None)
            {
                bool bIgnoreLastBackup = ((pwOpt & PwCompareOptions.IgnoreLastBackup) !=
                                          PwCompareOptions.None);

                if (!bIgnoreLastBackup && (m_lHistory.UCount != pe.m_lHistory.UCount))
                {
                    return(false);
                }
                if (bIgnoreLastBackup && (m_lHistory.UCount == 0))
                {
                    Debug.Assert(false);
                    return(false);
                }
                if (bIgnoreLastBackup && ((m_lHistory.UCount - 1) != pe.m_lHistory.UCount))
                {
                    return(false);
                }

                PwCompareOptions cmpSub = PwCompareOptions.IgnoreParentGroup;
                if (bNeEqStd)
                {
                    cmpSub |= PwCompareOptions.NullEmptyEquivStd;
                }
                if (bIgnoreLastMod)
                {
                    cmpSub |= PwCompareOptions.IgnoreLastMod;
                }
                if (bIgnoreLastAccess)
                {
                    cmpSub |= PwCompareOptions.IgnoreLastAccess;
                }

                for (uint uHist = 0; uHist < pe.m_lHistory.UCount; ++uHist)
                {
                    if (!m_lHistory.GetAt(uHist).EqualsEntry(pe.m_lHistory.GetAt(
                                                                 uHist), cmpSub, MemProtCmpMode.None))
                    {
                        return(false);
                    }
                }
            }

            if (m_pwIcon != pe.m_pwIcon)
            {
                return(false);
            }
            if (!m_puCustomIcon.Equals(pe.m_puCustomIcon))
            {
                return(false);
            }

            if (m_clrForeground != pe.m_clrForeground)
            {
                return(false);
            }
            if (m_clrBackground != pe.m_clrBackground)
            {
                return(false);
            }

            if (!TimeUtil.EqualsFloor(m_tCreation, pe.m_tCreation))
            {
                return(false);
            }
            if (!bIgnoreLastMod && !TimeUtil.EqualsFloor(m_tLastMod, pe.m_tLastMod))
            {
                return(false);
            }
            if (!bIgnoreLastAccess && !TimeUtil.EqualsFloor(m_tLastAccess, pe.m_tLastAccess))
            {
                return(false);
            }
            if (!TimeUtil.EqualsFloor(m_tExpire, pe.m_tExpire))
            {
                return(false);
            }
            if (m_bExpires != pe.m_bExpires)
            {
                return(false);
            }
            if (!bIgnoreLastAccess && (m_uUsageCount != pe.m_uUsageCount))
            {
                return(false);
            }

            if (m_strOverrideUrl != pe.m_strOverrideUrl)
            {
                return(false);
            }
            if (m_bQualityCheck != pe.m_bQualityCheck)
            {
                return(false);
            }

            // The Tags property normalizes
            if (!MemUtil.ListsEqual <string>(this.Tags, pe.Tags))
            {
                return(false);
            }

            if (!m_dCustomData.Equals(pe.m_dCustomData))
            {
                return(false);
            }

            return(true);
        }
Пример #3
0
        public string[] ReadLine()
        {
            char chFirst = m_sChars.PeekChar();

            if (chFirst == char.MinValue)
            {
                return(null);
            }

            List <string> v       = new List <string>();
            StringBuilder sb      = new StringBuilder();
            bool          bInText = false;

            char chFS = m_opt.FieldSeparator, chRS = m_opt.RecordSeparator;
            char chTQ = m_opt.TextQualifier;

            while (true)
            {
                char ch = m_sChars.ReadChar();
                if (ch == char.MinValue)
                {
                    break;
                }

                Debug.Assert(ch != '\r');                 // Was normalized to Unix "\n"

                if ((ch == '\\') && m_opt.BackslashIsEscape)
                {
                    char chEsc = m_sChars.ReadChar();
                    if (chEsc == char.MinValue)
                    {
                        break;
                    }

                    if (chEsc == 'n')
                    {
                        sb.Append('\n');
                    }
                    else if (chEsc == 'r')
                    {
                        sb.Append('\r');
                    }
                    else if (chEsc == 't')
                    {
                        sb.Append('\t');
                    }
                    else if (chEsc == 'u')
                    {
                        char chNum1 = m_sChars.ReadChar();
                        char chNum2 = m_sChars.ReadChar();
                        char chNum3 = m_sChars.ReadChar();
                        char chNum4 = m_sChars.ReadChar();
                        if (chNum4 != char.MinValue)                        // Implies the others
                        {
                            StringBuilder sbNum = new StringBuilder();
                            sbNum.Append(chNum3);                             // Little-endian
                            sbNum.Append(chNum4);
                            sbNum.Append(chNum1);
                            sbNum.Append(chNum2);

                            byte[] pbNum = MemUtil.HexStringToByteArray(sbNum.ToString());
                            ushort usNum = MemUtil.BytesToUInt16(pbNum);

                            sb.Append((char)usNum);
                        }
                    }
                    else
                    {
                        sb.Append(chEsc);
                    }
                }
                else if (ch == chTQ)
                {
                    if (!bInText)
                    {
                        bInText = true;
                    }
                    else                     // bInText
                    {
                        char chNext = m_sChars.PeekChar();
                        if (chNext == chTQ)
                        {
                            m_sChars.ReadChar();
                            sb.Append(chTQ);
                        }
                        else
                        {
                            bInText = false;
                        }
                    }
                }
                else if ((ch == chRS) && !bInText)
                {
                    break;
                }
                else if (bInText)
                {
                    sb.Append(ch);
                }
                else if (ch == chFS)
                {
                    AddField(v, sb.ToString());
                    if (sb.Length > 0)
                    {
                        sb.Remove(0, sb.Length);
                    }
                }
                else
                {
                    sb.Append(ch);
                }
            }
            // Debug.Assert(!bInText);
            AddField(v, sb.ToString());

            return(v.ToArray());
        }
Пример #4
0
        private bool CreateCompositeKey()
        {
            m_pKey = new CompositeKey();

            if (m_cbPassword.Checked)            // Use a password
            {
                byte[] pb = m_tbPassword.TextEx.ReadUtf8();
                try
                {
                    m_pKey.AddUserKey(new KcpPassword(pb,
                                                      Program.Config.Security.MasterPassword.RememberWhileOpen));
                }
                finally { MemUtil.ZeroByteArray(pb); }
            }

            string strKeyFile = m_cmbKeyFile.Text;

            Debug.Assert(strKeyFile != null); if (strKeyFile == null)
            {
                strKeyFile = string.Empty;
            }
            bool bIsProvKey = Program.KeyProviderPool.IsKeyProvider(strKeyFile);

            if (m_cbKeyFile.Checked && !strKeyFile.Equals(KPRes.NoKeyFileSpecifiedMeta) &&
                !bIsProvKey)
            {
                if (!ValidateKeyFile())
                {
                    return(false);
                }

                try { m_pKey.AddUserKey(new KcpKeyFile(strKeyFile)); }
                catch (Exception)
                {
                    MessageService.ShowWarning(strKeyFile, KPRes.KeyFileError);
                    return(false);
                }
            }
            else if (m_cbKeyFile.Checked && !strKeyFile.Equals(KPRes.NoKeyFileSpecifiedMeta) &&
                     bIsProvKey)
            {
                KeyProvider kp = Program.KeyProviderPool.Get(strKeyFile);
                if ((kp != null) && m_bSecureDesktop)
                {
                    if (!kp.SecureDesktopCompatible)
                    {
                        MessageService.ShowWarning(KPRes.KeyProvIncmpWithSD,
                                                   KPRes.KeyProvIncmpWithSDHint);
                        return(false);
                    }
                }

                KeyProviderQueryContext ctxKP = new KeyProviderQueryContext(
                    m_ioInfo, false, m_bSecureDesktop);

                bool   bPerformHash;
                byte[] pbProvKey = Program.KeyProviderPool.GetKey(strKeyFile, ctxKP,
                                                                  out bPerformHash);
                if ((pbProvKey != null) && (pbProvKey.Length > 0))
                {
                    try { m_pKey.AddUserKey(new KcpCustomKey(strKeyFile, pbProvKey, bPerformHash)); }
                    catch (Exception exCKP)
                    {
                        MessageService.ShowWarning(exCKP);
                        return(false);
                    }

                    MemUtil.ZeroByteArray(pbProvKey);
                }
                else
                {
                    return(false);                 // Provider has shown error message
                }
            }

            if (m_cbUserAccount.Checked)
            {
                try { m_pKey.AddUserKey(new KcpUserAccount()); }
                catch (Exception exUA)
                {
                    MessageService.ShowWarning(exUA);
                    return(false);
                }
            }

            return(true);
        }
Пример #5
0
 public ulong GetRandomUInt64()
 {
     byte[] pb = GetRandomBytes(8);
     return(MemUtil.BytesToUInt64(pb));
 }
Пример #6
0
        private bool ReadSafeBlock()
        {
            if (m_bEos)
            {
                return(false);                   // End of stream reached already
            }
            byte[] pbStoredHmac = MemUtil.Read(m_sBase, 32);
            if ((pbStoredHmac == null) || (pbStoredHmac.Length != 32))
            {
                throw new EndOfStreamException(KLRes.FileCorrupted + " " +
                                               KLRes.FileIncomplete);
            }

            // Block index is implicit: it's used in the HMAC computation,
            // but does not need to be stored
            // byte[] pbBlockIndex = MemUtil.Read(m_sBase, 8);
            // if((pbBlockIndex == null) || (pbBlockIndex.Length != 8))
            //	throw new EndOfStreamException();
            // ulong uBlockIndex = MemUtil.BytesToUInt64(pbBlockIndex);
            // if((uBlockIndex != m_uBlockIndex) && m_bVerify)
            //	throw new InvalidDataException();
            byte[] pbBlockIndex = MemUtil.UInt64ToBytes(m_uBlockIndex);

            byte[] pbBlockSize = MemUtil.Read(m_sBase, 4);
            if ((pbBlockSize == null) || (pbBlockSize.Length != 4))
            {
                throw new EndOfStreamException(KLRes.FileCorrupted + " " +
                                               KLRes.FileIncomplete);
            }
            int nBlockSize = MemUtil.BytesToInt32(pbBlockSize);

            if (nBlockSize < 0)
            {
                throw new InvalidDataException(KLRes.FileCorrupted);
            }

            m_iBufferPos = 0;

            SetBuffer(MemUtil.Read(m_sBase, nBlockSize));
            if ((m_pbBuffer == null) || ((m_pbBuffer.Length != nBlockSize) && m_bVerify))
            {
                throw new EndOfStreamException(KLRes.FileCorrupted + " " +
                                               KLRes.FileIncompleteExpc);
            }

            if (m_bVerify)
            {
                byte[] pbCmpHmac;
                byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex);
                using (HMACSHA256 h = new HMACSHA256(pbBlockKey))
                {
                    h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length,
                                     pbBlockIndex, 0);
                    h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length,
                                     pbBlockSize, 0);

                    if (m_pbBuffer.Length != 0)
                    {
                        h.TransformBlock(m_pbBuffer, 0, m_pbBuffer.Length,
                                         m_pbBuffer, 0);
                    }

                    h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);

                    pbCmpHmac = h.Hash;
                }
                MemUtil.ZeroByteArray(pbBlockKey);

                if (!MemUtil.ArraysEqual(pbCmpHmac, pbStoredHmac))
                {
                    throw new InvalidDataException(KLRes.FileCorrupted);
                }
            }

            ++m_uBlockIndex;

            if (nBlockSize == 0)
            {
                m_bEos = true;
                return(false);                // No further data available
            }
            return(true);
        }
Пример #7
0
        private static void ExtractFile(byte[] pbData, string strTmpRoot,
                                        PlgxPluginInfo plgx)
        {
            MemoryStream ms = new MemoryStream(pbData, false);
            BinaryReader br = new BinaryReader(ms);

            string strPath = null;

            byte[] pbContent = null;

            while (true)
            {
                KeyValuePair <ushort, byte[]> kvp = ReadObject(br);

                if (kvp.Key == PlgxfEOF)
                {
                    break;
                }
                else if (kvp.Key == PlgxfPath)
                {
                    strPath = StrUtil.Utf8.GetString(kvp.Value);
                }
                else if (kvp.Key == PlgxfData)
                {
                    pbContent = kvp.Value;
                }
                else
                {
                    Debug.Assert(false);
                }
            }

            br.Close();
            ms.Close();

            if (!string.IsNullOrEmpty(strPath) && (pbContent != null))
            {
                string strTmpFile = UrlUtil.EnsureTerminatingSeparator(strTmpRoot,
                                                                       false) + UrlUtil.ConvertSeparators(strPath);

                string strTmpDir = UrlUtil.GetFileDirectory(strTmpFile, false, true);
                if (!Directory.Exists(strTmpDir))
                {
                    Directory.CreateDirectory(strTmpDir);
                }

                byte[] pbDecompressed = MemUtil.Decompress(pbContent);
                File.WriteAllBytes(strTmpFile, pbDecompressed);

                // Although the temporary directory will be deleted recursively
                // anyway, add the extracted file here manually, in order to
                // minimize left-over files in case the recursive deletion fails
                // due to locked / in-use files
                Program.TempFilesPool.Add(strTmpFile);

                if (plgx.LogStream != null)
                {
                    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
                    byte[] pbMD5 = md5.ComputeHash(pbDecompressed);
                    plgx.LogStream.Write(MemUtil.ByteArrayToHexString(pbMD5));
                    plgx.LogStream.WriteLine(" " + strPath);
                }
            }
            else
            {
                Debug.Assert(false);
            }
        }
Пример #8
0
        private byte[] LoadHeader(BinaryReaderEx br)
        {
            string strPrevExcpText = br.ReadExceptionText;

            br.ReadExceptionText = KLRes.FileHeaderCorrupted + " " +
                                   KLRes.FileIncompleteExpc;

            MemoryStream msHeader = new MemoryStream();

            Debug.Assert(br.CopyDataTo == null);
            br.CopyDataTo = msHeader;

            byte[] pbSig1 = br.ReadBytes(4);
            uint   uSig1  = MemUtil.BytesToUInt32(pbSig1);

            byte[] pbSig2 = br.ReadBytes(4);
            uint   uSig2  = MemUtil.BytesToUInt32(pbSig2);

            if ((uSig1 == FileSignatureOld1) && (uSig2 == FileSignatureOld2))
            {
                throw new OldFormatException(PwDefs.ShortProductName + @" 1.x",
                                             OldFormatException.OldFormatType.KeePass1x);
            }

            if ((uSig1 == FileSignature1) && (uSig2 == FileSignature2))
            {
            }
            else if ((uSig1 == FileSignaturePreRelease1) && (uSig2 ==
                                                             FileSignaturePreRelease2))
            {
            }
            else
            {
                throw new FormatException(KLRes.FileSigInvalid);
            }

            byte[] pb       = br.ReadBytes(4);
            uint   uVersion = MemUtil.BytesToUInt32(pb);

            if ((uVersion & FileVersionCriticalMask) > (FileVersion32 & FileVersionCriticalMask))
            {
                throw new FormatException(KLRes.FileVersionUnsupported +
                                          Environment.NewLine + KLRes.FileNewVerReq);
            }
            m_uFileVersion = uVersion;

            while (true)
            {
                if (!ReadHeaderField(br))
                {
                    break;
                }
            }

            br.CopyDataTo = null;
            byte[] pbHeader = msHeader.ToArray();
            msHeader.Dispose();

            br.ReadExceptionText = strPrevExcpText;
            return(pbHeader);
        }
Пример #9
0
        private bool ReadHeaderField(BinaryReaderEx brSource)
        {
            Debug.Assert(brSource != null);
            if (brSource == null)
            {
                throw new ArgumentNullException("brSource");
            }

            byte btFieldID = brSource.ReadByte();

            int cbSize;

            Debug.Assert(m_uFileVersion > 0);
            if (m_uFileVersion < FileVersion32_4)
            {
                cbSize = (int)MemUtil.BytesToUInt16(brSource.ReadBytes(2));
            }
            else
            {
                cbSize = MemUtil.BytesToInt32(brSource.ReadBytes(4));
            }
            if (cbSize < 0)
            {
                throw new FormatException(KLRes.FileCorrupted);
            }

            byte[] pbData = MemUtil.EmptyByteArray;
            if (cbSize > 0)
            {
                pbData = brSource.ReadBytes(cbSize);
            }

            bool bResult            = true;
            KdbxHeaderFieldID kdbID = (KdbxHeaderFieldID)btFieldID;

            switch (kdbID)
            {
            case KdbxHeaderFieldID.EndOfHeader:
                bResult = false;                         // Returning false indicates end of header
                break;

            case KdbxHeaderFieldID.CipherID:
                SetCipher(pbData);
                break;

            case KdbxHeaderFieldID.CompressionFlags:
                SetCompressionFlags(pbData);
                break;

            case KdbxHeaderFieldID.MasterSeed:
                m_pbMasterSeed = pbData;
                CryptoRandom.Instance.AddEntropy(pbData);
                break;

            // Obsolete; for backward compatibility only
            case KdbxHeaderFieldID.TransformSeed:
                Debug.Assert(m_uFileVersion < FileVersion32_4);

                AesKdf kdfS = new AesKdf();
                if (!m_pwDatabase.KdfParameters.KdfUuid.Equals(kdfS.Uuid))
                {
                    m_pwDatabase.KdfParameters = kdfS.GetDefaultParameters();
                }

                // m_pbTransformSeed = pbData;
                m_pwDatabase.KdfParameters.SetByteArray(AesKdf.ParamSeed, pbData);

                CryptoRandom.Instance.AddEntropy(pbData);
                break;

            // Obsolete; for backward compatibility only
            case KdbxHeaderFieldID.TransformRounds:
                Debug.Assert(m_uFileVersion < FileVersion32_4);

                AesKdf kdfR = new AesKdf();
                if (!m_pwDatabase.KdfParameters.KdfUuid.Equals(kdfR.Uuid))
                {
                    m_pwDatabase.KdfParameters = kdfR.GetDefaultParameters();
                }

                // m_pwDatabase.KeyEncryptionRounds = MemUtil.BytesToUInt64(pbData);
                m_pwDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds,
                                                     MemUtil.BytesToUInt64(pbData));
                break;

            case KdbxHeaderFieldID.EncryptionIV:
                m_pbEncryptionIV = pbData;
                break;

            case KdbxHeaderFieldID.InnerRandomStreamKey:
                Debug.Assert(m_uFileVersion < FileVersion32_4);
                Debug.Assert(m_pbInnerRandomStreamKey == null);
                m_pbInnerRandomStreamKey = pbData;
                CryptoRandom.Instance.AddEntropy(pbData);
                break;

            case KdbxHeaderFieldID.StreamStartBytes:
                Debug.Assert(m_uFileVersion < FileVersion32_4);
                m_pbStreamStartBytes = pbData;
                break;

            case KdbxHeaderFieldID.InnerRandomStreamID:
                Debug.Assert(m_uFileVersion < FileVersion32_4);
                SetInnerRandomStreamID(pbData);
                break;

            case KdbxHeaderFieldID.KdfParameters:
                m_pwDatabase.KdfParameters = KdfParameters.DeserializeExt(pbData);
                break;

            case KdbxHeaderFieldID.PublicCustomData:
                Debug.Assert(m_pwDatabase.PublicCustomData.Count == 0);
                m_pwDatabase.PublicCustomData = VariantDictionary.Deserialize(pbData);
                break;

            default:
                Debug.Assert(false);
                if (m_slLogger != null)
                {
                    m_slLogger.SetText(KLRes.UnknownHeaderId + @": " +
                                       kdbID.ToString() + "!", LogStatusType.Warning);
                }
                break;
            }

            return(bResult);
        }
Пример #10
0
        private bool ReadHeaderField(BinaryReaderEx brSource)
        {
            Debug.Assert(brSource != null);
            if (brSource == null)
            {
                throw new ArgumentNullException("brSource");
            }

            byte   btFieldID = brSource.ReadByte();
            ushort uSize     = MemUtil.BytesToUInt16(brSource.ReadBytes(2));

            byte[] pbData = null;
            if (uSize > 0)
            {
                string strPrevExcpText = brSource.ReadExceptionText;
                brSource.ReadExceptionText = KLRes.FileHeaderEndEarly;

                pbData = brSource.ReadBytes(uSize);

                brSource.ReadExceptionText = strPrevExcpText;
            }

            bool bResult            = true;
            KdbxHeaderFieldID kdbID = (KdbxHeaderFieldID)btFieldID;

            switch (kdbID)
            {
            case KdbxHeaderFieldID.EndOfHeader:
                bResult = false;     // Returning false indicates end of header
                break;

            case KdbxHeaderFieldID.CipherID:
                SetCipher(pbData);
                break;

            case KdbxHeaderFieldID.CompressionFlags:
                SetCompressionFlags(pbData);
                break;

            case KdbxHeaderFieldID.MasterSeed:
                m_pbMasterSeed = pbData;
                CryptoRandom.Instance.AddEntropy(pbData);
                break;

            case KdbxHeaderFieldID.TransformSeed:
                m_pbTransformSeed = pbData;
                CryptoRandom.Instance.AddEntropy(pbData);
                break;

            case KdbxHeaderFieldID.TransformRounds:
                m_pwDatabase.KeyEncryptionRounds = MemUtil.BytesToUInt64(pbData);
                break;

            case KdbxHeaderFieldID.EncryptionIV:
                m_pbEncryptionIV = pbData;
                break;

            case KdbxHeaderFieldID.ProtectedStreamKey:
                m_pbProtectedStreamKey = pbData;
                CryptoRandom.Instance.AddEntropy(pbData);
                break;

            case KdbxHeaderFieldID.StreamStartBytes:
                m_pbStreamStartBytes = pbData;
                break;

            case KdbxHeaderFieldID.InnerRandomStreamID:
                SetInnerRandomStreamID(pbData);
                break;

            default:
                Debug.Assert(false);
                if (m_slLogger != null)
                {
                    m_slLogger.SetText(KLRes.UnknownHeaderId + @": " +
                                       kdbID.ToString() + "!", LogStatusType.Warning);
                }
                break;
            }

            return(bResult);
        }
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            _design.ApplyDialogTheme();
            SetContentView(Resource.Layout.group_edit);

            ImageButton iconButton = (ImageButton)FindViewById(Resource.Id.icon_button);

            iconButton.Click += (sender, e) =>
            {
                IconPickerActivity.Launch(this);
            };
            _selectedIconId = (int)PwIcon.FolderOpen;

            iconButton.SetImageDrawable(App.Kp2a.GetDb().DrawableFactory.GetIconDrawable(this, App.Kp2a.GetDb().KpDatabase, (PwIcon)_selectedIconId, null, true));

            Button okButton = (Button)FindViewById(Resource.Id.ok);

            okButton.Click += (sender, e) => {
                TextView nameField = (TextView)FindViewById(Resource.Id.group_name);
                String   name      = nameField.Text;

                if (name.Length > 0)
                {
                    Intent intent = new Intent();

                    intent.PutExtra(KeyName, name);
                    intent.PutExtra(KeyIconId, _selectedIconId);
                    if (_selectedCustomIconId != null)
                    {
                        intent.PutExtra(KeyCustomIconId, MemUtil.ByteArrayToHexString(_selectedCustomIconId.UuidBytes));
                    }
                    if (_groupToEdit != null)
                    {
                        intent.PutExtra(KeyGroupUuid, MemUtil.ByteArrayToHexString(_groupToEdit.Uuid.UuidBytes));
                    }

                    SetResult(Result.Ok, intent);

                    Finish();
                }
                else
                {
                    Toast.MakeText(this, Resource.String.error_no_name, ToastLength.Long).Show();
                }
            };

            if (Intent.HasExtra(KeyGroupUuid))
            {
                string groupUuid = Intent.Extras.GetString(KeyGroupUuid);
                _groupToEdit          = App.Kp2a.GetDb().Groups[new PwUuid(MemUtil.HexStringToByteArray(groupUuid))];
                _selectedIconId       = (int)_groupToEdit.IconId;
                _selectedCustomIconId = _groupToEdit.CustomIconUuid;
                TextView nameField = (TextView)FindViewById(Resource.Id.group_name);
                nameField.Text = _groupToEdit.Name;
                App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iconButton, this, App.Kp2a.GetDb().KpDatabase, _groupToEdit.IconId, _groupToEdit.CustomIconUuid, false);
                SetTitle(Resource.String.edit_group_title);
            }
            else
            {
                SetTitle(Resource.String.add_group_title);
            }



            Button cancel = (Button)FindViewById(Resource.Id.cancel);

            cancel.Click += (sender, e) => {
                Intent intent = new Intent();
                SetResult(Result.Canceled, intent);

                Finish();
            };
        }
Пример #12
0
        public static VariantDictionary Deserialize(byte[] pb)
        {
            if (pb == null)
            {
                Debug.Assert(false); return(null);
            }

            VariantDictionary d = new VariantDictionary();

            using (MemoryStream ms = new MemoryStream(pb, false))
            {
                ushort uVersion = MemUtil.BytesToUInt16(MemUtil.Read(ms, 2));
                if ((uVersion & VdmCritical) > (VdVersion & VdmCritical))
                {
                    throw new FormatException(KLRes.FileNewVerReq);
                }

                while (true)
                {
                    int iType = ms.ReadByte();
                    if (iType < 0)
                    {
                        throw new EndOfStreamException(KLRes.FileCorrupted);
                    }
                    byte btType = (byte)iType;
                    if (btType == (byte)VdType.None)
                    {
                        break;
                    }

                    int    cbName = MemUtil.BytesToInt32(MemUtil.Read(ms, 4));
                    byte[] pbName = MemUtil.Read(ms, cbName);
                    if (pbName.Length != cbName)
                    {
                        throw new EndOfStreamException(KLRes.FileCorrupted);
                    }
                    string strName = StrUtil.Utf8.GetString(pbName);

                    int    cbValue = MemUtil.BytesToInt32(MemUtil.Read(ms, 4));
                    byte[] pbValue = MemUtil.Read(ms, cbValue);
                    if (pbValue.Length != cbValue)
                    {
                        throw new EndOfStreamException(KLRes.FileCorrupted);
                    }

                    switch (btType)
                    {
                    case (byte)VdType.UInt32:
                        if (cbValue == 4)
                        {
                            d.SetUInt32(strName, MemUtil.BytesToUInt32(pbValue));
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                        break;

                    case (byte)VdType.UInt64:
                        if (cbValue == 8)
                        {
                            d.SetUInt64(strName, MemUtil.BytesToUInt64(pbValue));
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                        break;

                    case (byte)VdType.Bool:
                        if (cbValue == 1)
                        {
                            d.SetBool(strName, (pbValue[0] != 0));
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                        break;

                    case (byte)VdType.Int32:
                        if (cbValue == 4)
                        {
                            d.SetInt32(strName, MemUtil.BytesToInt32(pbValue));
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                        break;

                    case (byte)VdType.Int64:
                        if (cbValue == 8)
                        {
                            d.SetInt64(strName, MemUtil.BytesToInt64(pbValue));
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                        break;

                    case (byte)VdType.String:
                        d.SetString(strName, StrUtil.Utf8.GetString(pbValue));
                        break;

                    case (byte)VdType.ByteArray:
                        d.SetByteArray(strName, pbValue);
                        break;

                    default:
                        Debug.Assert(false);                                 // Unknown type
                        break;
                    }
                }

                Debug.Assert(ms.ReadByte() < 0);
            }

            return(d);
        }
Пример #13
0
        public static byte[] Serialize(VariantDictionary p)
        {
            if (p == null)
            {
                Debug.Assert(false); return(null);
            }

            byte[] pbRet;
            using (MemoryStream ms = new MemoryStream())
            {
                MemUtil.Write(ms, MemUtil.UInt16ToBytes(VdVersion));

                foreach (KeyValuePair <string, object> kvp in p.m_d)
                {
                    string strName = kvp.Key;
                    if (string.IsNullOrEmpty(strName))
                    {
                        Debug.Assert(false); continue;
                    }
                    byte[] pbName = StrUtil.Utf8.GetBytes(strName);

                    object o = kvp.Value;
                    if (o == null)
                    {
                        Debug.Assert(false); continue;
                    }

                    Type   t       = o.GetType();
                    VdType vt      = VdType.None;
                    byte[] pbValue = null;
                    if (t == typeof(uint))
                    {
                        vt      = VdType.UInt32;
                        pbValue = MemUtil.UInt32ToBytes((uint)o);
                    }
                    else if (t == typeof(ulong))
                    {
                        vt      = VdType.UInt64;
                        pbValue = MemUtil.UInt64ToBytes((ulong)o);
                    }
                    else if (t == typeof(bool))
                    {
                        vt         = VdType.Bool;
                        pbValue    = new byte[1];
                        pbValue[0] = ((bool)o ? (byte)1 : (byte)0);
                    }
                    else if (t == typeof(int))
                    {
                        vt      = VdType.Int32;
                        pbValue = MemUtil.Int32ToBytes((int)o);
                    }
                    else if (t == typeof(long))
                    {
                        vt      = VdType.Int64;
                        pbValue = MemUtil.Int64ToBytes((long)o);
                    }
                    else if (t == typeof(string))
                    {
                        vt      = VdType.String;
                        pbValue = StrUtil.Utf8.GetBytes((string)o);
                    }
                    else if (t == typeof(byte[]))
                    {
                        vt      = VdType.ByteArray;
                        pbValue = (byte[])o;
                    }
                    else
                    {
                        Debug.Assert(false); continue;
                    }                                                           // Unknown type

                    ms.WriteByte((byte)vt);
                    MemUtil.Write(ms, MemUtil.Int32ToBytes(pbName.Length));
                    MemUtil.Write(ms, pbName);
                    MemUtil.Write(ms, MemUtil.Int32ToBytes(pbValue.Length));
                    MemUtil.Write(ms, pbValue);
                }

                ms.WriteByte((byte)VdType.None);
                pbRet = ms.ToArray();
            }

            return(pbRet);
        }
Пример #14
0
        public static StrEncodingInfo GetStringEncoding(byte[] pbData,
                                                        out uint uStartOffset)
        {
            if (pbData == null)
            {
                Debug.Assert(false); throw new ArgumentNullException("pbData");
            }

            uStartOffset = 0;

            List <StrEncodingInfo> lEncs = new List <StrEncodingInfo>(StrUtil.Encodings);

            lEncs.Sort(BinaryDataClassifier.CompareBySigLengthRev);

            foreach (StrEncodingInfo sei in lEncs)
            {
                byte[] pbSig = sei.StartSignature;
                if ((pbSig == null) || (pbSig.Length == 0))
                {
                    continue;
                }
                if (pbSig.Length > pbData.Length)
                {
                    continue;
                }

                byte[] pbStart = MemUtil.Mid <byte>(pbData, 0, pbSig.Length);
                if (MemUtil.ArraysEqual(pbStart, pbSig))
                {
                    uStartOffset = (uint)pbSig.Length;
                    return(sei);
                }
            }

            if ((pbData.Length % 4) == 0)
            {
                byte[] z3 = new byte[] { 0, 0, 0 };
                int    i  = MemUtil.IndexOf <byte>(pbData, z3);
                if ((i >= 0) && (i < (pbData.Length - 4)))                // Ignore last zero char
                {
                    if ((i % 4) == 0)
                    {
                        return(StrUtil.GetEncoding(StrEncodingType.Utf32BE));
                    }
                    if ((i % 4) == 1)
                    {
                        return(StrUtil.GetEncoding(StrEncodingType.Utf32LE));
                    }
                    // Don't assume UTF-32 for other offsets
                }
            }

            if ((pbData.Length % 2) == 0)
            {
                int i = Array.IndexOf <byte>(pbData, 0);
                if ((i >= 0) && (i < (pbData.Length - 2)))                // Ignore last zero char
                {
                    if ((i % 2) == 0)
                    {
                        return(StrUtil.GetEncoding(StrEncodingType.Utf16BE));
                    }
                    return(StrUtil.GetEncoding(StrEncodingType.Utf16LE));
                }
            }

            try
            {
                UTF8Encoding utf8Throw = new UTF8Encoding(false, true);
                utf8Throw.GetString(pbData);
                return(StrUtil.GetEncoding(StrEncodingType.Utf8));
            }
            catch (Exception) { }

            return(StrUtil.GetEncoding(StrEncodingType.Default));
        }
Пример #15
0
        private byte[] GetSystemEntropy()
        {
            SHA512Managed h = new SHA512Managed();

            byte[] pb4 = new byte[4];
            byte[] pb8 = new byte[8];

            GAction <byte[], bool> f = delegate(byte[] pbValue, bool bClearValue)
            {
                if (pbValue == null)
                {
                    Debug.Assert(false); return;
                }
                if (pbValue.Length == 0)
                {
                    return;
                }
                h.TransformBlock(pbValue, 0, pbValue.Length, pbValue, 0);
                if (bClearValue)
                {
                    MemUtil.ZeroByteArray(pbValue);
                }
            };
            Action <int> fI32 = delegate(int iValue)
            {
                MemUtil.Int32ToBytesEx(iValue, pb4, 0);
                f(pb4, false);
            };
            Action <long> fI64 = delegate(long lValue)
            {
                MemUtil.Int64ToBytesEx(lValue, pb8, 0);
                f(pb8, false);
            };
            Action <string> fStr = delegate(string strValue)
            {
                if (strValue == null)
                {
                    Debug.Assert(false); return;
                }
                if (strValue.Length == 0)
                {
                    return;
                }
                f(StrUtil.Utf8.GetBytes(strValue), false);
            };

            fI32(Environment.TickCount);
            fI64(DateTime.UtcNow.ToBinary());

#if !KeePassLibSD
            // In try-catch for systems without GUI;
            // https://sourceforge.net/p/keepass/discussion/329221/thread/20335b73/
            try
            {
                Point pt = Cursor.Position;
                fI32(pt.X);
                fI32(pt.Y);
            }
            catch (Exception) { Debug.Assert(NativeLib.IsUnix()); }
#endif

            try
            {
                fI32((int)NativeLib.GetPlatformID());
#if KeePassUAP
                fStr(EnvironmentExt.OSVersion.VersionString);
#else
                fStr(Environment.OSVersion.VersionString);
#endif

                fI32(Environment.ProcessorCount);

#if !KeePassUAP
                fStr(Environment.CommandLine);
                fI64(Environment.WorkingSet);
#endif
            }
            catch (Exception) { Debug.Assert(false); }

            try
            {
                foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
                {
                    fStr(de.Key as string);
                    fStr(de.Value as string);
                }
            }
            catch (Exception) { Debug.Assert(false); }

            try
            {
#if KeePassUAP
                f(DiagnosticsExt.GetProcessEntropy(), true);
#elif !KeePassLibSD
                using (Process p = Process.GetCurrentProcess())
                {
                    fI64(p.Handle.ToInt64());
                    fI32(p.HandleCount);
                    fI32(p.Id);
                    fI64(p.NonpagedSystemMemorySize64);
                    fI64(p.PagedMemorySize64);
                    fI64(p.PagedSystemMemorySize64);
                    fI64(p.PeakPagedMemorySize64);
                    fI64(p.PeakVirtualMemorySize64);
                    fI64(p.PeakWorkingSet64);
                    fI64(p.PrivateMemorySize64);
                    fI64(p.StartTime.ToBinary());
                    fI64(p.VirtualMemorySize64);
                    fI64(p.WorkingSet64);

                    // Not supported in Mono 1.2.6:
                    // fI32(p.SessionId);
                }
#endif
            }
            catch (Exception) { Debug.Assert(NativeLib.IsUnix()); }

            try
            {
                CultureInfo ci = CultureInfo.CurrentCulture;
                if (ci != null)
                {
                    fI32(ci.GetHashCode());
                }
                else
                {
                    Debug.Assert(false);
                }
            }
            catch (Exception) { Debug.Assert(false); }

            f(Guid.NewGuid().ToByteArray(), false);
            f(GetCspRandom(), true);

            h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
            byte[] pbHash = h.Hash;
            h.Clear();
            MemUtil.ZeroByteArray(pb4);
            MemUtil.ZeroByteArray(pb8);
            return(pbHash);
        }
Пример #16
0
        private bool ReadInnerHeaderField(BinaryReaderEx br)
        {
            Debug.Assert(br != null);
            if (br == null)
            {
                throw new ArgumentNullException("br");
            }

            byte btFieldID = br.ReadByte();

            int cbSize = MemUtil.BytesToInt32(br.ReadBytes(4));

            if (cbSize < 0)
            {
                throw new FormatException(KLRes.FileCorrupted);
            }

            byte[] pbData = MemUtil.EmptyByteArray;
            if (cbSize > 0)
            {
                pbData = br.ReadBytes(cbSize);
            }

            bool bResult = true;
            KdbxInnerHeaderFieldID kdbID = (KdbxInnerHeaderFieldID)btFieldID;

            switch (kdbID)
            {
            case KdbxInnerHeaderFieldID.EndOfHeader:
                bResult = false;                         // Returning false indicates end of header
                break;

            case KdbxInnerHeaderFieldID.InnerRandomStreamID:
                SetInnerRandomStreamID(pbData);
                break;

            case KdbxInnerHeaderFieldID.InnerRandomStreamKey:
                Debug.Assert(m_pbInnerRandomStreamKey == null);
                m_pbInnerRandomStreamKey = pbData;
                CryptoRandom.Instance.AddEntropy(pbData);
                break;

            case KdbxInnerHeaderFieldID.Binary:
                if (pbData.Length < 1)
                {
                    throw new FormatException();
                }
                KdbxBinaryFlags f     = (KdbxBinaryFlags)pbData[0];
                bool            bProt = ((f & KdbxBinaryFlags.Protected) != KdbxBinaryFlags.None);

                ProtectedBinary pb = new ProtectedBinary(bProt, pbData,
                                                         1, pbData.Length - 1);
                m_pbsBinaries.Add(pb);

                if (bProt)
                {
                    MemUtil.ZeroByteArray(pbData);
                }
                break;

            default:
                Debug.Assert(false);
                break;
            }

            return(bResult);
        }
Пример #17
0
        private void SetBuffer(byte[] pb)
        {
            MemUtil.ZeroByteArray(m_pbBuffer);             // Erase previous buffer

            m_pbBuffer = pb;
        }
Пример #18
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);
            }
#if !ModernKeePassLib
            catch (CryptographicException)            // Thrown on invalid padding
            {
                throw new CryptographicException(KLRes.FileCorrupted);
            }
#endif
            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
        }
Пример #19
0
        private static string ReadFile(BinaryReader br, PlgxPluginInfo plgx,
                                       IStatusLogger slStatus)
        {
            uint uSig1    = br.ReadUInt32();
            uint uSig2    = br.ReadUInt32();
            uint uVersion = br.ReadUInt32();

            if ((uSig1 != PlgxSignature1) || (uSig2 != PlgxSignature2))
            {
                return(null);                // Ignore file, don't throw
            }
            if ((uVersion & PlgxVersionMask) > (PlgxVersion & PlgxVersionMask))
            {
                throw new PlgxException(KLRes.FileVersionUnsupported);
            }

            string strPluginPath = null;
            string strTmpRoot = null;
            bool?  bContent = null;
            string strBuildPre = null, strBuildPost = null;

            while (true)
            {
                KeyValuePair <ushort, byte[]> kvp = ReadObject(br);

                if (kvp.Key == PlgxEOF)
                {
                    break;
                }
                else if (kvp.Key == PlgxFileUuid)
                {
                    plgx.FileUuid = new PwUuid(kvp.Value);
                }
                else if (kvp.Key == PlgxBaseFileName)
                {
                    plgx.BaseFileName = StrUtil.Utf8.GetString(kvp.Value);
                }
                else if (kvp.Key == PlgxCreationTime)
                {
                }                                                        // Ignore
                else if (kvp.Key == PlgxGeneratorName)
                {
                }
                else if (kvp.Key == PlgxGeneratorVersion)
                {
                }
                else if (kvp.Key == PlgxPrereqKP)
                {
                    ulong uReq = MemUtil.BytesToUInt64(kvp.Value);
                    if (uReq > PwDefs.FileVersion64)
                    {
                        throw new PlgxException(KLRes.FileNewVerReq);
                    }
                }
                else if (kvp.Key == PlgxPrereqNet)
                {
                    ulong uReq  = MemUtil.BytesToUInt64(kvp.Value);
                    ulong uInst = WinUtil.GetMaxNetFrameworkVersion();
                    if ((uInst != 0) && (uReq > uInst))
                    {
                        throw new PlgxException(KPRes.NewerNetRequired);
                    }
                }
                else if (kvp.Key == PlgxPrereqOS)
                {
                    string strOS  = "," + WinUtil.GetOSStr() + ",";
                    string strReq = "," + StrUtil.Utf8.GetString(kvp.Value) + ",";
                    if (strReq.IndexOf(strOS, StrUtil.CaseIgnoreCmp) < 0)
                    {
                        throw new PlgxException(KPRes.PluginOperatingSystemUnsupported);
                    }
                }
                else if (kvp.Key == PlgxPrereqPtr)
                {
                    uint uReq = MemUtil.BytesToUInt32(kvp.Value);
                    if (uReq > (uint)IntPtr.Size)
                    {
                        throw new PlgxException(KPRes.PluginOperatingSystemUnsupported);
                    }
                }
                else if (kvp.Key == PlgxBuildPre)
                {
                    strBuildPre = StrUtil.Utf8.GetString(kvp.Value);
                }
                else if (kvp.Key == PlgxBuildPost)
                {
                    strBuildPost = StrUtil.Utf8.GetString(kvp.Value);
                }
                else if (kvp.Key == PlgxBeginContent)
                {
                    if (bContent.HasValue)
                    {
                        throw new PlgxException(KLRes.FileCorrupted);
                    }

                    string strCached = PlgxCache.GetCacheFile(plgx, true, false);
                    if (!string.IsNullOrEmpty(strCached) && plgx.AllowCached)
                    {
                        strPluginPath = strCached;
                        break;
                    }

                    if (slStatus != null)
                    {
                        slStatus.SetText(KPRes.PluginsCompilingAndLoading,
                                         LogStatusType.Info);
                    }

                    bContent = true;
                    if (plgx.LogStream != null)
                    {
                        plgx.LogStream.WriteLine("Content:");
                    }
                }
                else if (kvp.Key == PlgxFile)
                {
                    if (!bContent.HasValue || !bContent.Value)
                    {
                        throw new PlgxException(KLRes.FileCorrupted);
                    }

                    if (strTmpRoot == null)
                    {
                        strTmpRoot = CreateTempDirectory();
                    }
                    ExtractFile(kvp.Value, strTmpRoot, plgx);
                }
                else if (kvp.Key == PlgxEndContent)
                {
                    if (!bContent.HasValue || !bContent.Value)
                    {
                        throw new PlgxException(KLRes.FileCorrupted);
                    }

                    bContent = false;
                }
                else
                {
                    Debug.Assert(false);
                }
            }

            if ((strPluginPath == null) && plgx.AllowCompile)
            {
                strPluginPath = Compile(strTmpRoot, plgx, strBuildPre, strBuildPost);
            }

            return(strPluginPath);
        }
Пример #20
0
        private byte[] GenerateHeader()
        {
            byte[] pbHeader;
            using (MemoryStream ms = new MemoryStream())
            {
                MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileSignature1));
                MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileSignature2));
                MemUtil.Write(ms, MemUtil.UInt32ToBytes(m_uFileVersion));

                WriteHeaderField(ms, KdbxHeaderFieldID.CipherID,
                                 m_pwDatabase.DataCipherUuid.UuidBytes);

                int nCprID = (int)m_pwDatabase.Compression;
                WriteHeaderField(ms, KdbxHeaderFieldID.CompressionFlags,
                                 MemUtil.UInt32ToBytes((uint)nCprID));

                WriteHeaderField(ms, KdbxHeaderFieldID.MasterSeed, m_pbMasterSeed);

                if (m_uFileVersion < FileVersion32_4)
                {
                    Debug.Assert(m_pwDatabase.KdfParameters.KdfUuid.Equals(
                                     (new AesKdf()).Uuid));
                    WriteHeaderField(ms, KdbxHeaderFieldID.TransformSeed,
                                     m_pwDatabase.KdfParameters.GetByteArray(AesKdf.ParamSeed));
                    WriteHeaderField(ms, KdbxHeaderFieldID.TransformRounds,
                                     MemUtil.UInt64ToBytes(m_pwDatabase.KdfParameters.GetUInt64(
                                                               AesKdf.ParamRounds, PwDefs.DefaultKeyEncryptionRounds)));
                }
                else
                {
                    WriteHeaderField(ms, KdbxHeaderFieldID.KdfParameters,
                                     KdfParameters.SerializeExt(m_pwDatabase.KdfParameters));
                }

                if (m_pbEncryptionIV.Length > 0)
                {
                    WriteHeaderField(ms, KdbxHeaderFieldID.EncryptionIV, m_pbEncryptionIV);
                }

                if (m_uFileVersion < FileVersion32_4)
                {
                    WriteHeaderField(ms, KdbxHeaderFieldID.InnerRandomStreamKey,
                                     m_pbInnerRandomStreamKey);

                    WriteHeaderField(ms, KdbxHeaderFieldID.StreamStartBytes,
                                     m_pbStreamStartBytes);

                    int nIrsID = (int)m_craInnerRandomStream;
                    WriteHeaderField(ms, KdbxHeaderFieldID.InnerRandomStreamID,
                                     MemUtil.Int32ToBytes(nIrsID));
                }

                // Write public custom data only when there is at least one item,
                // because KDBX 3.1 didn't support this field yet
                if (m_pwDatabase.PublicCustomData.Count > 0)
                {
                    WriteHeaderField(ms, KdbxHeaderFieldID.PublicCustomData,
                                     VariantDictionary.Serialize(m_pwDatabase.PublicCustomData));
                }

                WriteHeaderField(ms, KdbxHeaderFieldID.EndOfHeader, new byte[] {
                    (byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n'
                });

                pbHeader = ms.ToArray();
            }

            return(pbHeader);
        }
Пример #21
0
        private static void CreateFromDirectory(string strDirPath)
        {
            string strPlgx = strDirPath + "." + PlgxExtension;

            PlgxPluginInfo plgx = new PlgxPluginInfo(false, true, true);

            PlgxCsprojLoader.LoadDefault(strDirPath, plgx);

            FileStream fs = new FileStream(strPlgx, FileMode.Create,
                                           FileAccess.Write, FileShare.None);
            BinaryWriter bw = new BinaryWriter(fs);

            bw.Write(PlgxSignature1);
            bw.Write(PlgxSignature2);
            bw.Write(PlgxVersion);
            WriteObject(bw, PlgxFileUuid, (new PwUuid(true)).UuidBytes);
            WriteObject(bw, PlgxBaseFileName, StrUtil.Utf8.GetBytes(
                            plgx.BaseFileName));
            WriteObject(bw, PlgxCreationTime, StrUtil.Utf8.GetBytes(
                            TimeUtil.SerializeUtc(DateTime.Now)));
            WriteObject(bw, PlgxGeneratorName, StrUtil.Utf8.GetBytes(
                            PwDefs.ShortProductName));
            WriteObject(bw, PlgxGeneratorVersion, MemUtil.UInt64ToBytes(
                            PwDefs.FileVersion64));

            string strKP = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxPrereqKP];

            if (!string.IsNullOrEmpty(strKP))
            {
                ulong uKP = StrUtil.ParseVersion(strKP);
                if (uKP != 0)
                {
                    WriteObject(bw, PlgxPrereqKP, MemUtil.UInt64ToBytes(uKP));
                }
            }

            string strNet = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxPrereqNet];

            if (!string.IsNullOrEmpty(strNet))
            {
                ulong uNet = StrUtil.ParseVersion(strNet);
                if (uNet != 0)
                {
                    WriteObject(bw, PlgxPrereqNet, MemUtil.UInt64ToBytes(uNet));
                }
            }

            string strOS = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxPrereqOS];

            if (!string.IsNullOrEmpty(strOS))
            {
                WriteObject(bw, PlgxPrereqOS, StrUtil.Utf8.GetBytes(strOS));
            }

            string strPtr = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxPrereqPtr];

            if (!string.IsNullOrEmpty(strPtr))
            {
                uint uPtr;
                if (uint.TryParse(strPtr, out uPtr))
                {
                    WriteObject(bw, PlgxPrereqPtr, MemUtil.UInt32ToBytes(uPtr));
                }
            }

            string strBuildPre = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxBuildPre];

            if (!string.IsNullOrEmpty(strBuildPre))
            {
                WriteObject(bw, PlgxBuildPre, StrUtil.Utf8.GetBytes(strBuildPre));
            }

            string strBuildPost = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxBuildPost];

            if (!string.IsNullOrEmpty(strBuildPost))
            {
                WriteObject(bw, PlgxBuildPost, StrUtil.Utf8.GetBytes(strBuildPost));
            }

            WriteObject(bw, PlgxBeginContent, null);

            RecursiveFileAdd(bw, strDirPath, new DirectoryInfo(strDirPath));

            WriteObject(bw, PlgxEndContent, null);
            WriteObject(bw, PlgxEOF, null);

            bw.Close();
            fs.Close();

            // Test loading not possible, because MainForm not available
            // PlgxPlugin.Load(strPlgx);
        }
Пример #22
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;
            m_xmlWriter = null;

            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
            {
                // Fix history entries (should not be necessary; just for safety,
                // as e.g. XPath searches depend on correct history entry UUIDs)
                if (m_pwDatabase.MaintainBackups())
                {
                    Debug.Assert(false);
                }

                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");
                }

                m_xmlWriter = XmlUtilEx.CreateXmlWriter(sXml);

                WriteDocument(pgRoot);

                m_xmlWriter.Flush();
            }
            finally
            {
                CommonCleanUpWrite(lStreams, sHashing);

                if (pbCipherKey != null)
                {
                    MemUtil.ZeroByteArray(pbCipherKey);
                }
                if (pbHmacKey64 != null)
                {
                    MemUtil.ZeroByteArray(pbHmacKey64);
                }
            }
        }
Пример #23
0
        /// <summary>
        /// Create a cryptographic key of length <paramref name="cbOut" />
        /// (in bytes) from <paramref name="pbIn" />.
        /// </summary>
        public static byte[] ResizeKey(byte[] pbIn, int iInOffset,
                                       int cbIn, int cbOut)
        {
            if (pbIn == null)
            {
                throw new ArgumentNullException("pbIn");
            }
            if (cbOut < 0)
            {
                throw new ArgumentOutOfRangeException("cbOut");
            }

            if (cbOut == 0)
            {
                return(MemUtil.EmptyByteArray);
            }

            byte[] pbHash;
            if (cbOut <= 32)
            {
                pbHash = HashSha256(pbIn, iInOffset, cbIn);
            }
            else
            {
                using (SHA512Managed h = new SHA512Managed())
                {
                    pbHash = h.ComputeHash(pbIn, iInOffset, cbIn);
                }
            }

            if (cbOut == pbHash.Length)
            {
                return(pbHash);
            }

            byte[] pbRet = new byte[cbOut];
            if (cbOut < pbHash.Length)
            {
                Array.Copy(pbHash, pbRet, cbOut);
            }
            else
            {
                int   iPos = 0;
                ulong r    = 0;
                while (iPos < cbOut)
                {
                    Debug.Assert(pbHash.Length == 64);
                    using (HMACSHA256 h = new HMACSHA256(pbHash))
                    {
                        byte[] pbR    = MemUtil.UInt64ToBytes(r);
                        byte[] pbPart = h.ComputeHash(pbR);

                        int cbCopy = Math.Min(cbOut - iPos, pbPart.Length);
                        Debug.Assert(cbCopy > 0);

                        Array.Copy(pbPart, 0, pbRet, iPos, cbCopy);
                        iPos += cbCopy;
                        ++r;

                        MemUtil.ZeroByteArray(pbPart);
                    }
                }
                Debug.Assert(iPos == cbOut);
            }

#if DEBUG
            byte[] pbZero = new byte[pbHash.Length];
            Debug.Assert(!MemUtil.ArraysEqual(pbHash, pbZero));
#endif
            MemUtil.ZeroByteArray(pbHash);
            return(pbRet);
        }
Пример #24
0
        private static void Blake2bLong(byte[] pbOut, int cbOut,
                                        byte[] pbIn, int cbIn, Blake2b h)
        {
            Debug.Assert((h != null) && (h.HashSize == (64 * 8)));

            byte[] pbOutLen = new byte[4];
            MemUtil.UInt32ToBytesEx((uint)cbOut, pbOutLen, 0);

            if (cbOut <= 64)
            {
                Blake2b hOut = ((cbOut == 64) ? h : new Blake2b(cbOut));
                if (cbOut == 64)
                {
                    hOut.Initialize();
                }

                hOut.TransformBlock(pbOutLen, 0, pbOutLen.Length, pbOutLen, 0);
                hOut.TransformBlock(pbIn, 0, cbIn, pbIn, 0);
                hOut.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);

                Array.Copy(hOut.Hash, pbOut, cbOut);

                if (cbOut < 64)
                {
                    hOut.Clear();
                }
                return;
            }

            h.Initialize();
            h.TransformBlock(pbOutLen, 0, pbOutLen.Length, pbOutLen, 0);
            h.TransformBlock(pbIn, 0, cbIn, pbIn, 0);
            h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);

            byte[] pbOutBuffer = new byte[64];
            Array.Copy(h.Hash, pbOutBuffer, pbOutBuffer.Length);

            int ibOut = 64 / 2;

            Array.Copy(pbOutBuffer, pbOut, ibOut);
            int cbToProduce = cbOut - ibOut;

            h.Initialize();
            while (cbToProduce > 64)
            {
                byte[] pbHash = h.ComputeHash(pbOutBuffer);
                Array.Copy(pbHash, pbOutBuffer, 64);

                Array.Copy(pbHash, 0, pbOut, ibOut, 64 / 2);
                ibOut       += 64 / 2;
                cbToProduce -= 64 / 2;

                MemUtil.ZeroByteArray(pbHash);
            }

            using (Blake2b hOut = new Blake2b(cbToProduce))
            {
                byte[] pbHash = hOut.ComputeHash(pbOutBuffer);
                Array.Copy(pbHash, 0, pbOut, ibOut, cbToProduce);

                MemUtil.ZeroByteArray(pbHash);
            }

            MemUtil.ZeroByteArray(pbOutBuffer);
        }
Пример #25
0
        /// <summary>
        /// Construct a new cryptographically secure random stream object.
        /// </summary>
        /// <param name="a">Algorithm to use.</param>
        /// <param name="pbKey">Initialization key. Must not be <c>null</c>
        /// and must contain at least 1 byte.</param>
        public CryptoRandomStream(CrsAlgorithm a, byte[] pbKey)
        {
            if (pbKey == null)
            {
                Debug.Assert(false); throw new ArgumentNullException("pbKey");
            }

            int cbKey = pbKey.Length;

            if (cbKey <= 0)
            {
                Debug.Assert(false);                 // Need at least one byte
                throw new ArgumentOutOfRangeException("pbKey");
            }

            m_crsAlgorithm = a;

            if (a == CrsAlgorithm.ChaCha20)
            {
                byte[] pbKey32 = new byte[32];
                byte[] pbIV12  = new byte[12];

                using (SHA512Managed h = new SHA512Managed())
                {
                    byte[] pbHash = h.ComputeHash(pbKey);
                    Array.Copy(pbHash, pbKey32, 32);
                    Array.Copy(pbHash, 32, pbIV12, 0, 12);
                    MemUtil.ZeroByteArray(pbHash);
                }

                m_chacha20 = new ChaCha20Cipher(pbKey32, pbIV12, true);
            }
            else if (a == CrsAlgorithm.Salsa20)
            {
                byte[] pbKey32 = CryptoUtil.HashSha256(pbKey);
                byte[] pbIV8   = new byte[8] {
                    0xE8, 0x30, 0x09, 0x4B,
                    0x97, 0x20, 0x5D, 0x2A
                };                                                // Unique constant

                m_salsa20 = new Salsa20Cipher(pbKey32, pbIV8);
            }
            else if (a == CrsAlgorithm.ArcFourVariant)
            {
                // Fill the state linearly
                m_pbState = new byte[256];
                for (int w = 0; w < 256; ++w)
                {
                    m_pbState[w] = (byte)w;
                }

                unchecked
                {
                    byte j = 0, t;
                    int  inxKey = 0;
                    for (int w = 0; w < 256; ++w)                    // Key setup
                    {
                        j += (byte)(m_pbState[w] + pbKey[inxKey]);

                        t            = m_pbState[0];              // Swap entries
                        m_pbState[0] = m_pbState[j];
                        m_pbState[j] = t;

                        ++inxKey;
                        if (inxKey >= cbKey)
                        {
                            inxKey = 0;
                        }
                    }
                }

                GetRandomBytes(512); // Increases security, see cryptanalysis
            }
            else                     // Unknown algorithm
            {
                Debug.Assert(false);
                throw new ArgumentOutOfRangeException("a");
            }
        }
Пример #26
0
        private static void FillSegmentThr(object o)
        {
            Argon2ThreadInfo ti = (o as Argon2ThreadInfo);

            if (ti == null)
            {
                Debug.Assert(false); return;
            }

            try
            {
                Argon2Ctx ctx = ti.Context;
                if (ctx == null)
                {
                    Debug.Assert(false); return;
                }

                Debug.Assert(ctx.Version >= MinVersion);
                bool bCanXor = (ctx.Version >= 0x13U);

                ulong[] pbR             = new ulong[NbBlockSizeInQW];
                ulong[] pbTmp           = new ulong[NbBlockSizeInQW];
                ulong[] pbAddrInputZero = null;

                bool bDataIndependentAddr = ((ctx.Type == Argon2Type.ID) &&
                                             (ti.Pass == 0) && (ti.Slice < (NbSyncPoints / 2)));
                if (bDataIndependentAddr)
                {
                    pbAddrInputZero = new ulong[NbBlockSizeInQW * 3];

                    const int iInput = (int)NbBlockSizeInQW;
                    pbAddrInputZero[iInput]     = ti.Pass;
                    pbAddrInputZero[iInput + 1] = ti.Lane;
                    pbAddrInputZero[iInput + 2] = ti.Slice;
                    pbAddrInputZero[iInput + 3] = ctx.MemoryBlocks;
                    pbAddrInputZero[iInput + 4] = ctx.TCost;
                    pbAddrInputZero[iInput + 5] = (ulong)ctx.Type;
                }

                ulong uStart = 0;
                if ((ti.Pass == 0) && (ti.Slice == 0))
                {
                    uStart = 2;

                    if (bDataIndependentAddr)
                    {
                        NextAddresses(pbAddrInputZero, pbR, pbTmp);
                    }
                }

                ulong uCur = (ti.Lane * ctx.LaneLength) + (ti.Slice *
                                                           ctx.SegmentLength) + uStart;

                ulong uPrev = (((uCur % ctx.LaneLength) == 0) ?
                               (uCur + ctx.LaneLength - 1UL) : (uCur - 1UL));

                for (ulong i = uStart; i < ctx.SegmentLength; ++i)
                {
                    if ((uCur % ctx.LaneLength) == 1)
                    {
                        uPrev = uCur - 1UL;
                    }

                    ulong uPseudoRand;
                    if (bDataIndependentAddr)
                    {
                        ulong iMod = i % NbAddressesInBlock;
                        if (iMod == 0)
                        {
                            NextAddresses(pbAddrInputZero, pbR, pbTmp);
                        }
                        uPseudoRand = pbAddrInputZero[iMod];
                    }
                    else
                    {
                        uPseudoRand = ctx.Mem[uPrev * NbBlockSizeInQW];
                    }

                    ulong uRefLane = (uPseudoRand >> 32) % ctx.Lanes;
                    if ((ti.Pass == 0) && (ti.Slice == 0))
                    {
                        uRefLane = ti.Lane;
                    }

                    ti.Index = i;
                    ulong uRefIndex = IndexAlpha(ctx, ti, (uint)uPseudoRand,
                                                 (uRefLane == ti.Lane));

                    ulong uRefBlockIndex = (ctx.LaneLength * uRefLane +
                                            uRefIndex) * NbBlockSizeInQW;
                    ulong uCurBlockIndex = uCur * NbBlockSizeInQW;

                    FillBlock(ctx.Mem, uPrev * NbBlockSizeInQW, uRefBlockIndex,
                              uCurBlockIndex, ((ti.Pass != 0) && bCanXor), pbR, pbTmp);

                    ++uCur;
                    ++uPrev;
                }

                MemUtil.ZeroArray <ulong>(pbR);
                MemUtil.ZeroArray <ulong>(pbTmp);
                if (pbAddrInputZero != null)
                {
                    MemUtil.ZeroArray <ulong>(pbAddrInputZero);
                }
            }
            catch (Exception) { Debug.Assert(false); }

            try { ti.Finished.Set(); }
            catch (Exception) { Debug.Assert(false); }
        }
        internal static PwgError Generate(out ProtectedString psOut,
                                          PwProfile pwProfile, CryptoRandomStream crsRandomSource)
        {
            psOut = ProtectedString.Empty;

            string strPattern = pwProfile.Pattern;

            if (string.IsNullOrEmpty(strPattern))
            {
                return(PwgError.Success);
            }

            CharStream        cs          = new CharStream(strPattern);
            LinkedList <char> llGenerated = new LinkedList <char>();
            PwCharSet         pcs         = new PwCharSet();

            while (true)
            {
                char ch = cs.ReadChar();
                if (ch == char.MinValue)
                {
                    break;
                }

                pcs.Clear();

                if (ch == '\\')
                {
                    ch = cs.ReadChar();
                    if (ch == char.MinValue)
                    {
                        return(PwgError.InvalidPattern);
                    }

                    pcs.Add(ch);                     // Allow "{...}" support and char check
                }
                else if (ch == '[')
                {
                    if (!ReadCustomCharSet(cs, pcs))
                    {
                        return(PwgError.InvalidPattern);
                    }
                }
                else
                {
                    if (!pcs.AddCharSet(ch))
                    {
                        return(PwgError.InvalidPattern);
                    }
                }

                int nCount = 1;
                if (cs.PeekChar() == '{')
                {
                    nCount = ReadCount(cs);
                    if (nCount < 0)
                    {
                        return(PwgError.InvalidPattern);
                    }
                }

                for (int i = 0; i < nCount; ++i)
                {
                    if (!PwGenerator.PrepareCharSet(pcs, pwProfile))
                    {
                        return(PwgError.InvalidCharSet);
                    }
                    if (pwProfile.NoRepeatingCharacters)
                    {
                        foreach (char chUsed in llGenerated)
                        {
                            pcs.Remove(chUsed);
                        }
                    }

                    char chGen = PwGenerator.GenerateCharacter(pcs,
                                                               crsRandomSource);
                    if (chGen == char.MinValue)
                    {
                        return(PwgError.TooFewCharacters);
                    }

                    llGenerated.AddLast(chGen);
                }
            }

            if (llGenerated.Count == 0)
            {
                return(PwgError.Success);
            }

            char[] v = new char[llGenerated.Count];
            llGenerated.CopyTo(v, 0);

            if (pwProfile.PatternPermutePassword)
            {
                PwGenerator.Shuffle(v, crsRandomSource);
            }

            byte[] pbUtf8 = StrUtil.Utf8.GetBytes(v);
            psOut = new ProtectedString(true, pbUtf8);
            MemUtil.ZeroByteArray(pbUtf8);

            MemUtil.ZeroArray <char>(v);
            return(PwgError.Success);
        }
Пример #28
0
        private byte[] Argon2Transform(byte[] pbMsg, byte[] pbSalt, uint uParallel,
                                       ulong uMem, ulong uIt, int cbOut, uint uVersion, byte[] pbSecretKey,
                                       byte[] pbAssocData)
        {
            pbSecretKey = (pbSecretKey ?? MemUtil.EmptyByteArray);
            pbAssocData = (pbAssocData ?? MemUtil.EmptyByteArray);

#if ARGON2_B2ROUND_ARRAYS
            InitB2RoundIndexArrays();
#endif

            Argon2Ctx ctx = new Argon2Ctx();
            ctx.Type    = m_t;
            ctx.Version = uVersion;

            ctx.Lanes        = uParallel;
            ctx.TCost        = uIt;
            ctx.MCost        = uMem / NbBlockSize;
            ctx.MemoryBlocks = Math.Max(ctx.MCost, 2UL * NbSyncPoints * ctx.Lanes);

            ctx.SegmentLength = ctx.MemoryBlocks / (ctx.Lanes * NbSyncPoints);
            ctx.MemoryBlocks  = ctx.SegmentLength * ctx.Lanes * NbSyncPoints;

            ctx.LaneLength = ctx.SegmentLength * NbSyncPoints;

            Debug.Assert(NbBlockSize == (NbBlockSizeInQW *
#if KeePassUAP
                                         (ulong)Marshal.SizeOf <ulong>()
#else
                                         (ulong)Marshal.SizeOf(typeof(ulong))
#endif
                                         ));
            ctx.Mem = new ulong[ctx.MemoryBlocks * NbBlockSizeInQW];

            Blake2b h = new Blake2b();

            // Initial hash
            Debug.Assert(h.HashSize == (NbPreHashDigestLength * 8));
            byte[] pbBuf = new byte[4];
            MemUtil.UInt32ToBytesEx(uParallel, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx((uint)cbOut, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx((uint)ctx.MCost, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx((uint)uIt, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx(uVersion, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx((uint)m_t, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx((uint)pbMsg.Length, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0);
            MemUtil.UInt32ToBytesEx((uint)pbSalt.Length, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            h.TransformBlock(pbSalt, 0, pbSalt.Length, pbSalt, 0);
            MemUtil.UInt32ToBytesEx((uint)pbSecretKey.Length, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            h.TransformBlock(pbSecretKey, 0, pbSecretKey.Length, pbSecretKey, 0);
            MemUtil.UInt32ToBytesEx((uint)pbAssocData.Length, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            h.TransformBlock(pbAssocData, 0, pbAssocData.Length, pbAssocData, 0);
            h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
            byte[] pbH0 = h.Hash;
            Debug.Assert(pbH0.Length == 64);

            byte[] pbBlockHash = new byte[NbPreHashSeedLength];
            Array.Copy(pbH0, pbBlockHash, pbH0.Length);
            MemUtil.ZeroByteArray(pbH0);

            FillFirstBlocks(ctx, pbBlockHash, h);
            MemUtil.ZeroByteArray(pbBlockHash);

            FillMemoryBlocks(ctx);

            byte[] pbOut = FinalHash(ctx, cbOut, h);

            h.Clear();
            MemUtil.ZeroArray <ulong>(ctx.Mem);
            return(pbOut);
        }
Пример #29
0
        public static PwProfile DeriveFromPassword(ProtectedString psPassword)
        {
            PwProfile pp = new PwProfile();

            Debug.Assert(psPassword != null); if (psPassword == null)
            {
                return(pp);
            }

            char[] vChars = psPassword.ReadChars();

            pp.GeneratorType = PasswordGeneratorType.CharSet;
            pp.Length        = (uint)vChars.Length;

            PwCharSet pcs = pp.CharSet;

            pcs.Clear();

            foreach (char ch in vChars)
            {
                if ((ch >= 'A') && (ch <= 'Z'))
                {
                    pcs.Add(PwCharSet.UpperCase);
                }
                else if ((ch >= 'a') && (ch <= 'z'))
                {
                    pcs.Add(PwCharSet.LowerCase);
                }
                else if ((ch >= '0') && (ch <= '9'))
                {
                    pcs.Add(PwCharSet.Digits);
                }
                else if (PwCharSet.Special.IndexOf(ch) >= 0)
                {
                    pcs.Add(PwCharSet.Special);
                }
                else if (ch == ' ')
                {
                    pcs.Add(' ');
                }
                else if (ch == '-')
                {
                    pcs.Add('-');
                }
                else if (ch == '_')
                {
                    pcs.Add('_');
                }
                else if (PwCharSet.Brackets.IndexOf(ch) >= 0)
                {
                    pcs.Add(PwCharSet.Brackets);
                }
                else if (PwCharSet.Latin1S.IndexOf(ch) >= 0)
                {
                    pcs.Add(PwCharSet.Latin1S);
                }
                else
                {
                    pcs.Add(ch);
                }
            }

            MemUtil.ZeroArray <char>(vChars);
            return(pp);
        }
Пример #30
0
        private bool ReadSafeBlock()
        {
            if (m_bEos)
            {
                return(false);                   // End of stream reached already
            }
            m_iBufferPos = 0;

            if (m_brInput.ReadUInt32() != m_uBlockIndex)
            {
                throw new InvalidDataException();
            }
            ++m_uBlockIndex;

            byte[] pbStoredHash = m_brInput.ReadBytes(32);
            if ((pbStoredHash == null) || (pbStoredHash.Length != 32))
            {
                throw new InvalidDataException();
            }

            int nBufferSize = 0;

            try { nBufferSize = m_brInput.ReadInt32(); }
            catch (NullReferenceException)            // Mono bug workaround (LaunchPad 783268)
            {
                if (!NativeLib.IsUnix())
                {
                    throw;
                }
            }

            if (nBufferSize < 0)
            {
                throw new InvalidDataException();
            }

            if (nBufferSize == 0)
            {
                for (int iHash = 0; iHash < 32; ++iHash)
                {
                    if (pbStoredHash[iHash] != 0)
                    {
                        throw new InvalidDataException();
                    }
                }

                m_bEos = true;
                SetBuffer(MemUtil.EmptyByteArray);
                return(false);
            }

            SetBuffer(m_brInput.ReadBytes(nBufferSize));
            if ((m_pbBuffer == null) || ((m_pbBuffer.Length != nBufferSize) && m_bVerify))
            {
                throw new InvalidDataException();
            }

            if (m_bVerify)
            {
                byte[] pbComputedHash = CryptoUtil.HashSha256(m_pbBuffer);
                if ((pbComputedHash == null) || (pbComputedHash.Length != 32))
                {
                    throw new InvalidOperationException();
                }

                if (!MemUtil.ArraysEqual(pbStoredHash, pbComputedHash))
                {
                    throw new InvalidDataException();
                }
            }

            return(true);
        }