* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / Mono.Security.Win32 / Mono.Security.Cryptography / CapiHash.cs
1 //
2 // Mono.Security.Cryptography.CapiHash
3 //
4 // Authors:
5 //      Sebastien Pouliot (sebastien@ximian.com)
6 //
7 // Copyright (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004 Novell (http://www.novell.com)
9 //
10
11 using System;
12 using System.Security.Cryptography;
13
14 namespace Mono.Security.Cryptography {
15
16 public class CapiHash : IDisposable {
17
18         private CapiContext context;
19         private IntPtr handle;
20         private uint hashSize;
21
22         public CapiHash (int hashAlgorithm) 
23         {
24                 context = new CapiContext ();
25                 Initialize (hashAlgorithm);
26         }
27
28         public CapiHash (CapiContext ctx, int hashAlgorithm) 
29         {
30                 context = ctx;
31                 Initialize (hashAlgorithm);
32         }
33
34         public CapiHash (CspParameters cspParams, int hashAlgorithm) 
35         {
36                 context = new CapiContext (cspParams);
37                 Initialize (hashAlgorithm);
38         }
39
40         ~CapiHash () 
41         {
42                 Dispose ();
43         }
44
45         public IntPtr Handle {
46                 get { return handle; }
47         }
48
49         public int HashSize {
50                 get { return (int) hashSize; }
51         }
52
53         public void Initialize (int algo) 
54         {
55                 if (context != null) {
56                         context.InternalResult = CryptoAPI.CryptCreateHash (context.Handle, (uint)algo, IntPtr.Zero, 0, ref handle);
57                         hashSize = 0;
58                         if (context.Result)
59                                 context.InternalResult = CryptoAPI.CryptGetHashParam (handle, CryptoAPI.HP_HASHVAL, null, ref hashSize, 0);
60                         GC.KeepAlive (this);
61                 }
62         }
63
64         public void Dispose () 
65         {
66                 if (handle != IntPtr.Zero) {
67                         CryptoAPI.CryptDestroyHash (handle);
68                         context.Dispose ();
69                         GC.KeepAlive (this);
70                         handle = IntPtr.Zero;
71                         GC.SuppressFinalize (this);
72                 }
73         }
74
75         // FIXME: calling this function 1,000,000 times (with a single character)
76         // is a good way to lose time (and hung NUnit)
77         // TODO: find the bug that hang NUnit
78         // TODO: optimize the function to call CryptHashData less often (bufferize)
79         public void HashCore (byte[] data, int start, int length) 
80         {
81                 byte[] toBeHashed = data;
82                 if (start != 0) {
83                         toBeHashed = new byte [length];
84                         Array.Copy (data, start, toBeHashed, 0, length);
85                 }
86                 context.InternalResult = CryptoAPI.CryptHashData (handle, toBeHashed, (uint)length, 0);
87                 GC.KeepAlive (this);
88         }
89
90         public byte[] HashFinal () 
91         {
92                 byte[] hash = new byte [hashSize];
93                 context.InternalResult = CryptoAPI.CryptGetHashParam (handle, CryptoAPI.HP_HASHVAL, hash, ref hashSize, 0);
94                 GC.KeepAlive (this);
95                 return hash;
96         }
97 }
98
99 }