summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2018-10-11 17:41:20 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2018-10-11 17:41:20 +0700
commit02d07a1f8bd57f4141ef1a1dc006e5f72c1116c5 (patch)
treefb5b664fda22c03a399d5185d0fe48336961fea7
parentMore PORTABLE fixes (diff)
downloadBouncyCastle.NET-ed25519-02d07a1f8bd57f4141ef1a1dc006e5f72c1116c5.tar.xz
Refactoring to support custom ISignatureFactory
- see https://github.com/bcgit/bc-csharp/issues/153
-rw-r--r--crypto/BouncyCastle.Android.csproj10
-rw-r--r--crypto/BouncyCastle.csproj10
-rw-r--r--crypto/BouncyCastle.iOS.csproj10
-rw-r--r--crypto/crypto.csproj50
-rw-r--r--crypto/src/cms/CMSAuthenticatedDataGenerator.cs2
-rw-r--r--crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs2
-rw-r--r--crypto/src/cms/CMSEnvelopedHelper.cs2
-rw-r--r--crypto/src/cms/CMSSignedDataGenerator.cs3
-rw-r--r--crypto/src/cms/CMSSignedDataStreamGenerator.cs2
-rw-r--r--crypto/src/cms/DigOutputStream.cs28
-rw-r--r--crypto/src/cms/MacOutputStream.cs28
-rw-r--r--crypto/src/cms/SigOutputStream.cs43
-rw-r--r--crypto/src/cms/SignerInformation.cs14
-rw-r--r--crypto/src/crypto/IRsa.cs16
-rw-r--r--crypto/src/crypto/engines/RSABlindedEngine.cs13
-rw-r--r--crypto/src/crypto/engines/RSABlindingEngine.cs12
-rw-r--r--crypto/src/crypto/engines/RSACoreEngine.cs29
-rw-r--r--crypto/src/crypto/engines/RsaEngine.cs24
-rw-r--r--crypto/src/crypto/io/DigestSink.cs35
-rw-r--r--crypto/src/crypto/io/MacSink.cs35
-rw-r--r--crypto/src/crypto/io/SignerSink.cs35
-rw-r--r--crypto/src/crypto/operators/Asn1Signature.cs194
-rw-r--r--crypto/src/crypto/operators/DefaultSignatureCalculator.cs28
-rw-r--r--crypto/src/crypto/operators/DefaultSignatureResult.cs27
-rw-r--r--crypto/src/crypto/operators/DefaultVerifierCalculator.cs28
-rw-r--r--crypto/src/crypto/operators/DefaultVerifierResult.cs29
-rw-r--r--crypto/src/crypto/signers/RsaDigestSigner.cs13
-rw-r--r--crypto/src/security/ParameterUtilities.cs9
-rw-r--r--crypto/src/security/SignerUtilities.cs12
29 files changed, 406 insertions, 337 deletions
diff --git a/crypto/BouncyCastle.Android.csproj b/crypto/BouncyCastle.Android.csproj
index 8936ecbc1..80a50ff56 100644
--- a/crypto/BouncyCastle.Android.csproj
+++ b/crypto/BouncyCastle.Android.csproj
@@ -602,7 +602,6 @@
     <Compile Include="src\cms\CounterSignatureDigestCalculator.cs" />
     <Compile Include="src\cms\DefaultAuthenticatedAttributeTableGenerator.cs" />
     <Compile Include="src\cms\DefaultSignedAttributeTableGenerator.cs" />
-    <Compile Include="src\cms\DigOutputStream.cs" />
     <Compile Include="src\cms\IDigestCalculator.cs" />
     <Compile Include="src\cms\KEKRecipientInfoGenerator.cs" />
     <Compile Include="src\cms\KEKRecipientInformation.cs" />
@@ -610,7 +609,6 @@
     <Compile Include="src\cms\KeyAgreeRecipientInformation.cs" />
     <Compile Include="src\cms\KeyTransRecipientInfoGenerator.cs" />
     <Compile Include="src\cms\KeyTransRecipientInformation.cs" />
-    <Compile Include="src\cms\MacOutputStream.cs" />
     <Compile Include="src\cms\OriginatorId.cs" />
     <Compile Include="src\cms\OriginatorInfoGenerator.cs" />
     <Compile Include="src\cms\OriginatorInformation.cs" />
@@ -622,7 +620,6 @@
     <Compile Include="src\cms\RecipientInfoGenerator.cs" />
     <Compile Include="src\cms\RecipientInformation.cs" />
     <Compile Include="src\cms\RecipientInformationStore.cs" />
-    <Compile Include="src\cms\SigOutputStream.cs" />
     <Compile Include="src\cms\SignerId.cs" />
     <Compile Include="src\cms\SignerInfoGenerator.cs" />
     <Compile Include="src\cms\SignerInformation.cs" />
@@ -841,8 +838,11 @@
     <Compile Include="src\crypto\generators\X25519KeyPairGenerator.cs" />
     <Compile Include="src\crypto\generators\X448KeyPairGenerator.cs" />
     <Compile Include="src\crypto\io\CipherStream.cs" />
+    <Compile Include="src\crypto\io\DigestSink.cs" />
     <Compile Include="src\crypto\io\DigestStream.cs" />
+    <Compile Include="src\crypto\io\MacSink.cs" />
     <Compile Include="src\crypto\io\MacStream.cs" />
+    <Compile Include="src\crypto\io\SignerSink.cs" />
     <Compile Include="src\crypto\io\SignerStream.cs" />
     <Compile Include="src\crypto\macs\CMac.cs" />
     <Compile Include="src\crypto\macs\CbcBlockCipherMac.cs" />
