a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
100 lines
2.2 KiB
C#
100 lines
2.2 KiB
C#
//
|
|
// Mono.Security.Cryptography.CapiHash
|
|
//
|
|
// Authors:
|
|
// Sebastien Pouliot (sebastien@ximian.com)
|
|
//
|
|
// Copyright (C) 2003 Motus Technologies Inc. (http://www.motus.com)
|
|
// Copyright (C) 2004 Novell (http://www.novell.com)
|
|
//
|
|
|
|
using System;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace Mono.Security.Cryptography {
|
|
|
|
public class CapiHash : IDisposable {
|
|
|
|
private CapiContext context;
|
|
private IntPtr handle;
|
|
private uint hashSize;
|
|
|
|
public CapiHash (int hashAlgorithm)
|
|
{
|
|
context = new CapiContext ();
|
|
Initialize (hashAlgorithm);
|
|
}
|
|
|
|
public CapiHash (CapiContext ctx, int hashAlgorithm)
|
|
{
|
|
context = ctx;
|
|
Initialize (hashAlgorithm);
|
|
}
|
|
|
|
public CapiHash (CspParameters cspParams, int hashAlgorithm)
|
|
{
|
|
context = new CapiContext (cspParams);
|
|
Initialize (hashAlgorithm);
|
|
}
|
|
|
|
~CapiHash ()
|
|
{
|
|
Dispose ();
|
|
}
|
|
|
|
public IntPtr Handle {
|
|
get { return handle; }
|
|
}
|
|
|
|
public int HashSize {
|
|
get { return (int) hashSize; }
|
|
}
|
|
|
|
public void Initialize (int algo)
|
|
{
|
|
if (context != null) {
|
|
context.InternalResult = CryptoAPI.CryptCreateHash (context.Handle, (uint)algo, IntPtr.Zero, 0, ref handle);
|
|
hashSize = 0;
|
|
if (context.Result)
|
|
context.InternalResult = CryptoAPI.CryptGetHashParam (handle, CryptoAPI.HP_HASHVAL, null, ref hashSize, 0);
|
|
GC.KeepAlive (this);
|
|
}
|
|
}
|
|
|
|
public void Dispose ()
|
|
{
|
|
if (handle != IntPtr.Zero) {
|
|
CryptoAPI.CryptDestroyHash (handle);
|
|
context.Dispose ();
|
|
GC.KeepAlive (this);
|
|
handle = IntPtr.Zero;
|
|
GC.SuppressFinalize (this);
|
|
}
|
|
}
|
|
|
|
// FIXME: calling this function 1,000,000 times (with a single character)
|
|
// is a good way to lose time (and hung NUnit)
|
|
// TODO: find the bug that hang NUnit
|
|
// TODO: optimize the function to call CryptHashData less often (bufferize)
|
|
public void HashCore (byte[] data, int start, int length)
|
|
{
|
|
byte[] toBeHashed = data;
|
|
if (start != 0) {
|
|
toBeHashed = new byte [length];
|
|
Array.Copy (data, start, toBeHashed, 0, length);
|
|
}
|
|
context.InternalResult = CryptoAPI.CryptHashData (handle, toBeHashed, (uint)length, 0);
|
|
GC.KeepAlive (this);
|
|
}
|
|
|
|
public byte[] HashFinal ()
|
|
{
|
|
byte[] hash = new byte [hashSize];
|
|
context.InternalResult = CryptoAPI.CryptGetHashParam (handle, CryptoAPI.HP_HASHVAL, hash, ref hashSize, 0);
|
|
GC.KeepAlive (this);
|
|
return hash;
|
|
}
|
|
}
|
|
|
|
}
|