/* * Mentalis.org Security Library * * Copyright © 2002-2005, The KPD-Team * All rights reserved. * http://www.mentalis.org/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Neither the name of the KPD-Team, nor the names of its contributors * may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ using System; using System.Security.Cryptography; using System.Runtime.InteropServices; using Org.Mentalis.Security; namespace Org.Mentalis.Security.Cryptography { /// /// Computes the hash for the input data using the implementation provided by the cryptographic service provider (CSP). /// /// Warning: The MD4 algorithm is a broken algorithm. It should only be used for compatibility with older systems. public sealed class MD4CryptoServiceProvider : MD4 { /// /// Initializes a new instance of the class. This class cannot be inherited. /// public MD4CryptoServiceProvider() { // acquire an MD4 context m_Provider = CAPIProvider.Handle; /* if (SspiProvider.CryptAcquireContext(ref m_Provider, IntPtr.Zero, null, SecurityConstants.PROV_RSA_FULL, 0) == 0) { if (Marshal.GetLastWin32Error() == SecurityConstants.NTE_BAD_KEYSET) SspiProvider.CryptAcquireContext(ref m_Provider, IntPtr.Zero, null, SecurityConstants.PROV_RSA_FULL, SecurityConstants.CRYPT_NEWKEYSET); }*/ Initialize(); m_Disposed = false; } /// /// Initializes an instance of . /// /// The MD4CryptoServiceProvider instance has been disposed. public override void Initialize() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); if (m_Hash != 0) { SspiProvider.CryptDestroyHash(m_Hash); } SspiProvider.CryptCreateHash(m_Provider, SecurityConstants.CALG_MD4, 0, 0, out m_Hash); } /// /// Routes data written to the object into the hash algorithm for computing the hash. /// /// The array of data bytes. /// The offset into the byte array from which to begin using data. /// The number of bytes in the array to use as data. /// The MD4CryptoServiceProvider instance has been disposed. /// The data could not be hashed. protected override void HashCore(byte[] array, int ibStart, int cbSize) { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); byte[] copy = new byte[cbSize]; Array.Copy(array, ibStart, copy, 0, cbSize); if (SspiProvider.CryptHashData(m_Hash, copy, copy.Length, 0) == 0) throw new CryptographicException("The data could not be hashed."); } /// /// Returns the computed hash as an array of bytes after all data has been written to the object. /// /// The computed hash value. /// The MD4CryptoServiceProvider instance has been disposed. /// The data could not be hashed. protected override byte[] HashFinal() { if (m_Disposed) throw new ObjectDisposedException(this.GetType().FullName); byte[] buffer = new byte[16]; int length = buffer.Length; if (SspiProvider.CryptGetHashParam(m_Hash, SecurityConstants.HP_HASHVAL, buffer, ref length, 0) == 0) throw new CryptographicException("The hash value could not be read."); return buffer; } /// /// Releases the unmanaged resources used by the and optionally releases the managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected override void Dispose(bool disposing) { if (!m_Disposed) { if (m_Hash != 0) { SspiProvider.CryptDestroyHash(m_Hash); m_Hash = 0; } /* if (m_Provider != 0) { SspiProvider.CryptReleaseContext(m_Provider, 0); m_Provider = 0; }*/ try { GC.SuppressFinalize(this); } catch {} m_Disposed = true; } } /// /// Finalizes the MD4CryptoServiceProvider. /// ~MD4CryptoServiceProvider() { Clear(); } /// /// Holds the handle of the crypto service provider. /// private int m_Provider; /// /// Holds the hash handle. /// private int m_Hash; /// /// true if the object ahs been disposed, false otherwise. /// private bool m_Disposed; } }