@@ -880,6 +880,10 @@
     <Compile Include="src\crypto\modes\gcm\Tables64kGcmMultiplier.cs" />
     <Compile Include="src\crypto\modes\gcm\Tables8kGcmMultiplier.cs" />
     <Compile Include="src\crypto\operators\Asn1Signature.cs" />
+    <Compile Include="src\crypto\operators\DefaultSignatureCalculator.cs" />
+    <Compile Include="src\crypto\operators\DefaultSignatureResult.cs" />
+    <Compile Include="src\crypto\operators\DefaultVerifierCalculator.cs" />
+    <Compile Include="src\crypto\operators\DefaultVerifierResult.cs" />
     <Compile Include="src\crypto\paddings\BlockCipherPadding.cs" />
     <Compile Include="src\crypto\paddings\ISO10126d2Padding.cs" />
     <Compile Include="src\crypto\paddings\ISO7816d4Padding.cs" />
diff --git a/crypto/BouncyCastle.csproj b/crypto/BouncyCastle.csproj
index e66bb4e5d..fb4baa9b5 100644
--- a/crypto/BouncyCastle.csproj
+++ b/crypto/BouncyCastle.csproj
@@ -596,7 +596,6 @@
     <Compile Include="src\cms\CounterSignatureDigestCalculator.cs" />
     <Compile Include="src\cms\DefaultAuthenticatedAttributeTableGenerator.cs" />
     <Compile Include="src\cms\DefaultSignedAttributeTableGenerator.cs" />
-    <Compile Include="src\cms\DigOutputStream.cs" />
     <Compile Include="src\cms\IDigestCalculator.cs" />
     <Compile Include="src\cms\KEKRecipientInfoGenerator.cs" />
     <Compile Include="src\cms\KEKRecipientInformation.cs" />
@@ -604,7 +603,6 @@
     <Compile Include="src\cms\KeyAgreeRecipientInformation.cs" />
     <Compile Include="src\cms\KeyTransRecipientInfoGenerator.cs" />
     <Compile Include="src\cms\KeyTransRecipientInformation.cs" />
-    <Compile Include="src\cms\MacOutputStream.cs" />
     <Compile Include="src\cms\OriginatorId.cs" />
     <Compile Include="src\cms\OriginatorInfoGenerator.cs" />
     <Compile Include="src\cms\OriginatorInformation.cs" />
@@ -616,7 +614,6 @@
     <Compile Include="src\cms\RecipientInfoGenerator.cs" />
     <Compile Include="src\cms\RecipientInformation.cs" />
     <Compile Include="src\cms\RecipientInformationStore.cs" />
-    <Compile Include="src\cms\SigOutputStream.cs" />
     <Compile Include="src\cms\SignerId.cs" />
     <Compile Include="src\cms\SignerInfoGenerator.cs" />
     <Compile Include="src\cms\SignerInformation.cs" />
@@ -835,8 +832,11 @@
     <Compile Include="src\crypto\generators\X25519KeyPairGenerator.cs" />
     <Compile Include="src\crypto\generators\X448KeyPairGenerator.cs" />
     <Compile Include="src\crypto\io\CipherStream.cs" />
+    <Compile Include="src\crypto\io\DigestSink.cs" />
     <Compile Include="src\crypto\io\DigestStream.cs" />
+    <Compile Include="src\crypto\io\MacSink.cs" />
     <Compile Include="src\crypto\io\MacStream.cs" />
+    <Compile Include="src\crypto\io\SignerSink.cs" />
     <Compile Include="src\crypto\io\SignerStream.cs" />
     <Compile Include="src\crypto\macs\CMac.cs" />
     <Compile Include="src\crypto\macs\CbcBlockCipherMac.cs" />
@@ -874,6 +874,10 @@
     <Compile Include="src\crypto\modes\gcm\Tables64kGcmMultiplier.cs" />
     <Compile Include="src\crypto\modes\gcm\Tables8kGcmMultiplier.cs" />
     <Compile Include="src\crypto\operators\Asn1Signature.cs" />
+    <Compile Include="src\crypto\operators\DefaultSignatureCalculator.cs" />
+    <Compile Include="src\crypto\operators\DefaultSignatureResult.cs" />
+    <Compile Include="src\crypto\operators\DefaultVerifierCalculator.cs" />
+    <Compile Include="src\crypto\operators\DefaultVerifierResult.cs" />
     <Compile Include="src\crypto\paddings\BlockCipherPadding.cs" />
     <Compile Include="src\crypto\paddings\ISO10126d2Padding.cs" />
     <Compile Include="src\crypto\paddings\ISO7816d4Padding.cs" />
diff --git a/crypto/BouncyCastle.iOS.csproj b/crypto/BouncyCastle.iOS.csproj
index ad433e3dc..34e7b4ec3 100644
--- a/crypto/BouncyCastle.iOS.csproj
+++ b/crypto/BouncyCastle.iOS.csproj
@@ -597,7 +597,6 @@
     <Compile Include="src\cms\CounterSignatureDigestCalculator.cs" />
     <Compile Include="src\cms\DefaultAuthenticatedAttributeTableGenerator.cs" />
     <Compile Include="src\cms\DefaultSignedAttributeTableGenerator.cs" />
-    <Compile Include="src\cms\DigOutputStream.cs" />
     <Compile Include="src\cms\IDigestCalculator.cs" />
     <Compile Include="src\cms\KEKRecipientInfoGenerator.cs" />
     <Compile Include="src\cms\KEKRecipientInformation.cs" />
@@ -605,7 +604,6 @@
     <Compile Include="src\cms\KeyAgreeRecipientInformation.cs" />
     <Compile Include="src\cms\KeyTransRecipientInfoGenerator.cs" />
     <Compile Include="src\cms\KeyTransRecipientInformation.cs" />
