**** Merged from MCS ****
[mono-project.git] / mcs / class / Npgsql / Npgsql / HashAlgorithm.cs
blobad05a0ef0dbd06d094f97417953ae5bc6eb249fd
1 //
2 // System.Security.Cryptography HashAlgorithm Class implementation
3 //
4 // Authors:
5 // Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
6 // Sebastien Pouliot (spouliot@motus.com)
7 //
8 // Copyright 2001 by Matthew S. Ford.
9 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
11 // Comment: Adapted to the Project from Mono CVS as Sebastien Pouliot suggested to enable
12 // support of Npgsql MD5 authentication in platforms which don't have support for MD5 algorithm.
16 using System;
17 using System.IO;
20 namespace Npgsql
24 // Comment: Removed the ICryptoTransform implementation as this interface may be not supported by
25 // all platforms.
27 internal abstract class HashAlgorithm : IDisposable
29 protected byte[] HashValue; // Caches the hash after it is calculated. Accessed through the Hash property.
30 protected int HashSizeValue; // The size of the hash in bits.
31 protected int State; // nonzero when in use; zero when not in use
32 private bool disposed;
34 /// <summary>
35 /// Called from constructor of derived class.
36 /// </summary>
37 protected HashAlgorithm ()
39 disposed = false;
42 /// <summary>
43 /// Finalizer for HashAlgorithm
44 /// </summary>
45 ~HashAlgorithm ()
47 Dispose(false);
50 /// <summary>
51 /// Get whether or not the hash can transform multiple blocks at a time.
52 /// Note: MUST be overriden if descendant can transform multiple block
53 /// on a single call!
54 /// </summary>
55 public virtual bool CanTransformMultipleBlocks {
56 get
58 return true;
62 public virtual bool CanReuseTransform {
63 get
65 return true;
69 public void Clear()
71 // same as System.IDisposable.Dispose() which is documented
72 Dispose (true);
75 /// <summary>
76 /// Computes the entire hash of all the bytes in the byte array.
77 /// </summary>
78 public byte[] ComputeHash (byte[] input)
80 return ComputeHash (input, 0, input.Length);
83 public byte[] ComputeHash (byte[] buffer, int offset, int count)
85 if (disposed)
86 throw new ObjectDisposedException ("HashAlgorithm");
88 HashCore (buffer, offset, count);
89 HashValue = HashFinal ();
90 Initialize ();
92 return HashValue;
95 public byte[] ComputeHash (Stream inputStream)
97 // don't read stream unless object is ready to use
98 if (disposed)
99 throw new ObjectDisposedException ("HashAlgorithm");
101 int l = (int) (inputStream.Length - inputStream.Position);
102 byte[] buffer = new byte [l];
103 inputStream.Read (buffer, 0, l);
105 return ComputeHash (buffer, 0, l);
108 // Commented out because it uses the CryptoConfig which can't be available in all platforms
111 /// <summary>
112 /// Creates the default implementation of the default hash algorithm (SHA1).
113 /// </summary>
114 public static HashAlgorithm Create ()
116 return Create ("System.Security.Cryptography.HashAlgorithm");
120 /// <summary>
121 /// Creates a specific implementation of the general hash idea.
122 /// </summary>
123 /// <param name="hashName">Specifies which derived class to create.</param>
124 public static HashAlgorithm Create (string hashName)
126 return (HashAlgorithm) CryptoConfig.CreateFromName (hashName);
131 // Changed Exception type because it uses the CryptographicUnexpectedOperationException
132 // which can't be available in all platforms.
133 /// <summary>
134 /// Gets the previously computed hash.
135 /// </summary>
136 public virtual byte[] Hash {
139 if (HashValue == null)
140 throw new NullReferenceException("HashValue is null");
141 return HashValue;
145 /// <summary>
146 /// When overridden in a derived class, drives the hashing function.
147 /// </summary>
148 /// <param name="rgb"></param>
149 /// <param name="start"></param>
150 /// <param name="size"></param>
151 protected abstract void HashCore (byte[] rgb, int start, int size);
153 /// <summary>
154 /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.
155 /// </summary>
156 protected abstract byte[] HashFinal ();
158 /// <summary>
159 /// Returns the size in bits of the hash.
160 /// </summary>
161 public virtual int HashSize {
164 return HashSizeValue;
168 /// <summary>
169 /// When overridden in a derived class, initializes the object to prepare for hashing.
170 /// </summary>
171 public abstract void Initialize ();
173 protected virtual void Dispose (bool disposing)
175 disposed = true;
178 /// <summary>
179 /// Must be overriden if not 1
180 /// </summary>
181 public virtual int InputBlockSize {
184 return 1;
188 /// <summary>
189 /// Must be overriden if not 1
190 /// </summary>
191 public virtual int OutputBlockSize {
194 return 1;
198 void IDisposable.Dispose ()
200 Dispose (true);
201 GC.SuppressFinalize (this); // Finalization is now unnecessary
204 /// <summary>
205 /// Used for stream chaining. Computes hash as data passes through it.
206 /// </summary>
207 /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
208 /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
209 /// <param name="inputCount">The number of bytes to be copied.</param>
210 /// <param name="outputBuffer">The buffer to write the copied data to.</param>
211 /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>
212 public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
214 Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
215 HashCore (inputBuffer, inputOffset, inputCount);
217 return inputCount;
220 /// <summary>
221 /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash.
222 /// </summary>
223 /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
224 /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
225 /// <param name="inputCount">The number of bytes to be copied.</param>
226 public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
228 byte[] outputBuffer = new byte[inputCount];
230 Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount);
232 HashCore (inputBuffer, inputOffset, inputCount);
233 HashValue = HashFinal ();
234 Initialize ();
236 return outputBuffer;