123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
- using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
- using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
- using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Zlib;
- namespace Best.HTTP.SecureProtocol.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
- {
- private IDigest digest;
- private IAsymmetricBlockCipher cipher;
- private RsaKeyParameters kParam;
- private int trailer;
- private int keyBits;
- private byte[] block;
- /**
- * Generate a signer with either implicit or explicit trailers for X9.31.
- *
- * @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 = IsoTrailers.TRAILER_IMPLICIT;
- }
- else if (IsoTrailers.NoTrailerAvailable(digest))
- {
- throw new ArgumentException("no valid trailer", "digest");
- }
- else
- {
- trailer = IsoTrailers.GetTrailer(digest);
- }
- }
- public virtual string AlgorithmName
- {
- get { return digest.AlgorithmName + "with" + cipher.AlgorithmName + "/X9.31"; }
- }
- /**
- * 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();
- }
- public virtual void Update(byte b)
- {
- digest.Update(b);
- }
- public virtual void BlockUpdate(byte[] input, int inOff, int inLen)
- {
- digest.BlockUpdate(input, inOff, inLen);
- }
- #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
- public virtual void BlockUpdate(ReadOnlySpan<byte> input)
- {
- digest.BlockUpdate(input);
- }
- #endif
- public virtual void Reset()
- {
- digest.Reset();
- }
- public virtual byte[] GenerateSignature()
- {
- CreateSignatureBlock();
- BigInteger t = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length));
- Arrays.Fill(block, 0x00);
- t = t.Min(kParam.Modulus.Subtract(t));
- int size = BigIntegers.GetUnsignedByteLength(kParam.Modulus);
- return BigIntegers.AsUnsignedByteArray(size, t);
- }
- private void CreateSignatureBlock()
- {
- int digSize = digest.GetDigestSize();
- int delta;
- if (trailer == IsoTrailers.TRAILER_IMPLICIT)
- {
- delta = block.Length - digSize - 1;
- digest.DoFinal(block, delta);
- block[block.Length - 1] = (byte)IsoTrailers.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;
- }
- public virtual bool VerifySignature(byte[] signature)
- {
- try
- {
- block = cipher.ProcessBlock(signature, 0, signature.Length);
- }
- catch (Exception)
- {
- return false;
- }
- BigInteger t = new BigInteger(1, 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();
- #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
- int fBlockSize = block.Length;
- Span<byte> fBlock = fBlockSize <= 512
- ? stackalloc byte[fBlockSize]
- : new byte[fBlockSize];
- BigIntegers.AsUnsignedByteArray(f, fBlock);
- #else
- byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
- #endif
- bool rv = Arrays.ConstantTimeAreEqual(block, fBlock);
- Arrays.Fill(block, 0x00);
- Arrays.Fill<byte>(fBlock, 0x00);
- return rv;
- }
- }
- }
- #pragma warning restore
- #endif
|