-    <Compile Include="src\cms\MacOutputStream.cs" />
     <Compile Include="src\cms\OriginatorId.cs" />
     <Compile Include="src\cms\OriginatorInfoGenerator.cs" />
     <Compile Include="src\cms\OriginatorInformation.cs" />
@@ -617,7 +615,6 @@
     <Compile Include="src\cms\RecipientInfoGenerator.cs" />
     <Compile Include="src\cms\RecipientInformation.cs" />
     <Compile Include="src\cms\RecipientInformationStore.cs" />
-    <Compile Include="src\cms\SigOutputStream.cs" />
     <Compile Include="src\cms\SignerId.cs" />
     <Compile Include="src\cms\SignerInfoGenerator.cs" />
     <Compile Include="src\cms\SignerInformation.cs" />
@@ -836,8 +833,11 @@
     <Compile Include="src\crypto\generators\X25519KeyPairGenerator.cs" />
     <Compile Include="src\crypto\generators\X448KeyPairGenerator.cs" />
     <Compile Include="src\crypto\io\CipherStream.cs" />
+    <Compile Include="src\crypto\io\DigestSink.cs" />
     <Compile Include="src\crypto\io\DigestStream.cs" />
+    <Compile Include="src\crypto\io\MacSink.cs" />
     <Compile Include="src\crypto\io\MacStream.cs" />
+    <Compile Include="src\crypto\io\SignerSink.cs" />
     <Compile Include="src\crypto\io\SignerStream.cs" />
     <Compile Include="src\crypto\macs\CMac.cs" />
     <Compile Include="src\crypto\macs\CbcBlockCipherMac.cs" />
@@ -875,6 +875,10 @@
     <Compile Include="src\crypto\modes\gcm\Tables64kGcmMultiplier.cs" />
     <Compile Include="src\crypto\modes\gcm\Tables8kGcmMultiplier.cs" />
     <Compile Include="src\crypto\operators\Asn1Signature.cs" />
+    <Compile Include="src\crypto\operators\DefaultSignatureCalculator.cs" />
+    <Compile Include="src\crypto\operators\DefaultSignatureResult.cs" />
+    <Compile Include="src\crypto\operators\DefaultVerifierCalculator.cs" />
+    <Compile Include="src\crypto\operators\DefaultVerifierResult.cs" />
     <Compile Include="src\crypto\paddings\BlockCipherPadding.cs" />
     <Compile Include="src\crypto\paddings\ISO10126d2Padding.cs" />
     <Compile Include="src\crypto\paddings\ISO7816d4Padding.cs" />
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj
index d0f672e8e..85cf632c8 100644
--- a/crypto/crypto.csproj
+++ b/crypto/crypto.csproj
@@ -2869,11 +2869,6 @@
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "src\cms\DigOutputStream.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-                <File
                     RelPath = "src\cms\IDigestCalculator.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -2909,11 +2904,6 @@
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "src\cms\MacOutputStream.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-                <File
                     RelPath = "src\cms\OriginatorId.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -2989,11 +2979,6 @@
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "src\cms\SigOutputStream.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-                <File
                     RelPath = "src\cms\SimpleAttributeTableGenerator.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -3989,16 +3974,31 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\crypto\io\DigestSink.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\crypto\io\DigestStream.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\crypto\io\MacSink.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\crypto\io\MacStream.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\crypto\io\SignerSink.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\crypto\io\SignerStream.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -4184,6 +4184,26 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\crypto\operators\DefaultSignatureCalculator.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "src\crypto\operators\DefaultSignatureResult.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "src\crypto\operators\DefaultVerifierCalculator.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "src\crypto\operators\DefaultVerifierResult.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\crypto\paddings\BlockCipherPadding.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
diff --git a/crypto/src/cms/CMSAuthenticatedDataGenerator.cs b/crypto/src/cms/CMSAuthenticatedDataGenerator.cs
index 131a4753f..addd14c7d 100644
--- a/crypto/src/cms/CMSAuthenticatedDataGenerator.cs
+++ b/crypto/src/cms/CMSAuthenticatedDataGenerator.cs
@@ -80,7 +80,7 @@ namespace Org.BouncyCastle.Cms
 				mac.Init(encKey);
 
 				MemoryStream bOut = new MemoryStream();
-				Stream mOut = new TeeOutputStream(bOut, new MacOutputStream(mac));
+				Stream mOut = new TeeOutputStream(bOut, new MacSink(mac));
 
 				content.Write(mOut);
 
diff --git a/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs b/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs
index 4d18d10d4..9d9e2450c 100644
--- a/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs
+++ b/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs
@@ -168,7 +168,7 @@ namespace Org.BouncyCastle.Cms
                 IMac mac = MacUtilities.GetMac(macAlgId.Algorithm);
 				// TODO Confirm no ParametersWithRandom needed
 	            mac.Init(cipherParameters);
-				Stream mOut = new TeeOutputStream(octetOutputStream, new MacOutputStream(mac));
+				Stream mOut = new TeeOutputStream(octetOutputStream, new MacSink(mac));
 
 				return new CmsAuthenticatedDataOutputStream(mOut, mac, cGen, authGen, eiGen);
 			}
