This commit is contained in:
2020-07-09 08:50:24 +08:00
parent 13d25f4707
commit c523462b82
1818 changed files with 174940 additions and 582 deletions

View File

@@ -0,0 +1,149 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using System.Collections;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers
{
public class DsaDigestSigner
: ISigner
{
private readonly IDigest digest;
private readonly IDsa dsaSigner;
private bool forSigning;
public DsaDigestSigner(
IDsa signer,
IDigest digest)
{
this.digest = digest;
this.dsaSigner = signer;
}
public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; }
}
public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
this.forSigning = forSigning;
AsymmetricKeyParameter k;
if (parameters is ParametersWithRandom)
{
k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters;
}
else
{
k = (AsymmetricKeyParameter)parameters;
}
if (forSigning && !k.IsPrivate)
throw new InvalidKeyException("Signing Requires Private Key.");
if (!forSigning && k.IsPrivate)
throw new InvalidKeyException("Verification Requires Public Key.");
Reset();
dsaSigner.Init(forSigning, parameters);
}
/**
* update the internal digest with the byte b
*/
public virtual void Update(
byte input)
{
digest.Update(input);
}
/**
* update the internal digest with the byte array in
*/
public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
{
digest.BlockUpdate(input, inOff, length);
}
/**
* Generate a signature for the message we've been loaded with using
* the key we were initialised with.
*/
public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("DSADigestSigner not initialised for signature generation.");
byte[] hash = new byte[digest.GetDigestSize()];
digest.DoFinal(hash, 0);
BigInteger[] sig = dsaSigner.GenerateSignature(hash);
return DerEncode(sig[0], sig[1]);
}
/// <returns>true if the internal state represents the signature described in the passed in array.</returns>
public virtual bool VerifySignature(
byte[] signature)
{
if (forSigning)
throw new InvalidOperationException("DSADigestSigner not initialised for verification");
byte[] hash = new byte[digest.GetDigestSize()];
digest.DoFinal(hash, 0);
try
{
BigInteger[] sig = DerDecode(signature);
return dsaSigner.VerifySignature(hash, sig[0], sig[1]);
}
catch (IOException)
{
return false;
}
}
/// <summary>Reset the internal state</summary>
public virtual void Reset()
{
digest.Reset();
}
private byte[] DerEncode(
BigInteger r,
BigInteger s)
{
return new DerSequence(new DerInteger(r), new DerInteger(s)).GetDerEncoded();
}
private BigInteger[] DerDecode(
byte[] encoding)
{
Asn1Sequence s = (Asn1Sequence) Asn1Object.FromByteArray(encoding);
return new BigInteger[]
{
((DerInteger) s[0]).Value,
((DerInteger) s[1]).Value
};
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e6c86faffe0754ab3a698e0bafe05b3b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,160 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers
{
/**
* The Digital Signature Algorithm - as described in "Handbook of Applied
* Cryptography", pages 452 - 453.
*/
public class DsaSigner
: IDsa
{
protected readonly IDsaKCalculator kCalculator;
protected DsaKeyParameters key = null;
protected SecureRandom random = null;
/**
* Default configuration, random K values.
*/
public DsaSigner()
{
this.kCalculator = new RandomDsaKCalculator();
}
/**
* Configuration with an alternate, possibly deterministic calculator of K.
*
* @param kCalculator a K value calculator.
*/
public DsaSigner(IDsaKCalculator kCalculator)
{
this.kCalculator = kCalculator;
}
public virtual string AlgorithmName
{
get { return "DSA"; }
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
SecureRandom providedRandom = null;
if (forSigning)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom)parameters;
providedRandom = rParam.Random;
parameters = rParam.Parameters;
}
if (!(parameters is DsaPrivateKeyParameters))
throw new InvalidKeyException("DSA private key required for signing");
this.key = (DsaPrivateKeyParameters)parameters;
}
else
{
if (!(parameters is DsaPublicKeyParameters))
throw new InvalidKeyException("DSA public key required for verification");
this.key = (DsaPublicKeyParameters)parameters;
}
this.random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, providedRandom);
}
/**
* Generate a signature for the given message using the key we were
* initialised with. For conventional DSA the message should be a SHA-1
* hash of the message of interest.
*
* @param message the message that will be verified later.
*/
public virtual BigInteger[] GenerateSignature(byte[] message)
{
DsaParameters parameters = key.Parameters;
BigInteger q = parameters.Q;
BigInteger m = CalculateE(q, message);
BigInteger x = ((DsaPrivateKeyParameters)key).X;
if (kCalculator.IsDeterministic)
{
kCalculator.Init(q, x, message);
}
else
{
kCalculator.Init(q, random);
}
BigInteger k = kCalculator.NextK();
BigInteger r = parameters.G.ModPow(k, parameters.P).Mod(q);
k = k.ModInverse(q).Multiply(m.Add(x.Multiply(r)));
BigInteger s = k.Mod(q);
return new BigInteger[]{ r, s };
}
/**
* return true if the value r and s represent a DSA signature for
* the passed in message for standard DSA the message should be a
* SHA-1 hash of the real message to be verified.
*/
public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
{
DsaParameters parameters = key.Parameters;
BigInteger q = parameters.Q;
BigInteger m = CalculateE(q, message);
if (r.SignValue <= 0 || q.CompareTo(r) <= 0)
{
return false;
}
if (s.SignValue <= 0 || q.CompareTo(s) <= 0)
{
return false;
}
BigInteger w = s.ModInverse(q);
BigInteger u1 = m.Multiply(w).Mod(q);
BigInteger u2 = r.Multiply(w).Mod(q);
BigInteger p = parameters.P;
u1 = parameters.G.ModPow(u1, p);
u2 = ((DsaPublicKeyParameters)key).Y.ModPow(u2, p);
BigInteger v = u1.Multiply(u2).Mod(p).Mod(q);
return v.Equals(r);
}
protected virtual BigInteger CalculateE(BigInteger n, byte[] message)
{
int length = System.Math.Min(message.Length, n.BitLength / 8);
return new BigInteger(1, message, 0, length);
}
protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided)
{
return !needed ? null : (provided != null) ? provided : new SecureRandom();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e22ceda422d1640e49537895db17ca12
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,244 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers
{
/**
* EC-DSA as described in X9.62
*/
public class ECDsaSigner
: IDsa
{
private static readonly BigInteger Eight = BigInteger.ValueOf(8);
protected readonly IDsaKCalculator kCalculator;
protected ECKeyParameters key = null;
protected SecureRandom random = null;
/**
* Default configuration, random K values.
*/
public ECDsaSigner()
{
this.kCalculator = new RandomDsaKCalculator();
}
/**
* Configuration with an alternate, possibly deterministic calculator of K.
*
* @param kCalculator a K value calculator.
*/
public ECDsaSigner(IDsaKCalculator kCalculator)
{
this.kCalculator = kCalculator;
}
public virtual string AlgorithmName
{
get { return "ECDSA"; }
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
SecureRandom providedRandom = null;
if (forSigning)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom)parameters;
providedRandom = rParam.Random;
parameters = rParam.Parameters;
}
if (!(parameters is ECPrivateKeyParameters))
throw new InvalidKeyException("EC private key required for signing");
this.key = (ECPrivateKeyParameters)parameters;
}
else
{
if (!(parameters is ECPublicKeyParameters))
throw new InvalidKeyException("EC public key required for verification");
this.key = (ECPublicKeyParameters)parameters;
}
this.random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, providedRandom);
}
// 5.3 pg 28
/**
* Generate a signature for the given message using the key we were
* initialised with. For conventional DSA the message should be a SHA-1
* hash of the message of interest.
*
* @param message the message that will be verified later.
*/
public virtual BigInteger[] GenerateSignature(byte[] message)
{
ECDomainParameters ec = key.Parameters;
BigInteger n = ec.N;
BigInteger e = CalculateE(n, message);
BigInteger d = ((ECPrivateKeyParameters)key).D;
if (kCalculator.IsDeterministic)
{
kCalculator.Init(n, d, message);
}
else
{
kCalculator.Init(n, random);
}
BigInteger r, s;
ECMultiplier basePointMultiplier = CreateBasePointMultiplier();
// 5.3.2
do // Generate s
{
BigInteger k;
do // Generate r
{
k = kCalculator.NextK();
ECPoint p = basePointMultiplier.Multiply(ec.G, k).Normalize();
// 5.3.3
r = p.AffineXCoord.ToBigInteger().Mod(n);
}
while (r.SignValue == 0);
s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r))).Mod(n);
}
while (s.SignValue == 0);
return new BigInteger[]{ r, s };
}
// 5.4 pg 29
/**
* return true if the value r and s represent a DSA signature for
* the passed in message (for standard DSA the message should be
* a SHA-1 hash of the real message to be verified).
*/
public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
{
BigInteger n = key.Parameters.N;
// r and s should both in the range [1,n-1]
if (r.SignValue < 1 || s.SignValue < 1
|| r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0)
{
return false;
}
BigInteger e = CalculateE(n, message);
BigInteger c = s.ModInverse(n);
BigInteger u1 = e.Multiply(c).Mod(n);
BigInteger u2 = r.Multiply(c).Mod(n);
ECPoint G = key.Parameters.G;
ECPoint Q = ((ECPublicKeyParameters) key).Q;
ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2);
if (point.IsInfinity)
return false;
/*
* If possible, avoid normalizing the point (to save a modular inversion in the curve field).
*
* There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'.
* If the cofactor is known and small, we generate those possible field values and project each
* of them to the same "denominator" (depending on the particular projective coordinates in use)
* as the calculated point.X. If any of the projected values matches point.X, then we have:
* (point.X / Denominator mod p) mod n == r
* as required, and verification succeeds.
*
* Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in
* the libsecp256k1 project (https://github.com/bitcoin/secp256k1).
*/
ECCurve curve = point.Curve;
if (curve != null)
{
BigInteger cofactor = curve.Cofactor;
if (cofactor != null && cofactor.CompareTo(Eight) <= 0)
{
ECFieldElement D = GetDenominator(curve.CoordinateSystem, point);
if (D != null && !D.IsZero)
{
ECFieldElement X = point.XCoord;
while (curve.IsValidFieldElement(r))
{
ECFieldElement R = curve.FromBigInteger(r).Multiply(D);
if (R.Equals(X))
{
return true;
}
r = r.Add(n);
}
return false;
}
}
}
BigInteger v = point.Normalize().AffineXCoord.ToBigInteger().Mod(n);
return v.Equals(r);
}
protected virtual BigInteger CalculateE(BigInteger n, byte[] message)
{
int messageBitLength = message.Length * 8;
BigInteger trunc = new BigInteger(1, message);
if (n.BitLength < messageBitLength)
{
trunc = trunc.ShiftRight(messageBitLength - n.BitLength);
}
return trunc;
}
protected virtual ECMultiplier CreateBasePointMultiplier()
{
return new FixedPointCombMultiplier();
}
protected virtual ECFieldElement GetDenominator(int coordinateSystem, ECPoint p)
{
switch (coordinateSystem)
{
case ECCurve.COORD_HOMOGENEOUS:
case ECCurve.COORD_LAMBDA_PROJECTIVE:
case ECCurve.COORD_SKEWED:
return p.GetZCoord(0);
case ECCurve.COORD_JACOBIAN:
case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
case ECCurve.COORD_JACOBIAN_MODIFIED:
return p.GetZCoord(0).Square();
default:
return null;
}
}
protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided)
{
return !needed ? null : (provided != null) ? provided : new SecureRandom();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b16ae88f524a643708e70c9dfea29e75
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,166 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers
{
/**
* GOST R 34.10-2001 Signature Algorithm
*/
public class ECGost3410Signer
: IDsa
{
private ECKeyParameters key;
private SecureRandom random;
public virtual string AlgorithmName
{
get { return "ECGOST3410"; }
}
public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
if (forSigning)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom)parameters;
this.random = rParam.Random;
parameters = rParam.Parameters;
}
else
{
this.random = new SecureRandom();
}
if (!(parameters is ECPrivateKeyParameters))
throw new InvalidKeyException("EC private key required for signing");
this.key = (ECPrivateKeyParameters) parameters;
}
else
{
if (!(parameters is ECPublicKeyParameters))
throw new InvalidKeyException("EC public key required for verification");
this.key = (ECPublicKeyParameters)parameters;
}
}
/**
* generate a signature for the given message using the key we were
* initialised with. For conventional GOST3410 the message should be a GOST3411
* hash of the message of interest.
*
* @param message the message that will be verified later.
*/
public virtual BigInteger[] GenerateSignature(
byte[] message)
{
byte[] mRev = new byte[message.Length]; // conversion is little-endian
for (int i = 0; i != mRev.Length; i++)
{
mRev[i] = message[mRev.Length - 1 - i];
}
BigInteger e = new BigInteger(1, mRev);
ECDomainParameters ec = key.Parameters;
BigInteger n = ec.N;
BigInteger d = ((ECPrivateKeyParameters)key).D;
BigInteger r, s = null;
ECMultiplier basePointMultiplier = CreateBasePointMultiplier();
do // generate s
{
BigInteger k;
do // generate r
{
do
{
k = new BigInteger(n.BitLength, random);
}
while (k.SignValue == 0);
ECPoint p = basePointMultiplier.Multiply(ec.G, k).Normalize();
r = p.AffineXCoord.ToBigInteger().Mod(n);
}
while (r.SignValue == 0);
s = (k.Multiply(e)).Add(d.Multiply(r)).Mod(n);
}
while (s.SignValue == 0);
return new BigInteger[]{ r, s };
}
/**
* return true if the value r and s represent a GOST3410 signature for
* the passed in message (for standard GOST3410 the message should be
* a GOST3411 hash of the real message to be verified).
*/
public virtual bool VerifySignature(
byte[] message,
BigInteger r,
BigInteger s)
{
byte[] mRev = new byte[message.Length]; // conversion is little-endian
for (int i = 0; i != mRev.Length; i++)
{
mRev[i] = message[mRev.Length - 1 - i];
}
BigInteger e = new BigInteger(1, mRev);
BigInteger n = key.Parameters.N;
// r in the range [1,n-1]
if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
{
return false;
}
// s in the range [1,n-1]
if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0)
{
return false;
}
BigInteger v = e.ModInverse(n);
BigInteger z1 = s.Multiply(v).Mod(n);
BigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n);
ECPoint G = key.Parameters.G; // P
ECPoint Q = ((ECPublicKeyParameters)key).Q;
ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2).Normalize();
if (point.IsInfinity)
return false;
BigInteger R = point.AffineXCoord.ToBigInteger().Mod(n);
return R.Equals(r);
}
protected virtual ECMultiplier CreateBasePointMultiplier()
{
return new FixedPointCombMultiplier();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4a4fe5d07e5e544b095753876c6ba20c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,192 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers
{
/**
* EC-NR as described in IEEE 1363-2000
*/
public class ECNRSigner
: IDsa
{
private bool forSigning;
private ECKeyParameters key;
private SecureRandom random;
public virtual string AlgorithmName
{
get { return "ECNR"; }
}
public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
this.forSigning = forSigning;
if (forSigning)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom) parameters;
this.random = rParam.Random;
parameters = rParam.Parameters;
}
else
{
this.random = new SecureRandom();
}
if (!(parameters is ECPrivateKeyParameters))
throw new InvalidKeyException("EC private key required for signing");
this.key = (ECPrivateKeyParameters) parameters;
}
else
{
if (!(parameters is ECPublicKeyParameters))
throw new InvalidKeyException("EC public key required for verification");
this.key = (ECPublicKeyParameters) parameters;
}
}
// Section 7.2.5 ECSP-NR, pg 34
/**
* generate a signature for the given message using the key we were
* initialised with. Generally, the order of the curve should be at
* least as long as the hash of the message of interest, and with
* ECNR it *must* be at least as long.
*
* @param digest the digest to be signed.
* @exception DataLengthException if the digest is longer than the key allows
*/
public virtual BigInteger[] GenerateSignature(
byte[] message)
{
if (!this.forSigning)
{
// not properly initilaized... deal with it
throw new InvalidOperationException("not initialised for signing");
}
BigInteger n = ((ECPrivateKeyParameters) this.key).Parameters.N;
int nBitLength = n.BitLength;
BigInteger e = new BigInteger(1, message);
int eBitLength = e.BitLength;
ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)key;
if (eBitLength > nBitLength)
{
throw new DataLengthException("input too large for ECNR key.");
}
BigInteger r = null;
BigInteger s = null;
AsymmetricCipherKeyPair tempPair;
do // generate r
{
// generate another, but very temporary, key pair using
// the same EC parameters
ECKeyPairGenerator keyGen = new ECKeyPairGenerator();
keyGen.Init(new ECKeyGenerationParameters(privKey.Parameters, this.random));
tempPair = keyGen.GenerateKeyPair();
// BigInteger Vx = tempPair.getPublic().getW().getAffineX();
ECPublicKeyParameters V = (ECPublicKeyParameters) tempPair.Public; // get temp's public key
BigInteger Vx = V.Q.AffineXCoord.ToBigInteger(); // get the point's x coordinate
r = Vx.Add(e).Mod(n);
}
while (r.SignValue == 0);
// generate s
BigInteger x = privKey.D; // private key value
BigInteger u = ((ECPrivateKeyParameters) tempPair.Private).D; // temp's private key value
s = u.Subtract(r.Multiply(x)).Mod(n);
return new BigInteger[]{ r, s };
}
// Section 7.2.6 ECVP-NR, pg 35
/**
* return true if the value r and s represent a signature for the
* message passed in. Generally, the order of the curve should be at
* least as long as the hash of the message of interest, and with
* ECNR, it *must* be at least as long. But just in case the signer
* applied mod(n) to the longer digest, this implementation will
* apply mod(n) during verification.
*
* @param digest the digest to be verified.
* @param r the r value of the signature.
* @param s the s value of the signature.
* @exception DataLengthException if the digest is longer than the key allows
*/
public virtual bool VerifySignature(
byte[] message,
BigInteger r,
BigInteger s)
{
if (this.forSigning)
{
// not properly initilaized... deal with it
throw new InvalidOperationException("not initialised for verifying");
}
ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key;
BigInteger n = pubKey.Parameters.N;
int nBitLength = n.BitLength;
BigInteger e = new BigInteger(1, message);
int eBitLength = e.BitLength;
if (eBitLength > nBitLength)
{
throw new DataLengthException("input too large for ECNR key.");
}
// r in the range [1,n-1]
if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
{
return false;
}
// s in the range [0,n-1] NB: ECNR spec says 0
if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0)
{
return false;
}
// compute P = sG + rW
ECPoint G = pubKey.Parameters.G;
ECPoint W = pubKey.Q;
// calculate P using Bouncy math
ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r).Normalize();
if (P.IsInfinity)
return false;
BigInteger x = P.AffineXCoord.ToBigInteger();
BigInteger t = r.Subtract(x).Mod(n);
return t.Equals(e);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ea7581190a6d24b9e9ffc867593b1452
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,149 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using System.Collections;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers
{
public class Gost3410DigestSigner
: ISigner
{
private readonly IDigest digest;
private readonly IDsa dsaSigner;
private bool forSigning;
public Gost3410DigestSigner(
IDsa signer,
IDigest digest)
{
this.dsaSigner = signer;
this.digest = digest;
}
public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; }
}
public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
this.forSigning = forSigning;
AsymmetricKeyParameter k;
if (parameters is ParametersWithRandom)
{
k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters;
}
else
{
k = (AsymmetricKeyParameter)parameters;
}
if (forSigning && !k.IsPrivate)
{
throw new InvalidKeyException("Signing Requires Private Key.");
}
if (!forSigning && k.IsPrivate)
{
throw new InvalidKeyException("Verification Requires Public Key.");
}
Reset();
dsaSigner.Init(forSigning, parameters);
}
/**
* update the internal digest with the byte b
*/
public virtual void Update(
byte input)
{
digest.Update(input);
}
/**
* update the internal digest with the byte array in
*/
public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
{
digest.BlockUpdate(input, inOff, length);
}
/**
* Generate a signature for the message we've been loaded with using
* the key we were initialised with.
*/
public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("GOST3410DigestSigner not initialised for signature generation.");
byte[] hash = new byte[digest.GetDigestSize()];
digest.DoFinal(hash, 0);
try
{
BigInteger[] sig = dsaSigner.GenerateSignature(hash);
byte[] sigBytes = new byte[64];
// TODO Add methods to allow writing BigInteger to existing byte array?
byte[] r = sig[0].ToByteArrayUnsigned();
byte[] s = sig[1].ToByteArrayUnsigned();
s.CopyTo(sigBytes, 32 - s.Length);
r.CopyTo(sigBytes, 64 - r.Length);
return sigBytes;
}
catch (Exception e)
{
throw new SignatureException(e.Message, e);
}
}
/// <returns>true if the internal state represents the signature described in the passed in array.</returns>
public virtual bool VerifySignature(
byte[] signature)
{
if (forSigning)
throw new InvalidOperationException("DSADigestSigner not initialised for verification");
byte[] hash = new byte[digest.GetDigestSize()];
digest.DoFinal(hash, 0);
BigInteger R, S;
try
{
R = new BigInteger(1, signature, 32, 32);
S = new BigInteger(1, signature, 0, 32);
}
catch (Exception e)
{
throw new SignatureException("error decoding signature bytes.", e);
}
return dsaSigner.VerifySignature(hash, R, S);
}
/// <summary>Reset the internal state</summary>
public virtual void Reset()
{
digest.Reset();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cf0bdaf1c9e3f41e8b5d564892ee0dcd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,136 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers
{
/**
* Gost R 34.10-94 Signature Algorithm
*/
public class Gost3410Signer
: IDsa
{
private Gost3410KeyParameters key;
private SecureRandom random;
public virtual string AlgorithmName
{
get { return "GOST3410"; }
}
public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
if (forSigning)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom)parameters;
this.random = rParam.Random;
parameters = rParam.Parameters;
}
else
{
this.random = new SecureRandom();
}
if (!(parameters is Gost3410PrivateKeyParameters))
throw new InvalidKeyException("GOST3410 private key required for signing");
this.key = (Gost3410PrivateKeyParameters) parameters;
}
else
{
if (!(parameters is Gost3410PublicKeyParameters))
throw new InvalidKeyException("GOST3410 public key required for signing");
this.key = (Gost3410PublicKeyParameters) parameters;
}
}
/**
* generate a signature for the given message using the key we were
* initialised with. For conventional Gost3410 the message should be a Gost3411
* hash of the message of interest.
*
* @param message the message that will be verified later.
*/
public virtual BigInteger[] GenerateSignature(
byte[] message)
{
byte[] mRev = new byte[message.Length]; // conversion is little-endian
for (int i = 0; i != mRev.Length; i++)
{
mRev[i] = message[mRev.Length - 1 - i];
}
BigInteger m = new BigInteger(1, mRev);
Gost3410Parameters parameters = key.Parameters;
BigInteger k;
do
{
k = new BigInteger(parameters.Q.BitLength, random);
}
while (k.CompareTo(parameters.Q) >= 0);
BigInteger r = parameters.A.ModPow(k, parameters.P).Mod(parameters.Q);
BigInteger s = k.Multiply(m).
Add(((Gost3410PrivateKeyParameters)key).X.Multiply(r)).
Mod(parameters.Q);
return new BigInteger[]{ r, s };
}
/**
* return true if the value r and s represent a Gost3410 signature for
* the passed in message for standard Gost3410 the message should be a
* Gost3411 hash of the real message to be verified.
*/
public virtual bool VerifySignature(
byte[] message,
BigInteger r,
BigInteger s)
{
byte[] mRev = new byte[message.Length]; // conversion is little-endian
for (int i = 0; i != mRev.Length; i++)
{
mRev[i] = message[mRev.Length - 1 - i];
}
BigInteger m = new BigInteger(1, mRev);
Gost3410Parameters parameters = key.Parameters;
if (r.SignValue < 0 || parameters.Q.CompareTo(r) <= 0)
{
return false;
}
if (s.SignValue < 0 || parameters.Q.CompareTo(s) <= 0)
{
return false;
}
BigInteger v = m.ModPow(parameters.Q.Subtract(BigInteger.Two), parameters.Q);
BigInteger z1 = s.Multiply(v).Mod(parameters.Q);
BigInteger z2 = (parameters.Q.Subtract(r)).Multiply(v).Mod(parameters.Q);
z1 = parameters.A.ModPow(z1, parameters.P);
z2 = ((Gost3410PublicKeyParameters)key).Y.ModPow(z2, parameters.P);
BigInteger u = z1.Multiply(z2).Mod(parameters.P).Mod(parameters.Q);
return u.Equals(r);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ce3417c698f5943cd9744f15dbd9a81b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,134 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers
{
public class GenericSigner
: ISigner
{
private readonly IAsymmetricBlockCipher engine;
private readonly IDigest digest;
private bool forSigning;
public GenericSigner(
IAsymmetricBlockCipher engine,
IDigest digest)
{
this.engine = engine;
this.digest = digest;
}
public virtual string AlgorithmName
{
get { return "Generic(" + engine.AlgorithmName + "/" + digest.AlgorithmName + ")"; }
}
/**
* initialise the signer for signing or verification.
*
* @param forSigning
* true if for signing, false otherwise
* @param parameters
* necessary parameters.
*/
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
AsymmetricKeyParameter k;
if (parameters is ParametersWithRandom)
{
k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters;
}
else
{
k = (AsymmetricKeyParameter)parameters;
}
if (forSigning && !k.IsPrivate)
throw new InvalidKeyException("Signing requires private key.");
if (!forSigning && k.IsPrivate)
throw new InvalidKeyException("Verification requires public key.");
Reset();
engine.Init(forSigning, parameters);
}
/**
* update the internal digest with the byte b
*/
public virtual void Update(byte input)
{
digest.Update(input);
}
/**
* update the internal digest with the byte array in
*/
public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
digest.BlockUpdate(input, inOff, length);
}
/**
* Generate a signature for the message we've been loaded with using the key
* we were initialised with.
*/
public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("GenericSigner not initialised for signature generation.");
byte[] hash = new byte[digest.GetDigestSize()];
digest.DoFinal(hash, 0);
return engine.ProcessBlock(hash, 0, hash.Length);
}
/**
* return true if the internal state represents the signature described in
* the passed in array.
*/
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning)
throw new InvalidOperationException("GenericSigner not initialised for verification");
byte[] hash = new byte[digest.GetDigestSize()];
digest.DoFinal(hash, 0);
try
{
byte[] sig = engine.ProcessBlock(signature, 0, signature.Length);
// Extend with leading zeroes to match the digest size, if necessary.
if (sig.Length < hash.Length)
{
byte[] tmp = new byte[hash.Length];
Array.Copy(sig, 0, tmp, tmp.Length - sig.Length, sig.Length);
sig = tmp;
}
return Arrays.ConstantTimeAreEqual(sig, hash);
}
catch (Exception)
{
return false;
}
}
public virtual void Reset()
{
digest.Reset();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3946e7b2d6f0d40e79a77ff91c6c3b66
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,154 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers
{
/**
* A deterministic K calculator based on the algorithm in section 3.2 of RFC 6979.
*/
public class HMacDsaKCalculator
: IDsaKCalculator
{
private readonly HMac hMac;
private readonly byte[] K;
private readonly byte[] V;
private BigInteger n;
/**
* Base constructor.
*
* @param digest digest to build the HMAC on.
*/
public HMacDsaKCalculator(IDigest digest)
{
this.hMac = new HMac(digest);
this.V = new byte[hMac.GetMacSize()];
this.K = new byte[hMac.GetMacSize()];
}
public virtual bool IsDeterministic
{
get { return true; }
}
public virtual void Init(BigInteger n, SecureRandom random)
{
throw new InvalidOperationException("Operation not supported");
}
public void Init(BigInteger n, BigInteger d, byte[] message)
{
this.n = n;
Arrays.Fill(V, (byte)0x01);
Arrays.Fill(K, (byte)0);
byte[] x = new byte[(n.BitLength + 7) / 8];
byte[] dVal = BigIntegers.AsUnsignedByteArray(d);
Array.Copy(dVal, 0, x, x.Length - dVal.Length, dVal.Length);
byte[] m = new byte[(n.BitLength + 7) / 8];
BigInteger mInt = BitsToInt(message);
if (mInt.CompareTo(n) >= 0)
{
mInt = mInt.Subtract(n);
}
byte[] mVal = BigIntegers.AsUnsignedByteArray(mInt);
Array.Copy(mVal, 0, m, m.Length - mVal.Length, mVal.Length);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.Update((byte)0x00);
hMac.BlockUpdate(x, 0, x.Length);
hMac.BlockUpdate(m, 0, m.Length);
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
hMac.BlockUpdate(V, 0, V.Length);
hMac.Update((byte)0x01);
hMac.BlockUpdate(x, 0, x.Length);
hMac.BlockUpdate(m, 0, m.Length);
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
}
public virtual BigInteger NextK()
{
byte[] t = new byte[((n.BitLength + 7) / 8)];
for (;;)
{
int tOff = 0;
while (tOff < t.Length)
{
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
int len = System.Math.Min(t.Length - tOff, V.Length);
Array.Copy(V, 0, t, tOff, len);
tOff += len;
}
BigInteger k = BitsToInt(t);
if (k.SignValue > 0 && k.CompareTo(n) < 0)
{
return k;
}
hMac.BlockUpdate(V, 0, V.Length);
hMac.Update((byte)0x00);
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
}
}
private BigInteger BitsToInt(byte[] t)
{
BigInteger v = new BigInteger(1, t);
if (t.Length * 8 > n.BitLength)
{
v = v.ShiftRight(t.Length * 8 - n.BitLength);
}
return v;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6ed449950d3a84623b4b26d5ec6c9dcd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers
{
/**
* Interface define calculators of K values for DSA/ECDSA.
*/
public interface IDsaKCalculator
{
/**
* Return true if this calculator is deterministic, false otherwise.
*
* @return true if deterministic, otherwise false.
*/
bool IsDeterministic { get; }
/**
* Non-deterministic initialiser.
*
* @param n the order of the DSA group.
* @param random a source of randomness.
*/
void Init(BigInteger n, SecureRandom random);
/**
* Deterministic initialiser.
*
* @param n the order of the DSA group.
* @param d the DSA private value.
* @param message the message being signed.
*/
void Init(BigInteger n, BigInteger d, byte[] message);
/**
* Return the next valid value of K.
*
* @return a K value.
*/
BigInteger NextK();
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d81246ff96b1d4c808ac0c81b0bf5eee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,554 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using System.Collections;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers
{
/// <summary> ISO9796-2 - mechanism using a hash function with recovery (scheme 1)</summary>
public class Iso9796d2Signer : ISignerWithRecovery
{
/// <summary>
/// Return a reference to the recoveredMessage message.
/// </summary>
/// <returns>The full/partial recoveredMessage message.</returns>
/// <seealso cref="ISignerWithRecovery.GetRecoveredMessage"/>
public byte[] GetRecoveredMessage()
{
return recoveredMessage;
}
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerImplicit = 0xBC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerRipeMD160 = 0x31CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerRipeMD128 = 0x32CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha1 = 0x33CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha256 = 0x34CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha512 = 0x35CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha384 = 0x36CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerWhirlpool = 0x37CC;
private IDigest digest;
private IAsymmetricBlockCipher cipher;
private int trailer;
private int keyBits;
private byte[] block;
private byte[] mBuf;
private int messageLength;
private bool fullMessage;
private byte[] recoveredMessage;
private byte[] preSig;
private byte[] preBlock;
/// <summary>
/// Generate a signer with either implicit or explicit trailers for ISO9796-2.
/// </summary>
/// <param name="cipher">base cipher to use for signature creation/verification</param>
/// <param name="digest">digest to use.</param>
/// <param name="isImplicit">whether or not the trailer is implicit or gives the hash.</param>
public Iso9796d2Signer(
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);
}
}
/// <summary> Constructor for a signer with an explicit digest trailer.
///
/// </summary>
/// <param name="cipher">cipher to use.
/// </param>
/// <param name="digest">digest to sign with.
/// </param>
public Iso9796d2Signer(IAsymmetricBlockCipher cipher, IDigest digest)
: this(cipher, digest, false)
{
}
public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + "ISO9796-2S1"; }
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
RsaKeyParameters kParam = (RsaKeyParameters) parameters;
cipher.Init(forSigning, kParam);
keyBits = kParam.Modulus.BitLength;
block = new byte[(keyBits + 7) / 8];
if (trailer == IsoTrailers.TRAILER_IMPLICIT)
{
mBuf = new byte[block.Length - digest.GetDigestSize() - 2];
}
else
{
mBuf = new byte[block.Length - digest.GetDigestSize() - 3];
}
Reset();
}
/// <summary> compare two byte arrays - constant time.</summary>
private bool IsSameAs(byte[] a, byte[] b)
{
int checkLen;
if (messageLength > mBuf.Length)
{
if (mBuf.Length > b.Length)
{
return false;
}
checkLen = mBuf.Length;
}
else
{
if (messageLength != b.Length)
{
return false;
}
checkLen = b.Length;
}
bool isOkay = true;
for (int i = 0; i != checkLen; i++)
{
if (a[i] != b[i])
{
isOkay = false;
}
}
return isOkay;
}
/// <summary> clear possible sensitive data</summary>
private void ClearBlock(
byte[] block)
{
Array.Clear(block, 0, block.Length);
}
public virtual void UpdateWithRecoveredMessage(
byte[] signature)
{
byte[] block = cipher.ProcessBlock(signature, 0, signature.Length);
if (((block[0] & 0xC0) ^ 0x40) != 0)
throw new InvalidCipherTextException("malformed signature");
if (((block[block.Length - 1] & 0xF) ^ 0xC) != 0)
throw new InvalidCipherTextException("malformed signature");
int delta = 0;
if (((block[block.Length - 1] & 0xFF) ^ 0xBC) == 0)
{
delta = 1;
}
else
{
int sigTrail = ((block[block.Length - 2] & 0xFF) << 8) | (block[block.Length - 1] & 0xFF);
if (IsoTrailers.NoTrailerAvailable(digest))
throw new ArgumentException("unrecognised hash in signature");
if (sigTrail != IsoTrailers.GetTrailer(digest))
throw new InvalidOperationException("signer initialised with wrong digest for trailer " + sigTrail);
delta = 2;
}
//
// find out how much padding we've got
//
int mStart = 0;
for (mStart = 0; mStart != block.Length; mStart++)
{
if (((block[mStart] & 0x0f) ^ 0x0a) == 0)
break;
}
mStart++;
int off = block.Length - delta - digest.GetDigestSize();
//
// there must be at least one byte of message string
//
if ((off - mStart) <= 0)
throw new InvalidCipherTextException("malformed block");
//
// if we contain the whole message as well, check the hash of that.
//
if ((block[0] & 0x20) == 0)
{
fullMessage = true;
recoveredMessage = new byte[off - mStart];
Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length);
}
else
{
fullMessage = false;
recoveredMessage = new byte[off - mStart];
Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length);
}
preSig = signature;
preBlock = block;
digest.BlockUpdate(recoveredMessage, 0, recoveredMessage.Length);
messageLength = recoveredMessage.Length;
recoveredMessage.CopyTo(mBuf, 0);
}
/// <summary> update the internal digest with the byte b</summary>
public virtual void Update(
byte input)
{
digest.Update(input);
if (messageLength < mBuf.Length)
{
mBuf[messageLength] = input;
}
messageLength++;
}
/// <summary> update the internal digest with the byte array in</summary>
public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
{
while (length > 0 && messageLength < mBuf.Length)
{
//for (int i = 0; i < length && (i + messageLength) < mBuf.Length; i++)
//{
// mBuf[messageLength + i] = input[inOff + i];
//}
this.Update(input[inOff]);
inOff++;
length--;
}
digest.BlockUpdate(input, inOff, length);
messageLength += length;
}
/// <summary> reset the internal state</summary>
public virtual void Reset()
{
digest.Reset();
messageLength = 0;
ClearBlock(mBuf);
if (recoveredMessage != null)
{
ClearBlock(recoveredMessage);
}
recoveredMessage = null;
fullMessage = false;
if (preSig != null)
{
preSig = null;
ClearBlock(preBlock);
preBlock = null;
}
}
/// <summary> Generate a signature for the loaded message using the key we were
/// initialised with.
/// </summary>
public virtual byte[] GenerateSignature()
{
int digSize = digest.GetDigestSize();
int t = 0;
int delta = 0;
if (trailer == IsoTrailers.TRAILER_IMPLICIT)
{
t = 8;
delta = block.Length - digSize - 1;
digest.DoFinal(block, delta);
block[block.Length - 1] = (byte)IsoTrailers.TRAILER_IMPLICIT;
}
else
{
t = 16;
delta = block.Length - digSize - 2;
digest.DoFinal(block, delta);
block[block.Length - 2] = (byte) ((uint)trailer >> 8);
block[block.Length - 1] = (byte) trailer;
}
byte header = 0;
int x = (digSize + messageLength) * 8 + t + 4 - keyBits;
if (x > 0)
{
int mR = messageLength - ((x + 7) / 8);
header = (byte) (0x60);
delta -= mR;
Array.Copy(mBuf, 0, block, delta, mR);
}
else
{
header = (byte) (0x40);
delta -= messageLength;
Array.Copy(mBuf, 0, block, delta, messageLength);
}
if ((delta - 1) > 0)
{
for (int i = delta - 1; i != 0; i--)
{
block[i] = (byte) 0xbb;
}
block[delta - 1] ^= (byte) 0x01;
block[0] = (byte) 0x0b;
block[0] |= header;
}
else
{
block[0] = (byte) 0x0a;
block[0] |= header;
}
byte[] b = cipher.ProcessBlock(block, 0, block.Length);
ClearBlock(mBuf);
ClearBlock(block);
return b;
}
/// <summary> return true if the signature represents a ISO9796-2 signature
/// for the passed in message.
/// </summary>
public virtual bool VerifySignature(byte[] signature)
{
byte[] block;
if (preSig == null)
{
try
{
block = cipher.ProcessBlock(signature, 0, signature.Length);
}
catch (Exception)
{
return false;
}
}
else
{
if (!Arrays.AreEqual(preSig, signature))
throw new InvalidOperationException("updateWithRecoveredMessage called on different signature");
block = preBlock;
preSig = null;
preBlock = null;
}
if (((block[0] & 0xC0) ^ 0x40) != 0)
return ReturnFalse(block);
if (((block[block.Length - 1] & 0xF) ^ 0xC) != 0)
return ReturnFalse(block);
int delta = 0;
if (((block[block.Length - 1] & 0xFF) ^ 0xBC) == 0)
{
delta = 1;
}
else
{
int sigTrail = ((block[block.Length - 2] & 0xFF) << 8) | (block[block.Length - 1] & 0xFF);
if (IsoTrailers.NoTrailerAvailable(digest))
throw new ArgumentException("unrecognised hash in signature");
if (sigTrail != IsoTrailers.GetTrailer(digest))
throw new InvalidOperationException("signer initialised with wrong digest for trailer " + sigTrail);
delta = 2;
}
//
// find out how much padding we've got
//
int mStart = 0;
for (; mStart != block.Length; mStart++)
{
if (((block[mStart] & 0x0f) ^ 0x0a) == 0)
{
break;
}
}
mStart++;
//
// check the hashes
//
byte[] hash = new byte[digest.GetDigestSize()];
int off = block.Length - delta - hash.Length;
//
// there must be at least one byte of message string
//
if ((off - mStart) <= 0)
{
return ReturnFalse(block);
}
//
// if we contain the whole message as well, check the hash of that.
//
if ((block[0] & 0x20) == 0)
{
fullMessage = true;
// check right number of bytes passed in.
if (messageLength > off - mStart)
{
return ReturnFalse(block);
}
digest.Reset();
digest.BlockUpdate(block, mStart, off - mStart);
digest.DoFinal(hash, 0);
bool isOkay = true;
for (int i = 0; i != hash.Length; i++)
{
block[off + i] ^= hash[i];
if (block[off + i] != 0)
{
isOkay = false;
}
}
if (!isOkay)
{
return ReturnFalse(block);
}
recoveredMessage = new byte[off - mStart];
Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length);
}
else
{
fullMessage = false;
digest.DoFinal(hash, 0);
bool isOkay = true;
for (int i = 0; i != hash.Length; i++)
{
block[off + i] ^= hash[i];
if (block[off + i] != 0)
{
isOkay = false;
}
}
if (!isOkay)
{
return ReturnFalse(block);
}
recoveredMessage = new byte[off - mStart];
Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length);
}
//
// if they've input a message check what we've recovered against
// what was input.
//
if (messageLength != 0)
{
if (!IsSameAs(mBuf, recoveredMessage))
{
return ReturnFalse(block);
}
}
ClearBlock(mBuf);
ClearBlock(block);
return true;
}
private bool ReturnFalse(byte[] block)
{
ClearBlock(mBuf);
ClearBlock(block);
return false;
}
/// <summary>
/// Return true if the full message was recoveredMessage.
/// </summary>
/// <returns> true on full message recovery, false otherwise.</returns>
/// <seealso cref="ISignerWithRecovery.HasFullMessage"/>
public virtual bool HasFullMessage()
{
return fullMessage;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7861222e3080c4eeabf226092334789a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using System.Collections;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Crypto.Signers
{
public class IsoTrailers
{
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;
public const int TRAILER_SHA512_224 = 0x39CC;
public const int TRAILER_SHA512_256 = 0x40CC;
private static IDictionary CreateTrailerMap()
{
IDictionary trailers = Platform.CreateHashtable();
trailers.Add("RIPEMD128", TRAILER_RIPEMD128);
trailers.Add("RIPEMD160", TRAILER_RIPEMD160);
trailers.Add("SHA-1", TRAILER_SHA1);
trailers.Add("SHA-224", TRAILER_SHA224);
trailers.Add("SHA-256", TRAILER_SHA256);
trailers.Add("SHA-384", TRAILER_SHA384);
trailers.Add("SHA-512", TRAILER_SHA512);
trailers.Add("SHA-512/224", TRAILER_SHA512_224);
trailers.Add("SHA-512/256", TRAILER_SHA512_256);
trailers.Add("Whirlpool", TRAILER_WHIRLPOOL);
return CollectionUtilities.ReadOnly(trailers);
}
// IDictionary is (string -> Int32)
private static readonly IDictionary trailerMap = CreateTrailerMap();
public static int GetTrailer(IDigest digest)
{
return (int)trailerMap[digest.AlgorithmName];
}
public static bool NoTrailerAvailable(IDigest digest)
{
return !trailerMap.Contains(digest.AlgorithmName);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b67a7948a9c1141da92a1dbfb0971cca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,390 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers
{
/// <summary> RSA-PSS as described in Pkcs# 1 v 2.1.
/// <p>
/// Note: the usual value for the salt length is the number of
/// bytes in the hash function.</p>
/// </summary>
public class PssSigner
: ISigner
{
public const byte TrailerImplicit = (byte)0xBC;
private readonly IDigest contentDigest1, contentDigest2;
private readonly IDigest mgfDigest;
private readonly IAsymmetricBlockCipher cipher;
private SecureRandom random;
private int hLen;
private int mgfhLen;
private int sLen;
private bool sSet;
private int emBits;
private byte[] salt;
private byte[] mDash;
private byte[] block;
private byte trailer;
public static PssSigner CreateRawSigner(
IAsymmetricBlockCipher cipher,
IDigest digest)
{
return new PssSigner(cipher, new NullDigest(), digest, digest, digest.GetDigestSize(), null, TrailerImplicit);
}
public static PssSigner CreateRawSigner(
IAsymmetricBlockCipher cipher,
IDigest contentDigest,
IDigest mgfDigest,
int saltLen,
byte trailer)
{
return new PssSigner(cipher, new NullDigest(), contentDigest, mgfDigest, saltLen, null, trailer);
}
public PssSigner(
IAsymmetricBlockCipher cipher,
IDigest digest)
: this(cipher, digest, digest.GetDigestSize())
{
}
/// <summary>Basic constructor</summary>
/// <param name="cipher">the asymmetric cipher to use.</param>
/// <param name="digest">the digest to use.</param>
/// <param name="saltLen">the length of the salt to use (in bytes).</param>
public PssSigner(
IAsymmetricBlockCipher cipher,
IDigest digest,
int saltLen)
: this(cipher, digest, saltLen, TrailerImplicit)
{
}
/// <summary>Basic constructor</summary>
/// <param name="cipher">the asymmetric cipher to use.</param>
/// <param name="digest">the digest to use.</param>
/// <param name="salt">the fixed salt to be used.</param>
public PssSigner(
IAsymmetricBlockCipher cipher,
IDigest digest,
byte[] salt)
: this(cipher, digest, digest, digest, salt.Length, salt, TrailerImplicit)
{
}
public PssSigner(
IAsymmetricBlockCipher cipher,
IDigest contentDigest,
IDigest mgfDigest,
int saltLen)
: this(cipher, contentDigest, mgfDigest, saltLen, TrailerImplicit)
{
}
public PssSigner(
IAsymmetricBlockCipher cipher,
IDigest contentDigest,
IDigest mgfDigest,
byte[] salt)
: this(cipher, contentDigest, contentDigest, mgfDigest, salt.Length, salt, TrailerImplicit)
{
}
public PssSigner(
IAsymmetricBlockCipher cipher,
IDigest digest,
int saltLen,
byte trailer)
: this(cipher, digest, digest, saltLen, TrailerImplicit)
{
}
public PssSigner(
IAsymmetricBlockCipher cipher,
IDigest contentDigest,
IDigest mgfDigest,
int saltLen,
byte trailer)
: this(cipher, contentDigest, contentDigest, mgfDigest, saltLen, null, trailer)
{
}
private PssSigner(
IAsymmetricBlockCipher cipher,
IDigest contentDigest1,
IDigest contentDigest2,
IDigest mgfDigest,
int saltLen,
byte[] salt,
byte trailer)
{
this.cipher = cipher;
this.contentDigest1 = contentDigest1;
this.contentDigest2 = contentDigest2;
this.mgfDigest = mgfDigest;
this.hLen = contentDigest2.GetDigestSize();
this.mgfhLen = mgfDigest.GetDigestSize();
this.sLen = saltLen;
this.sSet = salt != null;
if (sSet)
{
this.salt = salt;
}
else
{
this.salt = new byte[saltLen];
}
this.mDash = new byte[8 + saltLen + hLen];
this.trailer = trailer;
}
public virtual string AlgorithmName
{
get { return mgfDigest.AlgorithmName + "withRSAandMGF1"; }
}
public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom p = (ParametersWithRandom) parameters;
parameters = p.Parameters;
random = p.Random;
}
else
{
if (forSigning)
{
random = new SecureRandom();
}
}
cipher.Init(forSigning, parameters);
RsaKeyParameters kParam;
if (parameters is RsaBlindingParameters)
{
kParam = ((RsaBlindingParameters) parameters).PublicKey;
}
else
{
kParam = (RsaKeyParameters) parameters;
}
emBits = kParam.Modulus.BitLength - 1;
if (emBits < (8 * hLen + 8 * sLen + 9))
throw new ArgumentException("key too small for specified hash and salt lengths");
block = new byte[(emBits + 7) / 8];
}
/// <summary> clear possible sensitive data</summary>
private void ClearBlock(
byte[] block)
{
Array.Clear(block, 0, block.Length);
}
/// <summary> update the internal digest with the byte b</summary>
public virtual void Update(
byte input)
{
contentDigest1.Update(input);
}
/// <summary> update the internal digest with the byte array in</summary>
public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
{
contentDigest1.BlockUpdate(input, inOff, length);
}
/// <summary> reset the internal state</summary>
public virtual void Reset()
{
contentDigest1.Reset();
}
/// <summary> Generate a signature for the message we've been loaded with using
/// the key we were initialised with.
/// </summary>
public virtual byte[] GenerateSignature()
{
contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen);
if (sLen != 0)
{
if (!sSet)
{
random.NextBytes(salt);
}
salt.CopyTo(mDash, mDash.Length - sLen);
}
byte[] h = new byte[hLen];
contentDigest2.BlockUpdate(mDash, 0, mDash.Length);
contentDigest2.DoFinal(h, 0);
block[block.Length - sLen - 1 - hLen - 1] = (byte) (0x01);
salt.CopyTo(block, block.Length - sLen - hLen - 1);
byte[] dbMask = MaskGeneratorFunction1(h, 0, h.Length, block.Length - hLen - 1);
for (int i = 0; i != dbMask.Length; i++)
{
block[i] ^= dbMask[i];
}
block[0] &= (byte) ((0xff >> ((block.Length * 8) - emBits)));
h.CopyTo(block, block.Length - hLen - 1);
block[block.Length - 1] = trailer;
byte[] b = cipher.ProcessBlock(block, 0, block.Length);
ClearBlock(block);
return b;
}
/// <summary> return true if the internal state represents the signature described
/// in the passed in array.
/// </summary>
public virtual bool VerifySignature(
byte[] signature)
{
contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen);
byte[] b = cipher.ProcessBlock(signature, 0, signature.Length);
b.CopyTo(block, block.Length - b.Length);
if (block[block.Length - 1] != trailer)
{
ClearBlock(block);
return false;
}
byte[] dbMask = MaskGeneratorFunction1(block, block.Length - hLen - 1, hLen, block.Length - hLen - 1);
for (int i = 0; i != dbMask.Length; i++)
{
block[i] ^= dbMask[i];
}
block[0] &= (byte) ((0xff >> ((block.Length * 8) - emBits)));
for (int i = 0; i != block.Length - hLen - sLen - 2; i++)
{
if (block[i] != 0)
{
ClearBlock(block);
return false;
}
}
if (block[block.Length - hLen - sLen - 2] != 0x01)
{
ClearBlock(block);
return false;
}
if (sSet)
{
Array.Copy(salt, 0, mDash, mDash.Length - sLen, sLen);
}
else
{
Array.Copy(block, block.Length - sLen - hLen - 1, mDash, mDash.Length - sLen, sLen);
}
contentDigest2.BlockUpdate(mDash, 0, mDash.Length);
contentDigest2.DoFinal(mDash, mDash.Length - hLen);
for (int i = block.Length - hLen - 1, j = mDash.Length - hLen; j != mDash.Length; i++, j++)
{
if ((block[i] ^ mDash[j]) != 0)
{
ClearBlock(mDash);
ClearBlock(block);
return false;
}
}
ClearBlock(mDash);
ClearBlock(block);
return true;
}
/// <summary> int to octet string.</summary>
private void ItoOSP(
int i,
byte[] sp)
{
sp[0] = (byte)((uint) i >> 24);
sp[1] = (byte)((uint) i >> 16);
sp[2] = (byte)((uint) i >> 8);
sp[3] = (byte)((uint) i >> 0);
}
/// <summary> mask generator function, as described in Pkcs1v2.</summary>
private byte[] MaskGeneratorFunction1(
byte[] Z,
int zOff,
int zLen,
int length)
{
byte[] mask = new byte[length];
byte[] hashBuf = new byte[mgfhLen];
byte[] C = new byte[4];
int counter = 0;
mgfDigest.Reset();
while (counter < (length / mgfhLen))
{
ItoOSP(counter, C);
mgfDigest.BlockUpdate(Z, zOff, zLen);
mgfDigest.BlockUpdate(C, 0, C.Length);
mgfDigest.DoFinal(hashBuf, 0);
hashBuf.CopyTo(mask, counter * mgfhLen);
++counter;
}
if ((counter * mgfhLen) < length)
{
ItoOSP(counter, C);
mgfDigest.BlockUpdate(Z, zOff, zLen);
mgfDigest.BlockUpdate(C, 0, C.Length);
mgfDigest.DoFinal(hashBuf, 0);
Array.Copy(hashBuf, 0, mask, counter * mgfhLen, mask.Length - (counter * mgfhLen));
}
return mask;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 695ba4f2df4cf4c8f901128a6241aad0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers
{
public class RandomDsaKCalculator
: IDsaKCalculator
{
private BigInteger q;
private SecureRandom random;
public virtual bool IsDeterministic
{
get { return false; }
}
public virtual void Init(BigInteger n, SecureRandom random)
{
this.q = n;
this.random = random;
}
public virtual void Init(BigInteger n, BigInteger d, byte[] message)
{
throw new InvalidOperationException("Operation not supported");
}
public virtual BigInteger NextK()
{
int qBitLength = q.BitLength;
BigInteger k;
do
{
k = new BigInteger(qBitLength, random);
}
while (k.SignValue < 1 || k.CompareTo(q) >= 0);
return k;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4278185bf105d4eadb0863332d3e2136
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,221 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
using System;
using System.Collections;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.Utilities;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers
{
public class RsaDigestSigner
: ISigner
{
private readonly IAsymmetricBlockCipher rsaEngine = new Pkcs1Encoding(new RsaBlindedEngine());
private readonly AlgorithmIdentifier algId;
private readonly IDigest digest;
private bool forSigning;
private static readonly IDictionary oidMap = Platform.CreateHashtable();
/// <summary>
/// Load oid table.
/// </summary>
static RsaDigestSigner()
{
oidMap["RIPEMD128"] = TeleTrusTObjectIdentifiers.RipeMD128;
oidMap["RIPEMD160"] = TeleTrusTObjectIdentifiers.RipeMD160;
oidMap["RIPEMD256"] = TeleTrusTObjectIdentifiers.RipeMD256;
oidMap["SHA-1"] = X509ObjectIdentifiers.IdSha1;
oidMap["SHA-224"] = NistObjectIdentifiers.IdSha224;
oidMap["SHA-256"] = NistObjectIdentifiers.IdSha256;
oidMap["SHA-384"] = NistObjectIdentifiers.IdSha384;
oidMap["SHA-512"] = NistObjectIdentifiers.IdSha512;
oidMap["MD2"] = PkcsObjectIdentifiers.MD2;
oidMap["MD4"] = PkcsObjectIdentifiers.MD4;
oidMap["MD5"] = PkcsObjectIdentifiers.MD5;
}
public RsaDigestSigner(IDigest digest)
: this(digest, (DerObjectIdentifier)oidMap[digest.AlgorithmName])
{
}
public RsaDigestSigner(IDigest digest, DerObjectIdentifier digestOid)
: this(digest, new AlgorithmIdentifier(digestOid, DerNull.Instance))
{
}
public RsaDigestSigner(IDigest digest, AlgorithmIdentifier algId)
{
this.digest = digest;
this.algId = algId;
}
public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "withRSA"; }
}
/**
* Initialise the signer for signing or verification.
*
* @param forSigning true if for signing, false otherwise
* @param param necessary parameters.
*/
public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
this.forSigning = forSigning;
AsymmetricKeyParameter k;
if (parameters is ParametersWithRandom)
{
k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters;
}
else
{
k = (AsymmetricKeyParameter)parameters;
}
if (forSigning && !k.IsPrivate)
throw new InvalidKeyException("Signing requires private key.");
if (!forSigning && k.IsPrivate)
throw new InvalidKeyException("Verification requires public key.");
Reset();
rsaEngine.Init(forSigning, parameters);
}
/**
* update the internal digest with the byte b
*/
public virtual void Update(
byte input)
{
digest.Update(input);
}
/**
* update the internal digest with the byte array in
*/
public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
{
digest.BlockUpdate(input, inOff, length);
}
/**
* Generate a signature for the message we've been loaded with using
* the key we were initialised with.
*/
public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("RsaDigestSigner not initialised for signature generation.");
byte[] hash = new byte[digest.GetDigestSize()];
digest.DoFinal(hash, 0);
byte[] data = DerEncode(hash);
return rsaEngine.ProcessBlock(data, 0, data.Length);
}
/**
* return true if the internal state represents the signature described
* in the passed in array.
*/
public virtual bool VerifySignature(
byte[] signature)
{
if (forSigning)
throw new InvalidOperationException("RsaDigestSigner not initialised for verification");
byte[] hash = new byte[digest.GetDigestSize()];
digest.DoFinal(hash, 0);
byte[] sig;
byte[] expected;
try
{
sig = rsaEngine.ProcessBlock(signature, 0, signature.Length);
expected = DerEncode(hash);
}
catch (Exception)
{
return false;
}
if (sig.Length == expected.Length)
{
return Arrays.ConstantTimeAreEqual(sig, expected);
}
else if (sig.Length == expected.Length - 2) // NULL left out
{
int sigOffset = sig.Length - hash.Length - 2;
int expectedOffset = expected.Length - hash.Length - 2;
expected[1] -= 2; // adjust lengths
expected[3] -= 2;
int nonEqual = 0;
for (int i = 0; i < hash.Length; i++)
{
nonEqual |= (sig[sigOffset + i] ^ expected[expectedOffset + i]);
}
for (int i = 0; i < sigOffset; i++)
{
nonEqual |= (sig[i] ^ expected[i]); // check header less NULL
}
return nonEqual == 0;
}
else
{
return false;
}
}
public virtual void Reset()
{
digest.Reset();
}
private byte[] DerEncode(byte[] hash)
{
if (algId == null)
{
// For raw RSA, the DigestInfo must be prepared externally
return hash;
}
DigestInfo dInfo = new DigestInfo(algId, hash);
return dInfo.GetDerEncoded();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 68cce63e9f34c49a4a205ea61ae442e1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,229 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
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
{
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_IMPLICIT = 0xBC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_RIPEMD160 = 0x31CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_RIPEMD128 = 0x32CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_SHA1 = 0x33CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_SHA256 = 0x34CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_SHA512 = 0x35CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_SHA384 = 0x36CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_WHIRLPOOL = 0x37CC;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_SHA224 = 0x38CC;
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();
}
/// <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 == 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;
}
/**
* 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(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();
byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
bool rv = Arrays.ConstantTimeAreEqual(block, fBlock);
ClearBlock(block);
ClearBlock(fBlock);
return rv;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7344702a9197a473cbdde551525e0a5b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: