diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-03-09 16:05:24 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-03-09 16:05:24 +0700 |
commit | ec1991b40df8748b6c436807ce9d9ea5f146b13c (patch) | |
tree | 53204a26b6db0aaaf2f5854996d99d5abd7c4a39 /crypto/src | |
parent | Refactor TLS ciphersuite processing (diff) | |
download | BouncyCastle.NET-ed25519-ec1991b40df8748b6c436807ce9d9ea5f146b13c.tar.xz |
Port X931Signer and tests from Java
Diffstat (limited to 'crypto/src')
-rw-r--r-- | crypto/src/crypto/signers/DsaDigestSigner.cs | 14 | ||||
-rw-r--r-- | crypto/src/crypto/signers/ECGOST3410Signer.cs | 8 | ||||
-rw-r--r-- | crypto/src/crypto/signers/ECNRSigner.cs | 8 | ||||
-rw-r--r-- | crypto/src/crypto/signers/GOST3410DigestSigner.cs | 14 | ||||
-rw-r--r-- | crypto/src/crypto/signers/GOST3410Signer.cs | 8 | ||||
-rw-r--r-- | crypto/src/crypto/signers/GenericSigner.cs | 14 | ||||
-rw-r--r-- | crypto/src/crypto/signers/Iso9796d2PssSigner.cs | 4 | ||||
-rw-r--r-- | crypto/src/crypto/signers/Iso9796d2Signer.cs | 6 | ||||
-rw-r--r-- | crypto/src/crypto/signers/PssSigner.cs | 2 | ||||
-rw-r--r-- | crypto/src/crypto/signers/RsaDigestSigner.cs | 15 | ||||
-rw-r--r-- | crypto/src/crypto/signers/X931Signer.cs | 235 |
11 files changed, 281 insertions, 47 deletions
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; + } + } +} |