diff --git a/crypto/src/cms/CMSEnvelopedHelper.cs b/crypto/src/cms/CMSEnvelopedHelper.cs
index 77d2da47a..930ffcbf1 100644
--- a/crypto/src/cms/CMSEnvelopedHelper.cs
+++ b/crypto/src/cms/CMSEnvelopedHelper.cs
@@ -223,7 +223,7 @@ namespace Org.BouncyCastle.Cms
 					return new CmsProcessableInputStream(
 						new TeeInputStream(
 							readable.GetInputStream(),
-							new MacOutputStream(this.mac)));
+							new MacSink(this.mac)));
 				}
 				catch (IOException e)
 				{
diff --git a/crypto/src/cms/CMSSignedDataGenerator.cs b/crypto/src/cms/CMSSignedDataGenerator.cs
index 5aa5f92ab..f2676a440 100644
--- a/crypto/src/cms/CMSSignedDataGenerator.cs
+++ b/crypto/src/cms/CMSSignedDataGenerator.cs
@@ -6,6 +6,7 @@ using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Cms;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.IO;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Security.Certificates;
 using Org.BouncyCastle.Utilities;
@@ -128,7 +129,7 @@ namespace Org.BouncyCastle.Cms
                     IDigest dig = Helper.GetDigestInstance(digestName);
                     if (content != null)
                     {
-                        content.Write(new DigOutputStream(dig));
+                        content.Write(new DigestSink(dig));
                     }
                     hash = DigestUtilities.DoFinal(dig);
                     outer._digests.Add(digestOID, hash.Clone());
diff --git a/crypto/src/cms/CMSSignedDataStreamGenerator.cs b/crypto/src/cms/CMSSignedDataStreamGenerator.cs
index 1cea087f3..0a3e0c87e 100644
--- a/crypto/src/cms/CMSSignedDataStreamGenerator.cs
+++ b/crypto/src/cms/CMSSignedDataStreamGenerator.cs
@@ -746,7 +746,7 @@ namespace Org.BouncyCastle.Cms
 			Stream result = s;
 			foreach (IDigest digest in digests)
 			{
-				result = GetSafeTeeOutputStream(result, new DigOutputStream(digest));
+				result = GetSafeTeeOutputStream(result, new DigestSink(digest));
 			}
 			return result;
 		}
diff --git a/crypto/src/cms/DigOutputStream.cs b/crypto/src/cms/DigOutputStream.cs
deleted file mode 100644
index 103b45cac..000000000
--- a/crypto/src/cms/DigOutputStream.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-
-using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Utilities.IO;
-
-namespace Org.BouncyCastle.Cms
-{
-	internal class DigOutputStream
-		: BaseOutputStream
-	{
-		private readonly IDigest dig;
-
-		internal DigOutputStream(IDigest dig)
-		{
-			this.dig = dig;
-		}
-
-		public override void WriteByte(byte b)
-		{
-			dig.Update(b);
-		}
-
-		public override void Write(byte[] b, int off, int len)
-		{
-			dig.BlockUpdate(b, off, len);
-		}
-	}
-}
diff --git a/crypto/src/cms/MacOutputStream.cs b/crypto/src/cms/MacOutputStream.cs
deleted file mode 100644
index 8891dbc2c..000000000
--- a/crypto/src/cms/MacOutputStream.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-
-using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Utilities.IO;
-
-namespace Org.BouncyCastle.Cms
-{
-	internal class MacOutputStream
-		: BaseOutputStream
-	{
-		private readonly IMac mac;
-
-		internal MacOutputStream(IMac mac)
-		{
-			this.mac = mac;
-		}
-
-		public override void Write(byte[] b, int off, int len)
-		{
-			mac.BlockUpdate(b, off, len);
-		}
-
-		public override void WriteByte(byte b)
-		{
-			mac.Update(b);
-		}
-	}
-}
diff --git a/crypto/src/cms/SigOutputStream.cs b/crypto/src/cms/SigOutputStream.cs
deleted file mode 100644
index a807fa7fc..000000000
--- a/crypto/src/cms/SigOutputStream.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System;
-
-using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Utilities.IO;
-using Org.BouncyCastle.Security;
-
-namespace Org.BouncyCastle.Cms
-{
-	internal class SigOutputStream
-		: BaseOutputStream
-	{
-		private readonly ISigner sig;
-
-		internal SigOutputStream(ISigner sig)
-		{
-			this.sig = sig;
-		}
-
-		public override void WriteByte(byte b)
-		{
-			try
-			{
-				sig.Update(b);
-			}
-			catch (SignatureException e)
-			{
-				throw new CmsStreamException("signature problem: " + e);
-			}
-		}
-
-		public override void Write(byte[] b, int off, int len)
-		{
-			try
-			{
-				sig.BlockUpdate(b, off, len);
-			}
-			catch (SignatureException e)
-			{
-				throw new CmsStreamException("signature problem: " + e);
-			}
-		}
-	}
-}
\ No newline at end of file
diff --git a/crypto/src/cms/SignerInformation.cs b/crypto/src/cms/SignerInformation.cs
index 39ecfa6d3..c262806a8 100644
--- a/crypto/src/cms/SignerInformation.cs
+++ b/crypto/src/cms/SignerInformation.cs
@@ -8,6 +8,7 @@ using Org.BouncyCastle.Asn1.Cms;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Crypto.IO;
 using Org.BouncyCastle.Crypto.Signers;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Utilities;
@@ -387,7 +388,7 @@ namespace Org.BouncyCastle.Cms
 				{
 					if (content != null)
 					{
-						content.Write(new DigOutputStream(digest));
+						content.Write(new DigestSink(digest));
 					}
 					else if (signedAttributeSet == null)
 					{
@@ -485,8 +486,15 @@ namespace Org.BouncyCastle.Cms
 					}
 					else if (content != null)
 					{
-						// TODO Use raw signature of the hash value instead
-						content.Write(new SigOutputStream(sig));
+                        try
+                        {
+                            // TODO Use raw signature of the hash value instead
+                            content.Write(new SignerSink(sig));
+                        }
+                        catch (SignatureException e)
+                        {
+                            throw new CmsStreamException("signature problem: " + e);
+                        }
 					}
 				}
 				else
