diff --git a/Monsoon/ChangeLog b/Monsoon/ChangeLog index ce33e3d..59309be 100644 --- a/Monsoon/ChangeLog +++ b/Monsoon/ChangeLog @@ -1,3 +1,12 @@ +2009-06-23 Alan McGovern + + * Makefile.am: + * Monsoon.csproj: + * OpenSSLSha1.cs: + * TorrentController.cs: Monsoon will use openssh for sha1 + hashing if it is available, otherwise fall back to the + standard hash function. + 2009-06-23 Alan McGovern * TorrentController.cs: diff --git a/Monsoon/Makefile.am b/Monsoon/Makefile.am index e7b9689..243ca79 100644 --- a/Monsoon/Makefile.am +++ b/Monsoon/Makefile.am @@ -5,7 +5,7 @@ EXTRA_DIST = $(NLOG_DLL_SOURCE) if ENABLE_DEBUG ASSEMBLY_COMPILER_COMMAND = gmcs -ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ -debug -define:DEBUG +ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ -debug -define:DEBUG -unsafe ASSEMBLY = bin/Debug/Monsoon.exe ASSEMBLY_MDB = $(ASSEMBLY).mdb COMPILE_TARGET = exe @@ -28,7 +28,7 @@ endif if ENABLE_RELEASE ASSEMBLY_COMPILER_COMMAND = gmcs -ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ -debug +ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ -debug -unsafe ASSEMBLY = bin/Release/Monsoon.exe ASSEMBLY_MDB = COMPILE_TARGET = exe @@ -134,6 +134,7 @@ FILES = \ Model/State.cs \ Model/StateChangedEventArgs.cs \ Model/TorrentFileModel.cs \ + OpenSSLSha1.cs \ PeerTreeView.cs \ PiecesTreeView.cs \ PreferencesDialog.cs \ diff --git a/Monsoon/Monsoon.csproj b/Monsoon/Monsoon.csproj index 2bbdc12..c8e8aac 100644 --- a/Monsoon/Monsoon.csproj +++ b/Monsoon/Monsoon.csproj @@ -19,6 +19,7 @@ 4 true . + true none @@ -28,6 +29,7 @@ 4 . -d + true @@ -146,6 +148,7 @@ + diff --git a/Monsoon/OpenSSLSha1.cs b/Monsoon/OpenSSLSha1.cs new file mode 100644 index 0000000..ad6ef5d --- /dev/null +++ b/Monsoon/OpenSSLSha1.cs @@ -0,0 +1,56 @@ + +using System; +using System.Runtime.InteropServices; + +namespace Monsoon +{ + public class OpenSSLSha1 : System.Security.Cryptography.SHA1 + { + IntPtr context; + public OpenSSLSha1 () + { + // The native SHA1 structure is 96 bytes in length + context = Marshal.AllocHGlobal (96); + if (SHA1_Init (context) != 1) + throw new Exception ("Could not init context"); + } + + public override void Initialize () + { + if (SHA1_Init (context) != 1) + throw new Exception ("Could not init context"); + } + + protected override unsafe void HashCore (byte[] array, int ibStart, int cbSize) + { + if (ibStart > array.Length) + throw new IndexOutOfRangeException ("ibStart"); + if ((array.Length - ibStart) < cbSize) + throw new IndexOutOfRangeException ("cbSize"); + + if (cbSize == 0) + return; + + fixed (byte *ptr = array) + if (SHA1_Update (context, ptr + ibStart, (ulong) cbSize) != 1) + throw new Exception ("Could not hash data"); + } + + protected override byte[] HashFinal () + { + // Result must be at least of length 20 + byte [] result = new byte [20]; + if (SHA1_Final (result, context) != 1) + throw new Exception ("Could not hash final chunk"); + return result; + } + + // All return '1' for success, '0' for failure + [DllImport ("libssl.so.0.9.8")] + static extern int SHA1_Init (IntPtr context); + [DllImport ("libssl.so.0.9.8")] + static extern unsafe int SHA1_Update (IntPtr context, byte *data, ulong len); + [DllImport ("libssl.so.0.9.8")] + static extern int SHA1_Final (byte [] buffer, IntPtr context); + } +} diff --git a/Monsoon/TorrentController.cs b/Monsoon/TorrentController.cs index 941c568..a89f14b 100644 --- a/Monsoon/TorrentController.cs +++ b/Monsoon/TorrentController.cs @@ -73,6 +73,21 @@ public List FastResume private static NLog.Logger logger = MainClass.DebugEnabled ? NLog.LogManager.GetCurrentClassLogger () : new EmptyLogger (); TorrentSettings defaultTorrentSettings; + + static TorrentController () + { + try { + using (OpenSSLSha1 native = new OpenSSLSha1 ()) { + native.ComputeHash (new byte[1024]); + HashAlgoFactory.Register (typeof (SHA1), typeof (SHA1CryptoServiceProvider)); + logger.Debug ("Using OpenSSL for SHA1 hashing"); + } + } catch { + // If an exception occurs it means that the native SHA1 function is unusable + // so don't register it then + } + } + public TorrentController() { this.defaultTorrentSettings = SettingsManager.DefaultTorrentSettings;