Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

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;
}
}
}