PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/seclib/Security/Ssl/Shared/CloneableHash.cs

http://github.com/greubelm/securitylibrary
C# | 117 lines | 83 code | 2 blank | 32 comment | 18 complexity | 4fce1cc3076911d798f0f8005e821eb7 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*
  2. * Mentalis.org Security Library
  3. *
  4. * Copyright Š 2002-2005, The Mentalis.org Team
  5. * All rights reserved.
  6. * http://www.mentalis.org/
  7. *
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * - Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. *
  16. * - Neither the name of the Mentalis.org Team, nor the names of its contributors
  17. * may be used to endorse or promote products derived from this
  18. * software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  24. * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  25. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  27. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  29. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  30. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  31. * OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. using System;
  34. using System.Security.Cryptography;
  35. using System.Runtime.InteropServices;
  36. using Org.Mentalis.Security;
  37. using Org.Mentalis.Security.Certificates;
  38. using Org.Mentalis.Security.Cryptography;
  39. namespace Org.Mentalis.Security.Ssl.Shared {
  40. internal sealed class CloneableHash : HashAlgorithm, ICloneable {
  41. public CloneableHash(HashType type) {
  42. m_Type = type;
  43. m_Provider = CAPIProvider.Handle;
  44. Initialize();
  45. m_Disposed = false;
  46. }
  47. public CloneableHash(int hash, HashType type, int size) {
  48. m_Provider = CAPIProvider.Handle;
  49. m_Type = type;
  50. m_Size = size;
  51. m_Disposed = false;
  52. if (SspiProvider.CryptDuplicateHash(hash, IntPtr.Zero, 0, out m_Hash) == 0)
  53. throw new CryptographicException("Couldn't duplicate hash.");
  54. }
  55. public override void Initialize() {
  56. if (m_Disposed)
  57. throw new ObjectDisposedException(this.GetType().FullName);
  58. if (m_Hash != 0) {
  59. SspiProvider.CryptDestroyHash(m_Hash);
  60. }
  61. int type = SecurityConstants.CALG_SHA1;
  62. m_Size = 20;
  63. if (m_Type == HashType.MD5) {
  64. type = SecurityConstants.CALG_MD5;
  65. m_Size = 16;
  66. }
  67. SspiProvider.CryptCreateHash(m_Provider, type, 0, 0, out m_Hash);
  68. }
  69. protected override void HashCore(byte[] array, int ibStart, int cbSize) {
  70. if (ibStart > 0) {
  71. GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
  72. try {
  73. IntPtr address = handle.AddrOfPinnedObject();
  74. if (SspiProvider.CryptHashData(m_Hash, new IntPtr(address.ToInt64() + ibStart), cbSize, 0) == 0)
  75. throw new CryptographicException("The data could not be hashed.");
  76. } finally {
  77. handle.Free();
  78. }
  79. } else {
  80. if (SspiProvider.CryptHashData(m_Hash, array, cbSize, 0) == 0)
  81. throw new CryptographicException("The data could not be hashed.");
  82. }
  83. }
  84. protected override byte[] HashFinal() {
  85. byte[] buffer = new byte[m_Size];
  86. int length = buffer.Length;
  87. if (SspiProvider.CryptGetHashParam(m_Hash, SecurityConstants.HP_HASHVAL, buffer, ref length, 0) == 0)
  88. throw new CryptographicException("The hash value could not be read.");
  89. return buffer;
  90. }
  91. public object Clone() {
  92. return new CloneableHash(this.m_Hash, this.m_Type, this.m_Size);
  93. }
  94. protected override void Dispose(bool disposing) {
  95. if (!m_Disposed) {
  96. if (m_Hash != 0) {
  97. SspiProvider.CryptDestroyHash(m_Hash);
  98. m_Hash = 0;
  99. }
  100. try {
  101. GC.SuppressFinalize(this);
  102. } catch {}
  103. m_Disposed = true;
  104. }
  105. }
  106. ~CloneableHash() {
  107. Clear();
  108. }
  109. private int m_Provider;
  110. private int m_Hash;
  111. private bool m_Disposed;
  112. private HashType m_Type;
  113. private int m_Size;
  114. }
  115. }