diff --git a/crypto/src/crypto/signers/DsaDigestSigner.cs b/crypto/src/crypto/signers/DsaDigestSigner.cs
index aee713450..086601481 100644
--- a/crypto/src/crypto/signers/DsaDigestSigner.cs
+++ b/crypto/src/crypto/signers/DsaDigestSigner.cs
@@ -26,12 +26,12 @@ namespace Org.BouncyCastle.Crypto.Signers
this.dsaSigner = signer;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; }
}
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte b
*/
- public void Update(
+ public virtual void Update(
byte input)
{
digest.Update(input);
@@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte array in
*/
- public void BlockUpdate(
+ public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
@@ -83,7 +83,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* Generate a signature for the message we've been loaded with using
* the key we were initialised with.
*/
- public byte[] GenerateSignature()
+ public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("DSADigestSigner not initialised for signature generation.");
@@ -97,7 +97,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <returns>true if the internal state represents the signature described in the passed in array.</returns>
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] signature)
{
if (forSigning)
@@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <summary>Reset the internal state</summary>
- public void Reset()
+ public virtual void Reset()
{
digest.Reset();
}
diff --git a/crypto/src/crypto/signers/ECGOST3410Signer.cs b/crypto/src/crypto/signers/ECGOST3410Signer.cs
index 6027aa9b9..28ab79c1c 100644
--- a/crypto/src/crypto/signers/ECGOST3410Signer.cs
+++ b/crypto/src/crypto/signers/ECGOST3410Signer.cs
@@ -18,12 +18,12 @@ namespace Org.BouncyCastle.Crypto.Signers
private ECKeyParameters key;
private SecureRandom random;
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "ECGOST3410"; }
}
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Signers
*
* @param message the message that will be verified later.
*/
- public BigInteger[] GenerateSignature(
+ public virtual BigInteger[] GenerateSignature(
byte[] message)
{
byte[] mRev = new byte[message.Length]; // conversion is little-endian
@@ -110,7 +110,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* the passed in message (for standard GOST3410 the message should be
* a GOST3411 hash of the real message to be verified).
*/
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] message,
BigInteger r,
BigInteger s)
diff --git a/crypto/src/crypto/signers/ECNRSigner.cs b/crypto/src/crypto/signers/ECNRSigner.cs
index cae15bdbf..bb21a4994 100644
--- a/crypto/src/crypto/signers/ECNRSigner.cs
+++ b/crypto/src/crypto/signers/ECNRSigner.cs
@@ -19,12 +19,12 @@ namespace Org.BouncyCastle.Crypto.Signers
private ECKeyParameters key;
private SecureRandom random;
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "ECNR"; }
}
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -68,7 +68,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* @param digest the digest to be signed.
* @exception DataLengthException if the digest is longer than the key allows
*/
- public BigInteger[] GenerateSignature(
+ public virtual BigInteger[] GenerateSignature(
byte[] message)
{
if (!this.forSigning)
@@ -134,7 +134,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* @param s the s value of the signature.
* @exception DataLengthException if the digest is longer than the key allows
*/
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] message,
BigInteger r,
BigInteger s)
diff --git a/crypto/src/crypto/signers/GOST3410DigestSigner.cs b/crypto/src/crypto/signers/GOST3410DigestSigner.cs
index 58aefa368..bc32808df 100644
--- a/crypto/src/crypto/signers/GOST3410DigestSigner.cs
+++ b/crypto/src/crypto/signers/GOST3410DigestSigner.cs
@@ -26,12 +26,12 @@ namespace Org.BouncyCastle.Crypto.Signers
this.digest = digest;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; }
}
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -65,7 +65,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte b
*/
- public void Update(
+ public virtual void Update(
byte input)
{
digest.Update(input);
@@ -74,7 +74,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte array in
*/
- public void BlockUpdate(
+ public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
@@ -86,7 +86,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* Generate a signature for the message we've been loaded with using
* the key we were initialised with.
*/
- public byte[] GenerateSignature()
+ public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("GOST3410DigestSigner not initialised for signature generation.");
@@ -113,7 +113,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <returns>true if the internal state represents the signature described in the passed in array.</returns>
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] signature)
{
if (forSigning)
@@ -137,7 +137,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <summary>Reset the internal state</summary>
- public void Reset()
+ public virtual void Reset()
{
digest.Reset();
}
diff --git a/crypto/src/crypto/signers/GOST3410Signer.cs b/crypto/src/crypto/signers/GOST3410Signer.cs
index 375eeb5cc..f1832ae37 100644
--- a/crypto/src/crypto/signers/GOST3410Signer.cs
+++ b/crypto/src/crypto/signers/GOST3410Signer.cs
@@ -15,12 +15,12 @@ namespace Org.BouncyCastle.Crypto.Signers
private Gost3410KeyParameters key;
private SecureRandom random;
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "GOST3410"; }
}
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -59,7 +59,7 @@ namespace Org.BouncyCastle.Crypto.Signers
*
* @param message the message that will be verified later.
*/
- public BigInteger[] GenerateSignature(
+ public virtual BigInteger[] GenerateSignature(
byte[] message)
{
byte[] mRev = new byte[message.Length]; // conversion is little-endian
@@ -92,7 +92,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* the passed in message for standard Gost3410 the message should be a
* Gost3411 hash of the real message to be verified.
*/
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] message,
BigInteger r,
BigInteger s)
diff --git a/crypto/src/crypto/signers/GenericSigner.cs b/crypto/src/crypto/signers/GenericSigner.cs
index 5035b454d..a5512176f 100644
--- a/crypto/src/crypto/signers/GenericSigner.cs
+++ b/crypto/src/crypto/signers/GenericSigner.cs
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crypto.Signers
this.digest = digest;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "Generic(" + engine.AlgorithmName + "/" + digest.AlgorithmName + ")"; }
}
@@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* @param parameters
* necessary parameters.
*/
- public void Init(bool forSigning, ICipherParameters parameters)
+ public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte b
*/
- public void Update(byte input)
+ public virtual void Update(byte input)
{
digest.Update(input);
}
@@ -70,7 +70,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte array in
*/
- public void BlockUpdate(byte[] input, int inOff, int length)
+ public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
digest.BlockUpdate(input, inOff, length);
}
@@ -79,7 +79,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* Generate a signature for the message we've been loaded with using the key
* we were initialised with.
*/
- public byte[] GenerateSignature()
+ public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("GenericSigner not initialised for signature generation.");
@@ -94,7 +94,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* return true if the internal state represents the signature described in
* the passed in array.
*/
- public bool VerifySignature(byte[] signature)
+ public virtual bool VerifySignature(byte[] signature)
{
if (forSigning)
throw new InvalidOperationException("GenericSigner not initialised for verification");
@@ -122,7 +122,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
}
- public void Reset()
+ public virtual void Reset()
{
digest.Reset();
}
diff --git a/crypto/src/crypto/signers/Iso9796d2PssSigner.cs b/crypto/src/crypto/signers/Iso9796d2PssSigner.cs
index d4f6c5522..1486656bd 100644
--- a/crypto/src/crypto/signers/Iso9796d2PssSigner.cs
+++ b/crypto/src/crypto/signers/Iso9796d2PssSigner.cs
@@ -120,7 +120,7 @@ namespace Org.BouncyCastle.Crypto.Signers
{
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + "ISO9796-2S2"; }
}
@@ -365,7 +365,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/// <summary> Generate a signature for the loaded message using the key we were
/// initialised with.
/// </summary>
- public byte[] GenerateSignature()
+ public virtual byte[] GenerateSignature()
{
int digSize = digest.GetDigestSize();
byte[] m2Hash = new byte[digSize];
diff --git a/crypto/src/crypto/signers/Iso9796d2Signer.cs b/crypto/src/crypto/signers/Iso9796d2Signer.cs
index cfb8942e6..4bb4d17a6 100644
--- a/crypto/src/crypto/signers/Iso9796d2Signer.cs
+++ b/crypto/src/crypto/signers/Iso9796d2Signer.cs
@@ -105,7 +105,7 @@ namespace Org.BouncyCastle.Crypto.Signers
{
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + "ISO9796-2S1"; }
}
@@ -252,7 +252,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <summary> update the internal digest with the byte b</summary>
- public void Update(
+ public virtual void Update(
byte input)
{
digest.Update(input);
@@ -266,7 +266,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <summary> update the internal digest with the byte array in</summary>
- public void BlockUpdate(
+ public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
diff --git a/crypto/src/crypto/signers/PssSigner.cs b/crypto/src/crypto/signers/PssSigner.cs
index 6900224f3..03890902b 100644
--- a/crypto/src/crypto/signers/PssSigner.cs
+++ b/crypto/src/crypto/signers/PssSigner.cs
@@ -115,7 +115,7 @@ namespace Org.BouncyCastle.Crypto.Signers
this.trailer = trailer;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return mgfDigest.AlgorithmName + "withRSAandMGF1"; }
}
diff --git a/crypto/src/crypto/signers/RsaDigestSigner.cs b/crypto/src/crypto/signers/RsaDigestSigner.cs
index 9af4e7145..d9b19cf6b 100644
--- a/crypto/src/crypto/signers/RsaDigestSigner.cs
+++ b/crypto/src/crypto/signers/RsaDigestSigner.cs
@@ -64,8 +64,7 @@ namespace Org.BouncyCastle.Crypto.Signers
this.algId = algId;
}
- [Obsolete]
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "withRSA"; }
}
@@ -76,7 +75,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* @param forSigning true if for signing, false otherwise
* @param param necessary parameters.
*/
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -106,7 +105,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte b
*/
- public void Update(
+ public virtual void Update(
byte input)
{
digest.Update(input);
@@ -115,7 +114,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte array in
*/
- public void BlockUpdate(
+ public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
@@ -127,7 +126,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* Generate a signature for the message we've been loaded with using
* the key we were initialised with.
*/
- public byte[] GenerateSignature()
+ public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("RsaDigestSigner not initialised for signature generation.");
@@ -143,7 +142,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* return true if the internal state represents the signature described
* in the passed in array.
*/
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] signature)
{
if (forSigning)
@@ -197,7 +196,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
}
- public void Reset()
+ public virtual void Reset()
{
digest.Reset();
}
diff --git a/crypto/src/crypto/signers/X931Signer.cs b/crypto/src/crypto/signers/X931Signer.cs
new file mode 100644
index 000000000..cc3292159
--- /dev/null
+++ b/crypto/src/crypto/signers/X931Signer.cs
@@ -0,0 +1,235 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Signers
+{
+ /**
+ * X9.31-1998 - signing using a hash.
+ * <p>
+ * The message digest hash, H, is encapsulated to form a byte string as follows
+ * </p>
+ * <pre>
+ * EB = 06 || PS || 0xBA || H || TRAILER
+ * </pre>
+ * where PS is a string of bytes all of value 0xBB of length such that |EB|=|n|, and TRAILER is the ISO/IEC 10118 part number†for the digest. The byte string, EB, is converted to an integer value, the message representative, f.
+ */
+ public class X931Signer
+ : ISigner
+ {
+ public const int TRAILER_IMPLICIT = 0xBC;
+ public const int TRAILER_RIPEMD160 = 0x31CC;
+ public const int TRAILER_RIPEMD128 = 0x32CC;
+ public const int TRAILER_SHA1 = 0x33CC;
+ public const int TRAILER_SHA256 = 0x34CC;
+ public const int TRAILER_SHA512 = 0x35CC;
+ public const int TRAILER_SHA384 = 0x36CC;
+ public const int TRAILER_WHIRLPOOL = 0x37CC;
+ public const int TRAILER_SHA224 = 0x38CC;
+
+ private static readonly IDictionary trailerMap = Platform.CreateHashtable();
+
+ static X931Signer()
+ {
+ trailerMap.Add("RIPEMD128", TRAILER_RIPEMD128);
+ trailerMap.Add("RIPEMD160", TRAILER_RIPEMD160);
+
+ trailerMap.Add("SHA-1", TRAILER_SHA1);
+ trailerMap.Add("SHA-224", TRAILER_SHA224);
+ trailerMap.Add("SHA-256", TRAILER_SHA256);
+ trailerMap.Add("SHA-384", TRAILER_SHA384);
+ trailerMap.Add("SHA-512", TRAILER_SHA512);
+
+ trailerMap.Add("Whirlpool", TRAILER_WHIRLPOOL);
+ }
+
+ private IDigest digest;
+ private IAsymmetricBlockCipher cipher;
+ private RsaKeyParameters kParam;
+
+ private int trailer;
+ private int keyBits;
+ private byte[] block;
+
+ /**
+ * Generate a signer for the with either implicit or explicit trailers
+ * for ISO9796-2.
+ *
+ * @param cipher base cipher to use for signature creation/verification
+ * @param digest digest to use.
+ * @param implicit whether or not the trailer is implicit or gives the hash.
+ */
+ public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest, bool isImplicit)
+ {
+ this.cipher = cipher;
+ this.digest = digest;
+
+ if (isImplicit)
+ {
+ trailer = TRAILER_IMPLICIT;
+ }
+ else
+ {
+ string name = digest.AlgorithmName;
+ if (!trailerMap.Contains(name))
+ throw new ArgumentException("no valid trailer", "digest");
+
+ trailer = (int)trailerMap[name];
+ }
+ }
+
+ [Obsolete]
+ public virtual string AlgorithmName
+ {
+ get { return digest.AlgorithmName + "withX931"; }
+ }
+
+ /**
+ * Constructor for a signer with an explicit digest trailer.
+ *
+ * @param cipher cipher to use.
+ * @param digest digest to sign with.
+ */
+ public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest)
+ : this(cipher, digest, false)
+ {
+ }
+
+ public virtual void Init(bool forSigning, ICipherParameters parameters)
+ {
+ kParam = (RsaKeyParameters)parameters;
+
+ cipher.Init(forSigning, kParam);
+
+ keyBits = kParam.Modulus.BitLength;
+
+ block = new byte[(keyBits + 7) / 8];
+
+ Reset();
+ }
+
+ /// <summary> clear possible sensitive data</summary>
+ private void ClearBlock(byte[] block)
+ {
+ Array.Clear(block, 0, block.Length);
+ }
+
+ /**
+ * update the internal digest with the byte b
+ */
+ public virtual void Update(byte b)
+ {
+ digest.Update(b);
+ }
+
+ /**
+ * update the internal digest with the byte array in
+ */
+ public virtual void BlockUpdate(byte[] input, int off, int len)
+ {
+ digest.BlockUpdate(input, off, len);
+ }
+
+ /**
+ * reset the internal state
+ */
+ public virtual void Reset()
+ {
+ digest.Reset();
+ }
+
+ /**
+ * generate a signature for the loaded message using the key we were
+ * initialised with.
+ */
+ public virtual byte[] GenerateSignature()
+ {
+ CreateSignatureBlock();
+
+ BigInteger t = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length));
+ ClearBlock(block);
+
+ t = t.Min(kParam.Modulus.Subtract(t));
+
+ return BigIntegers.AsUnsignedByteArray((kParam.Modulus.BitLength + 7) / 8, t);
+ }
+
+ private void CreateSignatureBlock()
+ {
+ int digSize = digest.GetDigestSize();
+
+ int delta;
+
+ if (trailer == TRAILER_IMPLICIT)
+ {
+ delta = block.Length - digSize - 1;
+ digest.DoFinal(block, delta);
+ block[block.Length - 1] = (byte)TRAILER_IMPLICIT;
+ }
+ else
+ {
+ delta = block.Length - digSize - 2;
+ digest.DoFinal(block, delta);
+ block[block.Length - 2] = (byte)(trailer >> 8);
+ block[block.Length - 1] = (byte)trailer;
+ }
+
+ block[0] = 0x6b;
+ for (int i = delta - 2; i != 0; i--)
+ {
+ block[i] = (byte)0xbb;
+ }
+ block[delta - 1] = (byte)0xba;
+ }
+
+ /**
+ * return true if the signature represents a ISO9796-2 signature
+ * for the passed in message.
+ */
+ public virtual bool VerifySignature(byte[] signature)
+ {
+ try
+ {
+ block = cipher.ProcessBlock(signature, 0, signature.Length);
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+
+ BigInteger t = new BigInteger(block);
+ BigInteger f;
+
+ if ((t.IntValue & 15) == 12)
+ {
+ f = t;
+ }
+ else
+ {
+ t = kParam.Modulus.Subtract(t);
+ if ((t.IntValue & 15) == 12)
+ {
+ f = t;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ CreateSignatureBlock();
+
+ byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
+
+ bool rv = Arrays.ConstantTimeAreEqual(block, fBlock);
+
+ ClearBlock(block);
+ ClearBlock(fBlock);
+
+ return rv;
+ }
+ }
+}
|