diff --git a/crypto/src/crypto/IRsa.cs b/crypto/src/crypto/IRsa.cs
new file mode 100644
index 000000000..f7bcc9e5a
--- /dev/null
+++ b/crypto/src/crypto/IRsa.cs
@@ -0,0 +1,16 @@
+using System;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Crypto
+{
+    public interface IRsa
+    {
+        void Init(bool forEncryption, ICipherParameters parameters);
+        int GetInputBlockSize();
+        int GetOutputBlockSize();
+        BigInteger ConvertInput(byte[] buf, int off, int len);
+        BigInteger ProcessBlock(BigInteger input);
+        byte[] ConvertOutput(BigInteger result);
+    }
+}
diff --git a/crypto/src/crypto/engines/RSABlindedEngine.cs b/crypto/src/crypto/engines/RSABlindedEngine.cs
index f95f145f6..7b928c5fb 100644
--- a/crypto/src/crypto/engines/RSABlindedEngine.cs
+++ b/crypto/src/crypto/engines/RSABlindedEngine.cs
@@ -13,10 +13,21 @@ namespace Org.BouncyCastle.Crypto.Engines
     public class RsaBlindedEngine
         : IAsymmetricBlockCipher
     {
-        private readonly RsaCoreEngine core = new RsaCoreEngine();
+        private readonly IRsa core;
+
         private RsaKeyParameters key;
         private SecureRandom random;
 
+        public RsaBlindedEngine()
+            : this(new RsaCoreEngine())
+        {
+        }
+
+        public RsaBlindedEngine(IRsa rsa)
+        {
+            this.core = rsa;
+        }
+
         public virtual string AlgorithmName
         {
             get { return "RSA"; }
diff --git a/crypto/src/crypto/engines/RSABlindingEngine.cs b/crypto/src/crypto/engines/RSABlindingEngine.cs
index c636627bf..1289456a6 100644
--- a/crypto/src/crypto/engines/RSABlindingEngine.cs
+++ b/crypto/src/crypto/engines/RSABlindingEngine.cs
@@ -14,13 +14,23 @@ namespace Org.BouncyCastle.Crypto.Engines
 	public class RsaBlindingEngine
 		: IAsymmetricBlockCipher
 	{
-		private readonly RsaCoreEngine core = new RsaCoreEngine();
+		private readonly IRsa core;
 
 		private RsaKeyParameters key;
 		private BigInteger blindingFactor;
 
 		private bool forEncryption;
 
+        public RsaBlindingEngine()
+            : this(new RsaCoreEngine())
+        {
+        }
+
+        public RsaBlindingEngine(IRsa rsa)
+        {
+            this.core = rsa;
+        }
+
         public virtual string AlgorithmName
 		{
 			get { return "RSA"; }
diff --git a/crypto/src/crypto/engines/RSACoreEngine.cs b/crypto/src/crypto/engines/RSACoreEngine.cs
index fd44e3cc1..5f6e98eea 100644
--- a/crypto/src/crypto/engines/RSACoreEngine.cs
+++ b/crypto/src/crypto/engines/RSACoreEngine.cs
@@ -9,13 +9,20 @@ namespace Org.BouncyCastle.Crypto.Engines
 	/**
 	* this does your basic RSA algorithm.
 	*/
-	class RsaCoreEngine
+	public class RsaCoreEngine
+        : IRsa
 	{
 		private RsaKeyParameters	key;
 		private bool				forEncryption;
 		private int					bitSize;
 
-		/**
+        private void CheckInitialised()
+        {
+            if (key == null)
+                throw new InvalidOperationException("RSA engine not initialised");
+        }
+
+        /**
 		* initialise the RSA engine.
 		*
 		* @param forEncryption true if we are encrypting, false otherwise.
@@ -47,6 +54,8 @@ namespace Org.BouncyCastle.Crypto.Engines
 		*/
         public virtual int GetInputBlockSize()
 		{
+            CheckInitialised();
+
 			if (forEncryption)
 			{
 				return (bitSize - 1) / 8;
@@ -64,7 +73,9 @@ namespace Org.BouncyCastle.Crypto.Engines
 		*/
         public virtual int GetOutputBlockSize()
 		{
-			if (forEncryption)
+            CheckInitialised();
+
+            if (forEncryption)
 			{
 				return (bitSize + 7) / 8;
 			}
@@ -77,7 +88,9 @@ namespace Org.BouncyCastle.Crypto.Engines
 			int		inOff,
 			int		inLen)
 		{
-			int maxLength = (bitSize + 7) / 8;
+            CheckInitialised();
+
+            int maxLength = (bitSize + 7) / 8;
 
 			if (inLen > maxLength)
 				throw new DataLengthException("input too large for RSA cipher.");
@@ -93,7 +106,9 @@ namespace Org.BouncyCastle.Crypto.Engines
         public virtual byte[] ConvertOutput(
 			BigInteger result)
 		{
-			byte[] output = result.ToByteArrayUnsigned();
+            CheckInitialised();
+
+            byte[] output = result.ToByteArrayUnsigned();
 
 			if (forEncryption)
 			{
@@ -115,7 +130,9 @@ namespace Org.BouncyCastle.Crypto.Engines
         public virtual BigInteger ProcessBlock(
 			BigInteger input)
 		{
-			if (key is RsaPrivateCrtKeyParameters)
+            CheckInitialised();
+
+            if (key is RsaPrivateCrtKeyParameters)
 			{
 				//
 				// we have the extra factors, use the Chinese Remainder Theorem - the author
diff --git a/crypto/src/crypto/engines/RsaEngine.cs b/crypto/src/crypto/engines/RsaEngine.cs
index 4399b4409..95bfb2371 100644
--- a/crypto/src/crypto/engines/RsaEngine.cs
+++ b/crypto/src/crypto/engines/RsaEngine.cs
@@ -1,5 +1,7 @@
 using System;
 
+using Org.BouncyCastle.Math;
+
 namespace Org.BouncyCastle.Crypto.Engines
 {
     /**
@@ -8,7 +10,17 @@ namespace Org.BouncyCastle.Crypto.Engines
     public class RsaEngine
 		: IAsymmetricBlockCipher
     {
-		private RsaCoreEngine core;
+		private readonly IRsa core;
+
+        public RsaEngine()
+            : this(new RsaCoreEngine())
+        {
+        }
+
+        public RsaEngine(IRsa rsa)
+        {
+            this.core = rsa;
+        }
 
         public virtual string AlgorithmName
         {
@@ -25,9 +37,6 @@ namespace Org.BouncyCastle.Crypto.Engines
             bool				forEncryption,
             ICipherParameters	parameters)
         {
-			if (core == null)
-				core = new RsaCoreEngine();
-
 			core.Init(forEncryption, parameters);
 		}
 
@@ -69,10 +78,9 @@ namespace Org.BouncyCastle.Crypto.Engines
             int		inOff,
             int		inLen)
         {
-			if (core == null)
-				throw new InvalidOperationException("RSA engine not initialised");
-
-			return core.ConvertOutput(core.ProcessBlock(core.ConvertInput(inBuf, inOff, inLen)));
+            BigInteger input = core.ConvertInput(inBuf, inOff, inLen);
+            BigInteger output = core.ProcessBlock(input);
+			return core.ConvertOutput(output);
         }
     }
 }
diff --git a/crypto/src/crypto/io/DigestSink.cs b/crypto/src/crypto/io/DigestSink.cs
new file mode 100644
index 000000000..98307e5f7
--- /dev/null
+++ b/crypto/src/crypto/io/DigestSink.cs
@@ -0,0 +1,35 @@
+using System;
+
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.Crypto.IO
+{
+    public class DigestSink
+        : BaseOutputStream
+    {
+        private readonly IDigest mDigest;
+
+        public DigestSink(IDigest digest)
+        {
+            this.mDigest = digest;
+        }
+
+        public virtual IDigest Digest
+        {
+            get { return mDigest; }
+        }
+
+        public override void WriteByte(byte b)
+        {
+            mDigest.Update(b);
+        }
+
+        public override void Write(byte[] buf, int off, int len)
+        {
+            if (len > 0)
+            {
+                mDigest.BlockUpdate(buf, off, len);
+            }
+        }
+    }
+}
diff --git a/crypto/src/crypto/io/MacSink.cs b/crypto/src/crypto/io/MacSink.cs
new file mode 100644
index 000000000..c4fe7169a
--- /dev/null
+++ b/crypto/src/crypto/io/MacSink.cs
@@ -0,0 +1,35 @@
+using System;
+
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.Crypto.IO
+{
+    public class MacSink
+        : BaseOutputStream
+    {
+        private readonly IMac mMac;
+
+        public MacSink(IMac mac)
+        {
+            this.mMac = mac;
+        }
+
+        public virtual IMac Mac
+        {
+            get { return mMac; }
+        }
+
+        public override void WriteByte(byte b)
+        {
+            mMac.Update(b);
+        }
+
+        public override void Write(byte[] buf, int off, int len)
+        {
+            if (len > 0)
+            {
+                mMac.BlockUpdate(buf, off, len);
+            }
+        }
+    }
+}
diff --git a/crypto/src/crypto/io/SignerSink.cs b/crypto/src/crypto/io/SignerSink.cs
new file mode 100644
index 000000000..c9bd8b9c8
--- /dev/null
+++ b/crypto/src/crypto/io/SignerSink.cs
@@ -0,0 +1,35 @@
+using System;
+
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.Crypto.IO
+{
+    public class SignerSink
+		: BaseOutputStream
+	{
+		private readonly ISigner mSigner;
+
+        public SignerSink(ISigner signer)
+		{
+            this.mSigner = signer;
+		}
+
+        public virtual ISigner Signer
+        {
+            get { return mSigner; }
+        }
+
+		public override void WriteByte(byte b)
+		{
+            mSigner.Update(b);
+		}
+
+		public override void Write(byte[] buf, int off, int len)
+		{
+			if (len > 0)
+			{
+				mSigner.BlockUpdate(buf, off, len);
+			}
+		}
+	}
+}
diff --git a/crypto/src/crypto/operators/Asn1Signature.cs b/crypto/src/crypto/operators/Asn1Signature.cs
index 373ba0cee..3fa193273 100644
--- a/crypto/src/crypto/operators/Asn1Signature.cs
+++ b/crypto/src/crypto/operators/Asn1Signature.cs
@@ -236,91 +236,6 @@ namespace Org.BouncyCastle.Crypto.Operators
 		}
 	}
 
-	internal class SignerBucket
-		: Stream
-	{
-		protected readonly ISigner signer;
-
-		public SignerBucket(
-			ISigner	signer)
-		{
-			this.signer = signer;
-		}
-
-		public override int Read(
-			byte[]	buffer,
-			int		offset,
-			int		count)
-		{
-			throw new NotImplementedException ();
-		}
-
-		public override int ReadByte()
-		{
-			throw new NotImplementedException ();
-		}
-
-		public override void Write(
-			byte[]	buffer,
-			int		offset,
-			int		count)
-		{
-			if (count > 0)
-			{
-				signer.BlockUpdate(buffer, offset, count);
-			}
-		}
-
-		public override void WriteByte(
-			byte b)
-		{
-			signer.Update(b);
-		}
-
-		public override bool CanRead
-		{
-			get { return false; }
-		}
-
-		public override bool CanWrite
-		{
-			get { return true; }
-		}
-
-		public override bool CanSeek
-		{
-			get { return false; }
-		}
-
-		public override long Length
-		{
-			get { return 0; }
-		}
-
-		public override long Position
-		{
-			get { throw new NotImplementedException (); }
-			set { throw new NotImplementedException (); }
-		}
-
-        public override void Flush()
-		{
-		}
-
-		public override long Seek(
-			long		offset,
-			SeekOrigin	origin)
-		{
-			throw new NotImplementedException ();
-		}
-
-		public override void SetLength(
-			long length)
-		{
-			throw new NotImplementedException ();
-		}
-	}
-
     /// <summary>
     /// Calculator factory class for signature generation in ASN.1 based profiles that use an AlgorithmIdentifier to preserve
     /// signature algorithm details.
@@ -373,14 +288,9 @@ namespace Org.BouncyCastle.Crypto.Operators
 
         public IStreamCalculator CreateCalculator()
         {
-            ISigner sig = SignerUtilities.GetSigner(algorithm);
-            ICipherParameters cp = privateKey;
-            if (random != null)
-            {
-                cp = new ParametersWithRandom(cp, random);
-            }
-            sig.Init(true, cp);
-            return new SigCalculator(sig);
+            ISigner signer = SignerUtilities.InitSigner(algorithm, true, privateKey, random);
+
+            return new DefaultSignatureCalculator(signer);
         }
 
         /// <summary>
@@ -392,52 +302,6 @@ namespace Org.BouncyCastle.Crypto.Operators
         }
     }
 
-    internal class SigCalculator : IStreamCalculator
-    {
-        private readonly ISigner sig;
-        private readonly Stream stream;
-
-        internal SigCalculator(ISigner sig)
-        {
-            this.sig = sig;
-            this.stream = new SignerBucket(sig);
-        }
-
-        public Stream Stream
-        {
-            get { return stream; }
-        }
-
-        public object GetResult()
-        {
-            return new SigResult(sig);
-        }
-    }
-
-    internal class SigResult : IBlockResult
-    {
-        private readonly ISigner sig;
-
-        internal SigResult(ISigner sig)
-        {
-            this.sig = sig;
-        }
-
-        public byte[] Collect()
-        {
-            return sig.GenerateSignature();
-        }
-
-        public int Collect(byte[] destination, int offset)
-        {
-            byte[] signature = Collect();
-
-            Array.Copy(signature, 0, destination, offset, signature.Length);
-
-            return signature.Length;
-        }
-    }
-
     /// <summary>
     /// Verifier class for signature verification in ASN.1 based profiles that use an AlgorithmIdentifier to preserve
     /// signature algorithm details.
@@ -481,57 +345,9 @@ namespace Org.BouncyCastle.Crypto.Operators
 
         public IStreamCalculator CreateCalculator()
         {
-            ISigner sig = SignerUtilities.GetSigner(X509Utilities.GetSignatureName(algID));
-
-            sig.Init(false, publicKey);
-          
-            return new VerifierCalculator(sig);
-        }
-    }
-
-    internal class VerifierCalculator : IStreamCalculator
-    {
-        private readonly ISigner sig;
-        private readonly Stream stream;
-
-        internal VerifierCalculator(ISigner sig)
-        {
-            this.sig = sig;
-            this.stream = new SignerBucket(sig);
-        }
-
-        public Stream Stream
-        {
-            get { return stream; }
-        }
-
-        public object GetResult()
-        {
-            return new VerifierResult(sig);
-        }
-    }
-
-    internal class VerifierResult : IVerifier
-    {
-        private readonly ISigner sig;
-
-        internal VerifierResult(ISigner sig)
-        {
-            this.sig = sig;
-        }
-
-        public bool IsVerified(byte[] signature)
-        {
-            return sig.VerifySignature(signature);
-        }
-
-        public bool IsVerified(byte[] signature, int off, int length)
-        {
-            byte[] sigBytes = new byte[length];
-
-            Array.Copy(signature, 0, sigBytes, off, sigBytes.Length);
+            ISigner verifier = SignerUtilities.InitSigner(X509Utilities.GetSignatureName(algID), false, publicKey, null);
 
-            return sig.VerifySignature(signature);
+            return new DefaultVerifierCalculator(verifier);
         }
     }
 
diff --git a/crypto/src/crypto/operators/DefaultSignatureCalculator.cs b/crypto/src/crypto/operators/DefaultSignatureCalculator.cs
new file mode 100644
index 000000000..8ca1c01d9
--- /dev/null
+++ b/crypto/src/crypto/operators/DefaultSignatureCalculator.cs
@@ -0,0 +1,28 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Crypto.IO;
+
+namespace Org.BouncyCastle.Crypto.Operators
+{
+    public class DefaultSignatureCalculator
+        : IStreamCalculator
+    {
+        private readonly SignerSink mSignerSink;
+
+        public DefaultSignatureCalculator(ISigner signer)
+        {
+            this.mSignerSink = new SignerSink(signer);
+        }
+
+        public Stream Stream
+        {
+            get { return mSignerSink; }
+        }
+
+        public object GetResult()
+        {
+            return new DefaultSignatureResult(mSignerSink.Signer);
+        }
+    }
+}
diff --git a/crypto/src/crypto/operators/DefaultSignatureResult.cs b/crypto/src/crypto/operators/DefaultSignatureResult.cs
new file mode 100644
index 000000000..615f67dcb
--- /dev/null
+++ b/crypto/src/crypto/operators/DefaultSignatureResult.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Org.BouncyCastle.Crypto.Operators
+{
+    public class DefaultSignatureResult
+        : IBlockResult
+    {
+        private readonly ISigner mSigner;
+
+        public DefaultSignatureResult(ISigner signer)
+        {
+            this.mSigner = signer;
+        }
+
+        public byte[] Collect()
+        {
+            return mSigner.GenerateSignature();
+        }
+
+        public int Collect(byte[] sig, int sigOff)
+        {
+            byte[] signature = Collect();
+            signature.CopyTo(sig, sigOff);
+            return signature.Length;
+        }
+    }
+}
diff --git a/crypto/src/crypto/operators/DefaultVerifierCalculator.cs b/crypto/src/crypto/operators/DefaultVerifierCalculator.cs
new file mode 100644
index 000000000..c985e81a5
--- /dev/null
+++ b/crypto/src/crypto/operators/DefaultVerifierCalculator.cs
@@ -0,0 +1,28 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Crypto.IO;
+
+namespace Org.BouncyCastle.Crypto.Operators
+{
+    public class DefaultVerifierCalculator
+        : IStreamCalculator
+    {
+        private readonly SignerSink mSignerSink;
+
+        public DefaultVerifierCalculator(ISigner signer)
+        {
+            this.mSignerSink = new SignerSink(signer);
+        }
+
+        public Stream Stream
+        {
+            get { return mSignerSink; }
+        }
+
+        public object GetResult()
+        {
+            return new DefaultVerifierResult(mSignerSink.Signer);
+        }
+    }
+}
diff --git a/crypto/src/crypto/operators/DefaultVerifierResult.cs b/crypto/src/crypto/operators/DefaultVerifierResult.cs
new file mode 100644
index 000000000..fb259c8f8
--- /dev/null
+++ b/crypto/src/crypto/operators/DefaultVerifierResult.cs
@@ -0,0 +1,29 @@
+using System;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Operators
+{
+    public class DefaultVerifierResult
+        : IVerifier
+    {
+        private readonly ISigner mSigner;
+
+        public DefaultVerifierResult(ISigner signer)
+        {
+            this.mSigner = signer;
+        }
+
+        public bool IsVerified(byte[] signature)
+        {
+            return mSigner.VerifySignature(signature);
+        }
+
+        public bool IsVerified(byte[] sig, int sigOff, int sigLen)
+        {
+            byte[] signature = Arrays.CopyOfRange(sig, sigOff, sigOff + sigLen);
+
+            return IsVerified(signature);
+        }
+    }
+}
diff --git a/crypto/src/crypto/signers/RsaDigestSigner.cs b/crypto/src/crypto/signers/RsaDigestSigner.cs
index d9b19cf6b..b210de03e 100644
--- a/crypto/src/crypto/signers/RsaDigestSigner.cs
+++ b/crypto/src/crypto/signers/RsaDigestSigner.cs
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crypto.Signers
     public class RsaDigestSigner
         : ISigner
     {
-        private readonly IAsymmetricBlockCipher rsaEngine = new Pkcs1Encoding(new RsaBlindedEngine());
+        private readonly IAsymmetricBlockCipher rsaEngine;
         private readonly AlgorithmIdentifier algId;
         private readonly IDigest digest;
         private bool forSigning;
@@ -59,7 +59,18 @@ namespace Org.BouncyCastle.Crypto.Signers
         }
 
         public RsaDigestSigner(IDigest digest, AlgorithmIdentifier algId)
+            :   this(new RsaCoreEngine(), digest, algId)
         {
+        }
+
+        public RsaDigestSigner(IRsa rsa, IDigest digest, DerObjectIdentifier digestOid)
+            :   this(rsa, digest, new AlgorithmIdentifier(digestOid, DerNull.Instance))
+        {
+        }
+
+        public RsaDigestSigner(IRsa rsa, IDigest digest, AlgorithmIdentifier algId)
+        {
+            this.rsaEngine = new Pkcs1Encoding(new RsaBlindedEngine(rsa));
             this.digest = digest;
             this.algId = algId;
         }
diff --git a/crypto/src/security/ParameterUtilities.cs b/crypto/src/security/ParameterUtilities.cs
index 792067bba..dc6992833 100644
--- a/crypto/src/security/ParameterUtilities.cs
+++ b/crypto/src/security/ParameterUtilities.cs
@@ -299,6 +299,15 @@ namespace Org.BouncyCastle.Security
             throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
         }
 
+        public static ICipherParameters WithRandom(ICipherParameters cp, SecureRandom random)
+        {
+            if (random != null)
+            {
+                cp = new ParametersWithRandom(cp, random);
+            }
+            return cp;
+        }
+
         private static Asn1OctetString CreateIVOctetString(
             SecureRandom	random,
             int				ivLength)
diff --git a/crypto/src/security/SignerUtilities.cs b/crypto/src/security/SignerUtilities.cs
index a9045ae6e..6107bf878 100644
--- a/crypto/src/security/SignerUtilities.cs
+++ b/crypto/src/security/SignerUtilities.cs
@@ -602,5 +602,17 @@ namespace Org.BouncyCastle.Security
         {
             return (string) algorithms[oid.Id];
         }
+
+        public static ISigner InitSigner(DerObjectIdentifier algorithmOid, bool forSigning, AsymmetricKeyParameter privateKey, SecureRandom random)
+        {
+            return InitSigner(algorithmOid.Id, forSigning, privateKey, random);
+        }
+
+        public static ISigner InitSigner(string algorithm, bool forSigning, AsymmetricKeyParameter privateKey, SecureRandom random)
+        {
+            ISigner signer = SignerUtilities.GetSigner(algorithm);
+            signer.Init(forSigning, ParameterUtilities.WithRandom(privateKey, random));
+            return signer;
+        }
     }
 }