/// <summary>Disposes of the object</summary>
        protected override void Dispose(bool disposing)
#endif
        {
            _block      = -1;
            _salt       = new byte[8];
            _iterations = 1;
            _hashAlgo.Clear();
        }
Example #2
0
        /// <summary>
        /// Dispose of all contained resources.
        /// </summary>
        public void Dispose()
        {
            if (m_decryptionBulkAlgorithm != null)
            {
#if NET40
                m_decryptionBulkAlgorithm.Dispose();
#else
                m_decryptionBulkAlgorithm.Clear();
#endif
                m_decryptionBulkAlgorithm = null;
            }

            if (m_encryptionBulkAlgorithm != null)
            {
#if NET40
                m_encryptionBulkAlgorithm.Dispose();
#else
                m_encryptionBulkAlgorithm.Clear();
#endif
                m_encryptionBulkAlgorithm = null;
            }

            if (m_decryptionHMAC != null)
            {
#if NET40
                m_decryptionHMAC.Dispose();
#else
                m_decryptionHMAC.Clear();
#endif
                m_decryptionHMAC = null;
            }

            if (m_encryptionHMAC != null)
            {
#if NET40
                m_encryptionHMAC.Dispose();
#else
                m_encryptionHMAC.Clear();
#endif
                m_encryptionHMAC = null;
            }

            if (PRF != null)
            {
                PRF.Dispose();
                PRF = null;
            }
        }
Example #3
0
        private static void VerifyIntegrity(FileData fileData)
        {
            BlobBuilder builder = new BlobBuilder();

            if (fileData.ppkFileVersion != Version.V1)
            {
                builder.AddStringBlob(fileData.publicKeyAlgorithm.GetIdentifierString());
                builder.AddStringBlob(fileData.privateKeyAlgorithm.GetIdentifierString());
                builder.AddBlob(Encoding.GetEncoding(1252).GetBytes(fileData.comment));
                builder.AddBlob(fileData.publicKeyBlob);
                builder.AddInt(fileData.privateKeyBlob.Data.Length);
            }
            builder.AddBytes(fileData.privateKeyBlob.Data);

            byte[] computedHash;
            SHA1   sha = SHA1.Create();

            if (fileData.isHMAC)
            {
                HMAC hmac = HMACSHA1.Create();
                if (fileData.passphrase != null)
                {
                    using (PinnedArray <byte> hashData =
                               new PinnedArray <byte>(cMACKeySalt.Length +
                                                      fileData.passphrase.Length)) {
                        Array.Copy(Encoding.UTF8.GetBytes(cMACKeySalt),
                                   hashData.Data, cMACKeySalt.Length);
                        IntPtr passphrasePtr =
                            Marshal.SecureStringToGlobalAllocUnicode(fileData.passphrase);
                        for (int i = 0; i < fileData.passphrase.Length; i++)
                        {
                            int  unicodeChar = Marshal.ReadInt16(passphrasePtr + i * 2);
                            byte ansiChar    = Util.UnicodeToAnsi(unicodeChar);
                            hashData.Data[cMACKeySalt.Length + i] = ansiChar;
                            Marshal.WriteByte(passphrasePtr, i * 2, 0);
                        }
                        Marshal.ZeroFreeGlobalAllocUnicode(passphrasePtr);
                        hmac.Key = sha.ComputeHash(hashData.Data);
                    }
                }
                else
                {
                    hmac.Key = sha.ComputeHash(Encoding.UTF8.GetBytes(cMACKeySalt));
                }
                computedHash = hmac.ComputeHash(builder.GetBlob());
                hmac.Clear();
            }
            else
            {
                computedHash = sha.ComputeHash(builder.GetBlob());
            }
            sha.Clear();
            builder.Clear();

            try {
                int  macLength = computedHash.Length;
                bool failed    = false;
                if (fileData.privateMAC.Length == macLength)
                {
                    for (int i = 0; i < macLength; i++)
                    {
                        if (fileData.privateMAC[i] != computedHash[i])
                        {
                            failed = true;
                            break;
                        }
                    }
                }
                else
                {
                    failed = true;
                }
                if (failed)
                {
                    // private key data should start with 3 bytes with value 0 if it was
                    // properly decrypted or does not require decryption
                    if ((fileData.privateKeyBlob.Data[0] == 0) &&
                        (fileData.privateKeyBlob.Data[1] == 0) &&
                        (fileData.privateKeyBlob.Data[2] == 0))
                    {
                        // so if they bytes are there, passphrase decrypted properly and
                        // something else is wrong with the file contents
                        throw new PpkFormatterException(PpkFormatterException.PpkErrorType.FileCorrupt);
                    }
                    else
                    {
                        // if the bytes are not zeros, we assume that the data was not
                        // properly decrypted because the passphrase was incorrect.
                        throw new PpkFormatterException(PpkFormatterException.PpkErrorType.BadPassphrase);
                    }
                }
            } catch {
                throw;
            } finally {
                Array.Clear(computedHash, 0, computedHash.Length);
            }
        }