add all
This commit is contained in:
130
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/DsaDigestSigner.cs
vendored
Normal file
130
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/DsaDigestSigner.cs
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
#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.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
public class DsaDigestSigner
|
||||
: ISigner
|
||||
{
|
||||
private readonly IDsa dsa;
|
||||
private readonly IDigest digest;
|
||||
private readonly IDsaEncoding encoding;
|
||||
private bool forSigning;
|
||||
|
||||
public DsaDigestSigner(IDsa dsa, IDigest digest)
|
||||
: this(dsa, digest, StandardDsaEncoding.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
public DsaDigestSigner(IDsa dsa, IDigest digest, IDsaEncoding encoding)
|
||||
{
|
||||
this.dsa = dsa;
|
||||
this.digest = digest;
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public virtual string AlgorithmName
|
||||
{
|
||||
get { return digest.AlgorithmName + "with" + dsa.AlgorithmName; }
|
||||
}
|
||||
|
||||
public virtual void Init(bool forSigning, ICipherParameters parameters)
|
||||
{
|
||||
this.forSigning = forSigning;
|
||||
|
||||
AsymmetricKeyParameter k;
|
||||
if (parameters is ParametersWithRandom withRandom)
|
||||
{
|
||||
k = (AsymmetricKeyParameter)withRandom.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();
|
||||
|
||||
dsa.Init(forSigning, parameters);
|
||||
}
|
||||
|
||||
public virtual void Update(byte input)
|
||||
{
|
||||
digest.Update(input);
|
||||
}
|
||||
|
||||
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 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 = dsa.GenerateSignature(hash);
|
||||
|
||||
try
|
||||
{
|
||||
return encoding.Encode(GetOrder(), sig[0], sig[1]);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new InvalidOperationException("unable to encode signature");
|
||||
}
|
||||
}
|
||||
|
||||
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 = encoding.Decode(GetOrder(), signature);
|
||||
|
||||
return dsa.VerifySignature(hash, sig[0], sig[1]);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
digest.Reset();
|
||||
}
|
||||
|
||||
protected virtual BigInteger GetOrder()
|
||||
{
|
||||
return dsa.Order;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 487af9cbb3780ce4391f6b50a2ef029b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
165
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/DsaSigner.cs
vendored
Normal file
165
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/DsaSigner.cs
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
#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.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.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);
|
||||
}
|
||||
|
||||
public virtual BigInteger Order
|
||||
{
|
||||
get { return key.Parameters.Q; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = BigIntegers.ModOddInverse(q, k).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 = BigIntegers.ModOddInverseVar(q, s);
|
||||
|
||||
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 : CryptoServicesRegistrar.GetSecureRandom(provided);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/DsaSigner.cs.meta
vendored
Normal file
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/DsaSigner.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 016fe8d4eaf679243a116a20525e9388
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
249
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/ECDsaSigner.cs
vendored
Normal file
249
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/ECDsaSigner.cs
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
#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.Math.EC;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.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);
|
||||
}
|
||||
|
||||
public virtual BigInteger Order
|
||||
{
|
||||
get { return key.Parameters.N; }
|
||||
}
|
||||
|
||||
// 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 = BigIntegers.ModOddInverse(n, k).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 = BigIntegers.ModOddInverseVar(n, s);
|
||||
|
||||
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 : CryptoServicesRegistrar.GetSecureRandom(provided);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/ECDsaSigner.cs.meta
vendored
Normal file
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/ECDsaSigner.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 553f34bfb968d9e458a9810e771b2acf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
155
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/ECGOST3410Signer.cs
vendored
Normal file
155
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/ECGOST3410Signer.cs
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
#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.Math.EC;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
/**
|
||||
* GOST R 34.10-2001 Signature Algorithm
|
||||
*/
|
||||
public class ECGost3410Signer
|
||||
: IDsa
|
||||
{
|
||||
private ECKeyParameters key;
|
||||
private SecureRandom random;
|
||||
private bool forSigning;
|
||||
|
||||
public virtual string AlgorithmName
|
||||
{
|
||||
get { return key.AlgorithmName; }
|
||||
}
|
||||
|
||||
public virtual void Init(bool forSigning, ICipherParameters parameters)
|
||||
{
|
||||
this.forSigning = forSigning;
|
||||
|
||||
if (forSigning)
|
||||
{
|
||||
if (parameters is ParametersWithRandom rParam)
|
||||
{
|
||||
this.random = rParam.Random;
|
||||
parameters = rParam.Parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.random = CryptoServicesRegistrar.GetSecureRandom();
|
||||
}
|
||||
|
||||
if (!(parameters is ECPrivateKeyParameters ecPrivateKeyParameters))
|
||||
throw new InvalidKeyException("EC private key required for signing");
|
||||
|
||||
this.key = ecPrivateKeyParameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(parameters is ECPublicKeyParameters ecPublicKeyParameters))
|
||||
throw new InvalidKeyException("EC public key required for verification");
|
||||
|
||||
this.key = ecPublicKeyParameters;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger Order => key.Parameters.N;
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if (!forSigning)
|
||||
throw new InvalidOperationException("not initialized for signing");
|
||||
|
||||
byte[] mRev = Arrays.Reverse(message); // conversion is little-endian
|
||||
BigInteger e = new BigInteger(1, mRev);
|
||||
|
||||
ECDomainParameters ec = key.Parameters;
|
||||
BigInteger n = ec.N;
|
||||
BigInteger d = ((ECPrivateKeyParameters)key).D;
|
||||
|
||||
BigInteger r, s;
|
||||
|
||||
ECMultiplier basePointMultiplier = CreateBasePointMultiplier();
|
||||
|
||||
do // generate s
|
||||
{
|
||||
BigInteger k;
|
||||
do // generate r
|
||||
{
|
||||
do
|
||||
{
|
||||
k = BigIntegers.CreateRandomBigInteger(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)
|
||||
{
|
||||
if (forSigning)
|
||||
throw new InvalidOperationException("not initialized for verification");
|
||||
|
||||
byte[] mRev = Arrays.Reverse(message); // conversion is little-endian
|
||||
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 = BigIntegers.ModOddInverseVar(n, e);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a99f6c7425d04f43abde96df9a1c8e0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
193
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/ECNRSigner.cs
vendored
Normal file
193
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/ECNRSigner.cs
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.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 rParam)
|
||||
{
|
||||
this.random = rParam.Random;
|
||||
parameters = rParam.Parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.random = CryptoServicesRegistrar.GetSecureRandom();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger Order
|
||||
{
|
||||
get { return key.Parameters.N; }
|
||||
}
|
||||
|
||||
// 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 = Order;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/ECNRSigner.cs.meta
vendored
Normal file
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/ECNRSigner.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a94d3c3fe5827ec489261fe5d6504965
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
134
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed25519Signer.cs
vendored
Normal file
134
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed25519Signer.cs
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Rfc8032;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
public class Ed25519Signer
|
||||
: ISigner
|
||||
{
|
||||
private readonly Buffer buffer = new Buffer();
|
||||
|
||||
private bool forSigning;
|
||||
private Ed25519PrivateKeyParameters privateKey;
|
||||
private Ed25519PublicKeyParameters publicKey;
|
||||
|
||||
public Ed25519Signer()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual string AlgorithmName
|
||||
{
|
||||
get { return "Ed25519"; }
|
||||
}
|
||||
|
||||
public virtual void Init(bool forSigning, ICipherParameters parameters)
|
||||
{
|
||||
this.forSigning = forSigning;
|
||||
|
||||
if (forSigning)
|
||||
{
|
||||
this.privateKey = (Ed25519PrivateKeyParameters)parameters;
|
||||
this.publicKey = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.privateKey = null;
|
||||
this.publicKey = (Ed25519PublicKeyParameters)parameters;
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
public virtual void Update(byte b)
|
||||
{
|
||||
buffer.WriteByte(b);
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] buf, int off, int len)
|
||||
{
|
||||
buffer.Write(buf, off, len);
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
|
||||
{
|
||||
buffer.Write(input);
|
||||
}
|
||||
#endif
|
||||
|
||||
public virtual byte[] GenerateSignature()
|
||||
{
|
||||
if (!forSigning || null == privateKey)
|
||||
throw new InvalidOperationException("Ed25519Signer not initialised for signature generation.");
|
||||
|
||||
return buffer.GenerateSignature(privateKey);
|
||||
}
|
||||
|
||||
public virtual bool VerifySignature(byte[] signature)
|
||||
{
|
||||
if (forSigning || null == publicKey)
|
||||
throw new InvalidOperationException("Ed25519Signer not initialised for verification");
|
||||
|
||||
return buffer.VerifySignature(publicKey, signature);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
buffer.Reset();
|
||||
}
|
||||
|
||||
private class Buffer : MemoryStream
|
||||
{
|
||||
internal byte[] GenerateSignature(Ed25519PrivateKeyParameters privateKey)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
byte[] buf = GetBuffer();
|
||||
int count = Convert.ToInt32(Length);
|
||||
|
||||
byte[] signature = new byte[Ed25519PrivateKeyParameters.SignatureSize];
|
||||
privateKey.Sign(Ed25519.Algorithm.Ed25519, null, buf, 0, count, signature, 0);
|
||||
Reset();
|
||||
return signature;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool VerifySignature(Ed25519PublicKeyParameters publicKey, byte[] signature)
|
||||
{
|
||||
if (Ed25519.SignatureSize != signature.Length)
|
||||
{
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
lock (this)
|
||||
{
|
||||
byte[] buf = GetBuffer();
|
||||
int count = Convert.ToInt32(Length);
|
||||
|
||||
byte[] pk = publicKey.GetEncoded();
|
||||
bool result = Ed25519.Verify(signature, 0, pk, 0, buf, 0, count);
|
||||
Reset();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
int count = Convert.ToInt32(Length);
|
||||
Array.Clear(GetBuffer(), 0, count);
|
||||
SetLength(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0935cb761421a742a943902beecf5bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
137
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed25519ctxSigner.cs
vendored
Normal file
137
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed25519ctxSigner.cs
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Rfc8032;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
public class Ed25519ctxSigner
|
||||
: ISigner
|
||||
{
|
||||
private readonly Buffer buffer = new Buffer();
|
||||
private readonly byte[] context;
|
||||
|
||||
private bool forSigning;
|
||||
private Ed25519PrivateKeyParameters privateKey;
|
||||
private Ed25519PublicKeyParameters publicKey;
|
||||
|
||||
public Ed25519ctxSigner(byte[] context)
|
||||
{
|
||||
this.context = Arrays.Clone(context);
|
||||
}
|
||||
|
||||
public virtual string AlgorithmName
|
||||
{
|
||||
get { return "Ed25519ctx"; }
|
||||
}
|
||||
|
||||
public virtual void Init(bool forSigning, ICipherParameters parameters)
|
||||
{
|
||||
this.forSigning = forSigning;
|
||||
|
||||
if (forSigning)
|
||||
{
|
||||
this.privateKey = (Ed25519PrivateKeyParameters)parameters;
|
||||
this.publicKey = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.privateKey = null;
|
||||
this.publicKey = (Ed25519PublicKeyParameters)parameters;
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
public virtual void Update(byte b)
|
||||
{
|
||||
buffer.WriteByte(b);
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] buf, int off, int len)
|
||||
{
|
||||
buffer.Write(buf, off, len);
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
|
||||
{
|
||||
buffer.Write(input);
|
||||
}
|
||||
#endif
|
||||
|
||||
public virtual byte[] GenerateSignature()
|
||||
{
|
||||
if (!forSigning || null == privateKey)
|
||||
throw new InvalidOperationException("Ed25519ctxSigner not initialised for signature generation.");
|
||||
|
||||
return buffer.GenerateSignature(privateKey, context);
|
||||
}
|
||||
|
||||
public virtual bool VerifySignature(byte[] signature)
|
||||
{
|
||||
if (forSigning || null == publicKey)
|
||||
throw new InvalidOperationException("Ed25519ctxSigner not initialised for verification");
|
||||
|
||||
return buffer.VerifySignature(publicKey, context, signature);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
buffer.Reset();
|
||||
}
|
||||
|
||||
private class Buffer : MemoryStream
|
||||
{
|
||||
internal byte[] GenerateSignature(Ed25519PrivateKeyParameters privateKey, byte[] ctx)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
byte[] buf = GetBuffer();
|
||||
int count = Convert.ToInt32(Length);
|
||||
|
||||
byte[] signature = new byte[Ed25519PrivateKeyParameters.SignatureSize];
|
||||
privateKey.Sign(Ed25519.Algorithm.Ed25519ctx, ctx, buf, 0, count, signature, 0);
|
||||
Reset();
|
||||
return signature;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool VerifySignature(Ed25519PublicKeyParameters publicKey, byte[] ctx, byte[] signature)
|
||||
{
|
||||
if (Ed25519.SignatureSize != signature.Length)
|
||||
{
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
lock (this)
|
||||
{
|
||||
byte[] buf = GetBuffer();
|
||||
int count = Convert.ToInt32(Length);
|
||||
|
||||
byte[] pk = publicKey.GetEncoded();
|
||||
bool result = Ed25519.Verify(signature, 0, pk, 0, ctx, buf, 0, count);
|
||||
Reset();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
int count = Convert.ToInt32(Length);
|
||||
Array.Clear(GetBuffer(), 0, count);
|
||||
SetLength(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4a91712f2dcf604a9fa460bf6159551
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
102
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed25519phSigner.cs
vendored
Normal file
102
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed25519phSigner.cs
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Rfc8032;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
public class Ed25519phSigner
|
||||
: ISigner
|
||||
{
|
||||
private readonly IDigest prehash = Ed25519.CreatePrehash();
|
||||
private readonly byte[] context;
|
||||
|
||||
private bool forSigning;
|
||||
private Ed25519PrivateKeyParameters privateKey;
|
||||
private Ed25519PublicKeyParameters publicKey;
|
||||
|
||||
public Ed25519phSigner(byte[] context)
|
||||
{
|
||||
this.context = Arrays.Clone(context);
|
||||
}
|
||||
|
||||
public virtual string AlgorithmName
|
||||
{
|
||||
get { return "Ed25519ph"; }
|
||||
}
|
||||
|
||||
public virtual void Init(bool forSigning, ICipherParameters parameters)
|
||||
{
|
||||
this.forSigning = forSigning;
|
||||
|
||||
if (forSigning)
|
||||
{
|
||||
this.privateKey = (Ed25519PrivateKeyParameters)parameters;
|
||||
this.publicKey = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.privateKey = null;
|
||||
this.publicKey = (Ed25519PublicKeyParameters)parameters;
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
public virtual void Update(byte b)
|
||||
{
|
||||
prehash.Update(b);
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] buf, int off, int len)
|
||||
{
|
||||
prehash.BlockUpdate(buf, off, len);
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
|
||||
{
|
||||
prehash.BlockUpdate(input);
|
||||
}
|
||||
#endif
|
||||
|
||||
public virtual byte[] GenerateSignature()
|
||||
{
|
||||
if (!forSigning || null == privateKey)
|
||||
throw new InvalidOperationException("Ed25519phSigner not initialised for signature generation.");
|
||||
|
||||
byte[] msg = new byte[Ed25519.PrehashSize];
|
||||
if (Ed25519.PrehashSize != prehash.DoFinal(msg, 0))
|
||||
throw new InvalidOperationException("Prehash digest failed");
|
||||
|
||||
byte[] signature = new byte[Ed25519PrivateKeyParameters.SignatureSize];
|
||||
privateKey.Sign(Ed25519.Algorithm.Ed25519ph, context, msg, 0, Ed25519.PrehashSize, signature, 0);
|
||||
return signature;
|
||||
}
|
||||
|
||||
public virtual bool VerifySignature(byte[] signature)
|
||||
{
|
||||
if (forSigning || null == publicKey)
|
||||
throw new InvalidOperationException("Ed25519phSigner not initialised for verification");
|
||||
if (Ed25519.SignatureSize != signature.Length)
|
||||
{
|
||||
prehash.Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] pk = publicKey.GetEncoded();
|
||||
return Ed25519.VerifyPrehash(signature, 0, pk, 0, context, prehash);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
prehash.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1afa3f95612dbd94e819615aa0720877
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
137
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed448Signer.cs
vendored
Normal file
137
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed448Signer.cs
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Rfc8032;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
public class Ed448Signer
|
||||
: ISigner
|
||||
{
|
||||
private readonly Buffer buffer = new Buffer();
|
||||
private readonly byte[] context;
|
||||
|
||||
private bool forSigning;
|
||||
private Ed448PrivateKeyParameters privateKey;
|
||||
private Ed448PublicKeyParameters publicKey;
|
||||
|
||||
public Ed448Signer(byte[] context)
|
||||
{
|
||||
this.context = Arrays.Clone(context);
|
||||
}
|
||||
|
||||
public virtual string AlgorithmName
|
||||
{
|
||||
get { return "Ed448"; }
|
||||
}
|
||||
|
||||
public virtual void Init(bool forSigning, ICipherParameters parameters)
|
||||
{
|
||||
this.forSigning = forSigning;
|
||||
|
||||
if (forSigning)
|
||||
{
|
||||
this.privateKey = (Ed448PrivateKeyParameters)parameters;
|
||||
this.publicKey = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.privateKey = null;
|
||||
this.publicKey = (Ed448PublicKeyParameters)parameters;
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
public virtual void Update(byte b)
|
||||
{
|
||||
buffer.WriteByte(b);
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] buf, int off, int len)
|
||||
{
|
||||
buffer.Write(buf, off, len);
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
|
||||
{
|
||||
buffer.Write(input);
|
||||
}
|
||||
#endif
|
||||
|
||||
public virtual byte[] GenerateSignature()
|
||||
{
|
||||
if (!forSigning || null == privateKey)
|
||||
throw new InvalidOperationException("Ed448Signer not initialised for signature generation.");
|
||||
|
||||
return buffer.GenerateSignature(privateKey, context);
|
||||
}
|
||||
|
||||
public virtual bool VerifySignature(byte[] signature)
|
||||
{
|
||||
if (forSigning || null == publicKey)
|
||||
throw new InvalidOperationException("Ed448Signer not initialised for verification");
|
||||
|
||||
return buffer.VerifySignature(publicKey, context, signature);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
buffer.Reset();
|
||||
}
|
||||
|
||||
private class Buffer : MemoryStream
|
||||
{
|
||||
internal byte[] GenerateSignature(Ed448PrivateKeyParameters privateKey, byte[] ctx)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
byte[] buf = GetBuffer();
|
||||
int count = Convert.ToInt32(Length);
|
||||
|
||||
byte[] signature = new byte[Ed448PrivateKeyParameters.SignatureSize];
|
||||
privateKey.Sign(Ed448.Algorithm.Ed448, ctx, buf, 0, count, signature, 0);
|
||||
Reset();
|
||||
return signature;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool VerifySignature(Ed448PublicKeyParameters publicKey, byte[] ctx, byte[] signature)
|
||||
{
|
||||
if (Ed448.SignatureSize != signature.Length)
|
||||
{
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
lock (this)
|
||||
{
|
||||
byte[] buf = GetBuffer();
|
||||
int count = Convert.ToInt32(Length);
|
||||
|
||||
byte[] pk = publicKey.GetEncoded();
|
||||
bool result = Ed448.Verify(signature, 0, pk, 0, ctx, buf, 0, count);
|
||||
Reset();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
int count = Convert.ToInt32(Length);
|
||||
Array.Clear(GetBuffer(), 0, count);
|
||||
SetLength(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed448Signer.cs.meta
vendored
Normal file
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed448Signer.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b8bb0258b551114893b817b5671ebed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
102
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed448phSigner.cs
vendored
Normal file
102
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Ed448phSigner.cs
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Rfc8032;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
public class Ed448phSigner
|
||||
: ISigner
|
||||
{
|
||||
private readonly IXof prehash = Ed448.CreatePrehash();
|
||||
private readonly byte[] context;
|
||||
|
||||
private bool forSigning;
|
||||
private Ed448PrivateKeyParameters privateKey;
|
||||
private Ed448PublicKeyParameters publicKey;
|
||||
|
||||
public Ed448phSigner(byte[] context)
|
||||
{
|
||||
this.context = Arrays.Clone(context);
|
||||
}
|
||||
|
||||
public virtual string AlgorithmName
|
||||
{
|
||||
get { return "Ed448ph"; }
|
||||
}
|
||||
|
||||
public virtual void Init(bool forSigning, ICipherParameters parameters)
|
||||
{
|
||||
this.forSigning = forSigning;
|
||||
|
||||
if (forSigning)
|
||||
{
|
||||
this.privateKey = (Ed448PrivateKeyParameters)parameters;
|
||||
this.publicKey = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.privateKey = null;
|
||||
this.publicKey = (Ed448PublicKeyParameters)parameters;
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
public virtual void Update(byte b)
|
||||
{
|
||||
prehash.Update(b);
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] buf, int off, int len)
|
||||
{
|
||||
prehash.BlockUpdate(buf, off, len);
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
|
||||
{
|
||||
prehash.BlockUpdate(input);
|
||||
}
|
||||
#endif
|
||||
|
||||
public virtual byte[] GenerateSignature()
|
||||
{
|
||||
if (!forSigning || null == privateKey)
|
||||
throw new InvalidOperationException("Ed448phSigner not initialised for signature generation.");
|
||||
|
||||
byte[] msg = new byte[Ed448.PrehashSize];
|
||||
if (Ed448.PrehashSize != prehash.OutputFinal(msg, 0, Ed448.PrehashSize))
|
||||
throw new InvalidOperationException("Prehash digest failed");
|
||||
|
||||
byte[] signature = new byte[Ed448PrivateKeyParameters.SignatureSize];
|
||||
privateKey.Sign(Ed448.Algorithm.Ed448ph, context, msg, 0, Ed448.PrehashSize, signature, 0);
|
||||
return signature;
|
||||
}
|
||||
|
||||
public virtual bool VerifySignature(byte[] signature)
|
||||
{
|
||||
if (forSigning || null == publicKey)
|
||||
throw new InvalidOperationException("Ed448phSigner not initialised for verification");
|
||||
if (Ed448.SignatureSize != signature.Length)
|
||||
{
|
||||
prehash.Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] pk = publicKey.GetEncoded();
|
||||
return Ed448.VerifyPrehash(signature, 0, pk, 0, context, prehash);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
prehash.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12fe22a83e9cad34ab8654655b71a93b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
137
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/GOST3410DigestSigner.cs
vendored
Normal file
137
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/GOST3410DigestSigner.cs
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
#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.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
public class Gost3410DigestSigner
|
||||
: ISigner
|
||||
{
|
||||
private readonly IDigest digest;
|
||||
private readonly IDsa dsaSigner;
|
||||
private readonly int size;
|
||||
private int halfSize;
|
||||
private bool forSigning;
|
||||
|
||||
public Gost3410DigestSigner(IDsa signer, IDigest digest)
|
||||
{
|
||||
this.dsaSigner = signer;
|
||||
this.digest = digest;
|
||||
|
||||
halfSize = digest.GetDigestSize();
|
||||
this.size = halfSize * 2;
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public virtual void Update(byte input)
|
||||
{
|
||||
digest.Update(input);
|
||||
}
|
||||
|
||||
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 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[size];
|
||||
|
||||
// TODO Add methods to allow writing BigInteger to existing byte array?
|
||||
byte[] r = sig[0].ToByteArrayUnsigned();
|
||||
byte[] s = sig[1].ToByteArrayUnsigned();
|
||||
s.CopyTo(sigBytes, halfSize - s.Length);
|
||||
r.CopyTo(sigBytes, size - r.Length);
|
||||
return sigBytes;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new SignatureException(e.Message, e);
|
||||
}
|
||||
}
|
||||
|
||||
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, halfSize, halfSize);
|
||||
S = new BigInteger(1, signature, 0, halfSize);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new SignatureException("error decoding signature bytes.", e);
|
||||
}
|
||||
|
||||
return dsaSigner.VerifySignature(hash, R, S);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
digest.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ce97acf4153cf643b9786312fcdd2d3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
128
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/GOST3410Signer.cs
vendored
Normal file
128
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/GOST3410Signer.cs
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
#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.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.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 rParam)
|
||||
{
|
||||
this.random = rParam.Random;
|
||||
parameters = rParam.Parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.random = CryptoServicesRegistrar.GetSecureRandom();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BigInteger Order
|
||||
{
|
||||
get { return key.Parameters.Q; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = Arrays.Reverse(message); // conversion is little-endian
|
||||
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 = Arrays.Reverse(message); // conversion is little-endian
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe6a597729247cd4a9ff4c882f553f79
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
127
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/GenericSigner.cs
vendored
Normal file
127
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/GenericSigner.cs
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
#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.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.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);
|
||||
}
|
||||
|
||||
public virtual void Update(byte input)
|
||||
{
|
||||
digest.Update(input);
|
||||
}
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41a534d5ac923ca41994ba43c95d82aa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
169
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/HMacDsaKCalculator.cs
vendored
Normal file
169
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/HMacDsaKCalculator.cs
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.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, 0x01);
|
||||
Arrays.Fill(K, 0);
|
||||
|
||||
BigInteger mInt = BitsToInt(message);
|
||||
if (mInt.CompareTo(n) >= 0)
|
||||
{
|
||||
mInt = mInt.Subtract(n);
|
||||
}
|
||||
|
||||
int size = BigIntegers.GetUnsignedByteLength(n);
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
int xmSize = size * 2;
|
||||
Span<byte> xm = xmSize <= 512
|
||||
? stackalloc byte[xmSize]
|
||||
: new byte[xmSize];
|
||||
BigIntegers.AsUnsignedByteArray(d, xm[..size]);
|
||||
BigIntegers.AsUnsignedByteArray(mInt, xm[size..]);
|
||||
#else
|
||||
byte[] x = BigIntegers.AsUnsignedByteArray(size, d);
|
||||
byte[] m = BigIntegers.AsUnsignedByteArray(size, mInt);
|
||||
#endif
|
||||
|
||||
hMac.Init(new KeyParameter(K));
|
||||
|
||||
hMac.BlockUpdate(V, 0, V.Length);
|
||||
hMac.Update(0x00);
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
hMac.BlockUpdate(xm);
|
||||
#else
|
||||
hMac.BlockUpdate(x, 0, x.Length);
|
||||
hMac.BlockUpdate(m, 0, m.Length);
|
||||
#endif
|
||||
InitAdditionalInput0(hMac);
|
||||
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(0x01);
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
hMac.BlockUpdate(xm);
|
||||
#else
|
||||
hMac.BlockUpdate(x, 0, x.Length);
|
||||
hMac.BlockUpdate(m, 0, m.Length);
|
||||
#endif
|
||||
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[BigIntegers.GetUnsignedByteLength(n)];
|
||||
|
||||
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(0x00);
|
||||
hMac.DoFinal(K, 0);
|
||||
|
||||
hMac.Init(new KeyParameter(K));
|
||||
hMac.BlockUpdate(V, 0, V.Length);
|
||||
hMac.DoFinal(V, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Supports use of additional input.</summary>
|
||||
/// <remarks>
|
||||
/// RFC 6979 3.6. Additional data may be added to the input of HMAC [..]. A use case may be a protocol that
|
||||
/// requires a non-deterministic signature algorithm on a system that does not have access to a high-quality
|
||||
/// random source. It suffices that the additional data[..] is non-repeating(e.g., a signature counter or a
|
||||
/// monotonic clock) to ensure "random-looking" signatures are indistinguishable, in a cryptographic way, from
|
||||
/// plain (EC)DSA signatures.
|
||||
/// <para/>
|
||||
/// By default there is no additional input. Override this method to supply additional input, bearing in mind
|
||||
/// that this calculator may be used for many signatures.
|
||||
/// </remarks>
|
||||
/// <param name="hmac0">The <see cref="HMac"/> to which the additional input should be added.</param>
|
||||
protected virtual void InitAdditionalInput0(HMac hmac0)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 969291a7bd4e5d245b4e357074ec29c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
29
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/IDsaEncoding.cs
vendored
Normal file
29
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/IDsaEncoding.cs
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface for different encoding formats for DSA signatures.
|
||||
/// </summary>
|
||||
public interface IDsaEncoding
|
||||
{
|
||||
/// <summary>Decode the (r, s) pair of a DSA signature.</summary>
|
||||
/// <param name="n">The order of the group that r, s belong to.</param>
|
||||
/// <param name="encoding">An encoding of the (r, s) pair of a DSA signature.</param>
|
||||
/// <returns>The (r, s) of a DSA signature, stored in an array of exactly two elements, r followed by s.</returns>
|
||||
BigInteger[] Decode(BigInteger n, byte[] encoding);
|
||||
|
||||
/// <summary>Encode the (r, s) pair of a DSA signature.</summary>
|
||||
/// <param name="n">The order of the group that r, s belong to.</param>
|
||||
/// <param name="r">The r value of a DSA signature.</param>
|
||||
/// <param name="s">The s value of a DSA signature.</param>
|
||||
/// <returns>An encoding of the DSA signature given by the provided (r, s) pair.</returns>
|
||||
byte[] Encode(BigInteger n, BigInteger r, BigInteger s);
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/IDsaEncoding.cs.meta
vendored
Normal file
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/IDsaEncoding.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16af24b9a2f88be4c8db714458e9b414
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
48
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/IDsaKCalculator.cs
vendored
Normal file
48
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/IDsaKCalculator.cs
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.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();
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e5243a39b34b0c4baecc8dd9f340769
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
617
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Iso9796d2PssSigner.cs
vendored
Normal file
617
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Iso9796d2PssSigner.cs
vendored
Normal file
@@ -0,0 +1,617 @@
|
||||
#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.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
/// <summary> ISO9796-2 - mechanism using a hash function with recovery (scheme 2 and 3).
|
||||
/// <p>
|
||||
/// Note: the usual length for the salt is the length of the hash
|
||||
/// function used in bytes.</p>
|
||||
/// </summary>
|
||||
public class Iso9796d2PssSigner
|
||||
: 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;
|
||||
}
|
||||
|
||||
private IDigest digest;
|
||||
private IAsymmetricBlockCipher cipher;
|
||||
|
||||
private SecureRandom random;
|
||||
private byte[] standardSalt;
|
||||
|
||||
private int hLen;
|
||||
private int trailer;
|
||||
private int keyBits;
|
||||
private byte[] block;
|
||||
private byte[] mBuf;
|
||||
private int messageLength;
|
||||
private readonly int saltLength;
|
||||
private bool fullMessage;
|
||||
private byte[] recoveredMessage;
|
||||
|
||||
private byte[] preSig;
|
||||
private byte[] preBlock;
|
||||
private int preMStart;
|
||||
private int preTLength;
|
||||
|
||||
/// <summary>
|
||||
/// Generate a signer with either implicit or explicit trailers for ISO9796-2, scheme 2 or 3.
|
||||
/// </summary>
|
||||
/// <param name="cipher">base cipher to use for signature creation/verification</param>
|
||||
/// <param name="digest">digest to use.</param>
|
||||
/// <param name="saltLength">length of salt in bytes.</param>
|
||||
/// <param name="isImplicit">whether or not the trailer is implicit or gives the hash.</param>
|
||||
public Iso9796d2PssSigner(
|
||||
IAsymmetricBlockCipher cipher,
|
||||
IDigest digest,
|
||||
int saltLength,
|
||||
bool isImplicit)
|
||||
{
|
||||
this.cipher = cipher;
|
||||
this.digest = digest;
|
||||
this.hLen = digest.GetDigestSize();
|
||||
this.saltLength = saltLength;
|
||||
|
||||
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>
|
||||
/// <param name="saltLength">length of salt in bytes.
|
||||
/// </param>
|
||||
public Iso9796d2PssSigner(
|
||||
IAsymmetricBlockCipher cipher,
|
||||
IDigest digest,
|
||||
int saltLength)
|
||||
: this(cipher, digest, saltLength, false)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual string AlgorithmName
|
||||
{
|
||||
get { return digest.AlgorithmName + "with" + "ISO9796-2S2"; }
|
||||
}
|
||||
|
||||
/// <summary>Initialise the signer.</summary>
|
||||
/// <param name="forSigning">true if for signing, false if for verification.</param>
|
||||
/// <param name="parameters">parameters for signature generation/verification. If the
|
||||
/// parameters are for generation they should be a ParametersWithRandom,
|
||||
/// a ParametersWithSalt, or just an RsaKeyParameters object. If RsaKeyParameters
|
||||
/// are passed in a SecureRandom will be created.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">if wrong parameter type or a fixed
|
||||
/// salt is passed in which is the wrong length.
|
||||
/// </exception>
|
||||
public virtual void Init(bool forSigning, ICipherParameters parameters)
|
||||
{
|
||||
RsaKeyParameters kParam;
|
||||
if (parameters is ParametersWithRandom withRandom)
|
||||
{
|
||||
kParam = (RsaKeyParameters)withRandom.Parameters;
|
||||
|
||||
if (forSigning)
|
||||
{
|
||||
random = withRandom.Random;
|
||||
}
|
||||
}
|
||||
else if (parameters is ParametersWithSalt withSalt)
|
||||
{
|
||||
if (!forSigning)
|
||||
throw new ArgumentException("ParametersWithSalt only valid for signing", nameof(parameters));
|
||||
|
||||
kParam = (RsaKeyParameters)withSalt.Parameters;
|
||||
standardSalt = withSalt.GetSalt();
|
||||
|
||||
if (standardSalt.Length != saltLength)
|
||||
throw new ArgumentException("Fixed salt is of wrong length");
|
||||
}
|
||||
else
|
||||
{
|
||||
kParam = (RsaKeyParameters)parameters;
|
||||
|
||||
if (forSigning)
|
||||
{
|
||||
random = CryptoServicesRegistrar.GetSecureRandom();
|
||||
}
|
||||
}
|
||||
|
||||
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() - saltLength - 1 - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
mBuf = new byte[block.Length - digest.GetDigestSize() - saltLength - 1 - 2];
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
/// <summary> compare two byte arrays - constant time.</summary>
|
||||
private bool IsSameAs(byte[] a, byte[] b)
|
||||
{
|
||||
if (messageLength != b.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isOkay = true;
|
||||
|
||||
for (int i = 0; i != b.Length; 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);
|
||||
|
||||
//
|
||||
// adjust block size for leading zeroes if necessary
|
||||
//
|
||||
if (block.Length < (keyBits + 7) / 8)
|
||||
{
|
||||
byte[] tmp = new byte[(keyBits + 7) / 8];
|
||||
|
||||
Array.Copy(block, 0, tmp, tmp.Length - block.Length, block.Length);
|
||||
ClearBlock(block);
|
||||
block = tmp;
|
||||
}
|
||||
|
||||
int tLength;
|
||||
|
||||
if (((block[block.Length - 1] & 0xFF) ^ 0xBC) == 0)
|
||||
{
|
||||
tLength = 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);
|
||||
|
||||
tLength = 2;
|
||||
}
|
||||
|
||||
//
|
||||
// calculate H(m2)
|
||||
//
|
||||
byte[] m2Hash = new byte[hLen];
|
||||
digest.DoFinal(m2Hash, 0);
|
||||
|
||||
//
|
||||
// remove the mask
|
||||
//
|
||||
byte[] dbMask = MaskGeneratorFunction1(block, block.Length - hLen - tLength, hLen, block.Length - hLen - tLength);
|
||||
for (int i = 0; i != dbMask.Length; i++)
|
||||
{
|
||||
block[i] ^= dbMask[i];
|
||||
}
|
||||
|
||||
block[0] &= 0x7f;
|
||||
|
||||
//
|
||||
// find out how much padding we've got
|
||||
//
|
||||
int mStart = 0;
|
||||
|
||||
while (mStart < block.Length)
|
||||
{
|
||||
if (block[mStart++] == 0x01)
|
||||
break;
|
||||
}
|
||||
|
||||
if (mStart >= block.Length)
|
||||
{
|
||||
ClearBlock(block);
|
||||
}
|
||||
|
||||
fullMessage = (mStart > 1);
|
||||
|
||||
recoveredMessage = new byte[dbMask.Length - mStart - saltLength];
|
||||
|
||||
Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length);
|
||||
recoveredMessage.CopyTo(mBuf, 0);
|
||||
|
||||
preSig = signature;
|
||||
preBlock = block;
|
||||
preMStart = mStart;
|
||||
preTLength = tLength;
|
||||
}
|
||||
|
||||
/// <summary> update the internal digest with the byte b</summary>
|
||||
public virtual void Update(
|
||||
byte input)
|
||||
{
|
||||
if (preSig == null && messageLength < mBuf.Length)
|
||||
{
|
||||
mBuf[messageLength++] = input;
|
||||
}
|
||||
else
|
||||
{
|
||||
digest.Update(input);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
BlockUpdate(input.AsSpan(inOff, inLen));
|
||||
#else
|
||||
if (preSig == null)
|
||||
{
|
||||
while (inLen > 0 && messageLength < mBuf.Length)
|
||||
{
|
||||
this.Update(input[inOff]);
|
||||
inOff++;
|
||||
inLen--;
|
||||
}
|
||||
}
|
||||
|
||||
if (inLen > 0)
|
||||
{
|
||||
digest.BlockUpdate(input, inOff, inLen);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
|
||||
{
|
||||
if (preSig == null)
|
||||
{
|
||||
while (!input.IsEmpty && messageLength < mBuf.Length)
|
||||
{
|
||||
this.Update(input[0]);
|
||||
input = input[1..];
|
||||
}
|
||||
}
|
||||
|
||||
if (!input.IsEmpty)
|
||||
{
|
||||
digest.BlockUpdate(input);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary> reset the internal state</summary>
|
||||
public virtual void Reset()
|
||||
{
|
||||
digest.Reset();
|
||||
messageLength = 0;
|
||||
if (mBuf != null)
|
||||
{
|
||||
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();
|
||||
byte[] m2Hash = new byte[digSize];
|
||||
digest.DoFinal(m2Hash, 0);
|
||||
|
||||
byte[] C = new byte[8];
|
||||
LtoOSP(messageLength * 8, C);
|
||||
|
||||
digest.BlockUpdate(C, 0, C.Length);
|
||||
digest.BlockUpdate(mBuf, 0, messageLength);
|
||||
digest.BlockUpdate(m2Hash, 0, m2Hash.Length);
|
||||
|
||||
byte[] salt;
|
||||
if (standardSalt != null)
|
||||
{
|
||||
salt = standardSalt;
|
||||
}
|
||||
else
|
||||
{
|
||||
salt = new byte[saltLength];
|
||||
random.NextBytes(salt);
|
||||
}
|
||||
|
||||
digest.BlockUpdate(salt, 0, salt.Length);
|
||||
|
||||
byte[] hash = new byte[digest.GetDigestSize()];
|
||||
digest.DoFinal(hash, 0);
|
||||
|
||||
int tLength = 2;
|
||||
if (trailer == IsoTrailers.TRAILER_IMPLICIT)
|
||||
{
|
||||
tLength = 1;
|
||||
}
|
||||
|
||||
int off = block.Length - messageLength - salt.Length - hLen - tLength - 1;
|
||||
|
||||
block[off] = (byte) (0x01);
|
||||
|
||||
Array.Copy(mBuf, 0, block, off + 1, messageLength);
|
||||
Array.Copy(salt, 0, block, off + 1 + messageLength, salt.Length);
|
||||
|
||||
byte[] dbMask = MaskGeneratorFunction1(hash, 0, hash.Length, block.Length - hLen - tLength);
|
||||
for (int i = 0; i != dbMask.Length; i++)
|
||||
{
|
||||
block[i] ^= dbMask[i];
|
||||
}
|
||||
|
||||
Array.Copy(hash, 0, block, block.Length - hLen - tLength, hLen);
|
||||
|
||||
if (trailer == IsoTrailers.TRAILER_IMPLICIT)
|
||||
{
|
||||
block[block.Length - 1] = (byte)IsoTrailers.TRAILER_IMPLICIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
block[block.Length - 2] = (byte) ((uint)trailer >> 8);
|
||||
block[block.Length - 1] = (byte) trailer;
|
||||
}
|
||||
|
||||
block[0] &= (byte) (0x7f);
|
||||
|
||||
byte[] b = cipher.ProcessBlock(block, 0, block.Length);
|
||||
|
||||
ClearBlock(mBuf);
|
||||
ClearBlock(block);
|
||||
messageLength = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
//
|
||||
// calculate H(m2)
|
||||
//
|
||||
byte[] m2Hash = new byte[hLen];
|
||||
digest.DoFinal(m2Hash, 0);
|
||||
|
||||
byte[] block;
|
||||
int tLength;
|
||||
int mStart = 0;
|
||||
|
||||
if (preSig == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
UpdateWithRecoveredMessage(signature);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Arrays.AreEqual(preSig, signature))
|
||||
{
|
||||
throw new InvalidOperationException("UpdateWithRecoveredMessage called on different signature");
|
||||
}
|
||||
}
|
||||
|
||||
block = preBlock;
|
||||
mStart = preMStart;
|
||||
tLength = preTLength;
|
||||
|
||||
preSig = null;
|
||||
preBlock = null;
|
||||
|
||||
//
|
||||
// check the hashes
|
||||
//
|
||||
byte[] C = new byte[8];
|
||||
LtoOSP(recoveredMessage.Length * 8, C);
|
||||
|
||||
digest.BlockUpdate(C, 0, C.Length);
|
||||
|
||||
if (recoveredMessage.Length != 0)
|
||||
{
|
||||
digest.BlockUpdate(recoveredMessage, 0, recoveredMessage.Length);
|
||||
}
|
||||
|
||||
digest.BlockUpdate(m2Hash, 0, m2Hash.Length);
|
||||
|
||||
// Update for the salt
|
||||
if (standardSalt != null)
|
||||
{
|
||||
digest.BlockUpdate(standardSalt, 0, standardSalt.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
digest.BlockUpdate(block, mStart + recoveredMessage.Length, saltLength);
|
||||
}
|
||||
|
||||
byte[] hash = new byte[digest.GetDigestSize()];
|
||||
digest.DoFinal(hash, 0);
|
||||
|
||||
int off = block.Length - tLength - hash.Length;
|
||||
|
||||
bool isOkay = true;
|
||||
|
||||
for (int i = 0; i != hash.Length; i++)
|
||||
{
|
||||
if (hash[i] != block[off + i])
|
||||
{
|
||||
isOkay = false;
|
||||
}
|
||||
}
|
||||
|
||||
ClearBlock(block);
|
||||
ClearBlock(hash);
|
||||
|
||||
if (!isOkay)
|
||||
{
|
||||
fullMessage = false;
|
||||
messageLength = 0;
|
||||
ClearBlock(recoveredMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// if they've input a message check what we've recovered against
|
||||
// what was input.
|
||||
//
|
||||
if (messageLength != 0)
|
||||
{
|
||||
if (!IsSameAs(mBuf, recoveredMessage))
|
||||
{
|
||||
messageLength = 0;
|
||||
ClearBlock(mBuf);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
messageLength = 0;
|
||||
|
||||
ClearBlock(mBuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return true if the full message was recoveredMessage.
|
||||
/// </summary>
|
||||
/// <returns>true on full message recovery, false otherwise, or if not sure.</returns>
|
||||
/// <seealso cref="ISignerWithRecovery.HasFullMessage"/>
|
||||
public virtual bool HasFullMessage()
|
||||
{
|
||||
return fullMessage;
|
||||
}
|
||||
|
||||
/// <summary> int to octet string.</summary>
|
||||
/// <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> long to octet string.</summary>
|
||||
private void LtoOSP(long l, byte[] sp)
|
||||
{
|
||||
sp[0] = (byte)((ulong)l >> 56);
|
||||
sp[1] = (byte)((ulong)l >> 48);
|
||||
sp[2] = (byte)((ulong)l >> 40);
|
||||
sp[3] = (byte)((ulong)l >> 32);
|
||||
sp[4] = (byte)((ulong)l >> 24);
|
||||
sp[5] = (byte)((ulong)l >> 16);
|
||||
sp[6] = (byte)((ulong)l >> 8);
|
||||
sp[7] = (byte)((ulong)l >> 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[hLen];
|
||||
byte[] C = new byte[4];
|
||||
int counter = 0;
|
||||
|
||||
digest.Reset();
|
||||
|
||||
do
|
||||
{
|
||||
ItoOSP(counter, C);
|
||||
|
||||
digest.BlockUpdate(Z, zOff, zLen);
|
||||
digest.BlockUpdate(C, 0, C.Length);
|
||||
digest.DoFinal(hashBuf, 0);
|
||||
|
||||
Array.Copy(hashBuf, 0, mask, counter * hLen, hLen);
|
||||
}
|
||||
while (++counter < (length / hLen));
|
||||
|
||||
if ((counter * hLen) < length)
|
||||
{
|
||||
ItoOSP(counter, C);
|
||||
|
||||
digest.BlockUpdate(Z, zOff, zLen);
|
||||
digest.BlockUpdate(C, 0, C.Length);
|
||||
digest.DoFinal(hashBuf, 0);
|
||||
|
||||
Array.Copy(hashBuf, 0, mask, counter * hLen, mask.Length - (counter * hLen));
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31b913e780f036440a7f9c54f0cdf1fc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
554
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Iso9796d2Signer.cs
vendored
Normal file
554
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/Iso9796d2Signer.cs
vendored
Normal file
@@ -0,0 +1,554 @@
|
||||
#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.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public virtual void Update(byte input)
|
||||
{
|
||||
digest.Update(input);
|
||||
|
||||
if (messageLength < mBuf.Length)
|
||||
{
|
||||
mBuf[messageLength] = input;
|
||||
}
|
||||
|
||||
messageLength++;
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
BlockUpdate(input.AsSpan(inOff, inLen));
|
||||
#else
|
||||
while (inLen > 0 && messageLength < mBuf.Length)
|
||||
{
|
||||
this.Update(input[inOff]);
|
||||
inOff++;
|
||||
inLen--;
|
||||
}
|
||||
|
||||
if (inLen > 0)
|
||||
{
|
||||
digest.BlockUpdate(input, inOff, inLen);
|
||||
messageLength += inLen;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
|
||||
{
|
||||
while (!input.IsEmpty && messageLength < mBuf.Length)
|
||||
{
|
||||
this.Update(input[0]);
|
||||
input = input[1..];
|
||||
}
|
||||
|
||||
if (!input.IsEmpty)
|
||||
{
|
||||
digest.BlockUpdate(input);
|
||||
messageLength += input.Length;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <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);
|
||||
|
||||
messageLength = 0;
|
||||
|
||||
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);
|
||||
|
||||
messageLength = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ReturnFalse(byte[] block)
|
||||
{
|
||||
messageLength = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f46652d751b6c574a94a6d0562824920
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
57
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/IsoTrailers.cs
vendored
Normal file
57
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/IsoTrailers.cs
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.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<string, int> CreateTrailerMap()
|
||||
{
|
||||
var trailers = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
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 trailers;
|
||||
}
|
||||
|
||||
// IDictionary is (string -> Int32)
|
||||
private static readonly IDictionary<string, int> TrailerMap = CreateTrailerMap();
|
||||
|
||||
public static int GetTrailer(IDigest digest)
|
||||
{
|
||||
return TrailerMap[digest.AlgorithmName];
|
||||
}
|
||||
|
||||
public static bool NoTrailerAvailable(IDigest digest)
|
||||
{
|
||||
return !TrailerMap.ContainsKey(digest.AlgorithmName);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/IsoTrailers.cs.meta
vendored
Normal file
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/IsoTrailers.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f9896fcb1ac70f46bcc315f89776165
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
62
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/PlainDsaEncoding.cs
vendored
Normal file
62
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/PlainDsaEncoding.cs
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
public class PlainDsaEncoding
|
||||
: IDsaEncoding
|
||||
{
|
||||
public static readonly PlainDsaEncoding Instance = new PlainDsaEncoding();
|
||||
|
||||
public virtual BigInteger[] Decode(BigInteger n, byte[] encoding)
|
||||
{
|
||||
int valueLength = BigIntegers.GetUnsignedByteLength(n);
|
||||
if (encoding.Length != valueLength * 2)
|
||||
throw new ArgumentException("Encoding has incorrect length", "encoding");
|
||||
|
||||
return new BigInteger[] {
|
||||
DecodeValue(n, encoding, 0, valueLength),
|
||||
DecodeValue(n, encoding, valueLength, valueLength),
|
||||
};
|
||||
}
|
||||
|
||||
public virtual byte[] Encode(BigInteger n, BigInteger r, BigInteger s)
|
||||
{
|
||||
int valueLength = BigIntegers.GetUnsignedByteLength(n);
|
||||
byte[] result = new byte[valueLength * 2];
|
||||
EncodeValue(n, r, result, 0, valueLength);
|
||||
EncodeValue(n, s, result, valueLength, valueLength);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected virtual BigInteger CheckValue(BigInteger n, BigInteger x)
|
||||
{
|
||||
if (x.SignValue < 0 || x.CompareTo(n) >= 0)
|
||||
throw new ArgumentException("Value out of range", "x");
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
protected virtual BigInteger DecodeValue(BigInteger n, byte[] buf, int off, int len)
|
||||
{
|
||||
return CheckValue(n, new BigInteger(1, buf, off, len));
|
||||
}
|
||||
|
||||
protected virtual void EncodeValue(BigInteger n, BigInteger x, byte[] buf, int off, int len)
|
||||
{
|
||||
byte[] bs = CheckValue(n, x).ToByteArrayUnsigned();
|
||||
int bsOff = System.Math.Max(0, bs.Length - len);
|
||||
int bsLen = bs.Length - bsOff;
|
||||
|
||||
int pos = len - bsLen;
|
||||
Arrays.Fill(buf, off, off + pos, 0);
|
||||
Array.Copy(bs, bsOff, buf, off + pos, bsLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc62c655d2ab26447a76733af7743e3f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
411
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/PssSigner.cs
vendored
Normal file
411
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/PssSigner.cs
vendored
Normal file
@@ -0,0 +1,411 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.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 = 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 static PssSigner CreateRawSigner(IAsymmetricBlockCipher cipher, IDigest contentDigest, IDigest mgfDigest,
|
||||
byte[] salt, byte trailer)
|
||||
{
|
||||
return new PssSigner(cipher, new NullDigest(), contentDigest, mgfDigest, salt.Length, salt, 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, trailer)
|
||||
{
|
||||
}
|
||||
|
||||
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 withRandom)
|
||||
{
|
||||
parameters = withRandom.Parameters;
|
||||
random = withRandom.Random;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (forSigning)
|
||||
{
|
||||
random = CryptoServicesRegistrar.GetSecureRandom();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public virtual void Update(byte input)
|
||||
{
|
||||
contentDigest1.Update(input);
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
contentDigest1.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)
|
||||
{
|
||||
contentDigest1.BlockUpdate(input);
|
||||
}
|
||||
#endif
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
contentDigest1.Reset();
|
||||
}
|
||||
|
||||
public virtual byte[] GenerateSignature()
|
||||
{
|
||||
if (contentDigest1.GetDigestSize() != hLen)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
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 = MaskGeneratorFunction(h, 0, h.Length, block.Length - hLen - 1);
|
||||
for (int i = 0; i != dbMask.Length; i++)
|
||||
{
|
||||
block[i] ^= dbMask[i];
|
||||
}
|
||||
|
||||
h.CopyTo(block, block.Length - hLen - 1);
|
||||
|
||||
uint firstByteMask = 0xFFU >> ((block.Length * 8) - emBits);
|
||||
|
||||
block[0] &= (byte)firstByteMask;
|
||||
block[block.Length - 1] = trailer;
|
||||
|
||||
byte[] b = cipher.ProcessBlock(block, 0, block.Length);
|
||||
|
||||
ClearBlock(block);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
public virtual bool VerifySignature(byte[] signature)
|
||||
{
|
||||
if (contentDigest1.GetDigestSize() != hLen)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen);
|
||||
|
||||
byte[] b = cipher.ProcessBlock(signature, 0, signature.Length);
|
||||
Arrays.Fill(block, 0, block.Length - b.Length, 0);
|
||||
b.CopyTo(block, block.Length - b.Length);
|
||||
|
||||
uint firstByteMask = 0xFFU >> ((block.Length * 8) - emBits);
|
||||
|
||||
if (block[0] != (byte)(block[0] & firstByteMask)
|
||||
|| block[block.Length - 1] != trailer)
|
||||
{
|
||||
ClearBlock(block);
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] dbMask = MaskGeneratorFunction(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)firstByteMask;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private byte[] MaskGeneratorFunction(
|
||||
byte[] Z,
|
||||
int zOff,
|
||||
int zLen,
|
||||
int length)
|
||||
{
|
||||
if (mgfDigest is IXof)
|
||||
{
|
||||
byte[] mask = new byte[length];
|
||||
mgfDigest.BlockUpdate(Z, zOff, zLen);
|
||||
((IXof)mgfDigest).OutputFinal(mask, 0, mask.Length);
|
||||
|
||||
return mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MaskGeneratorFunction1(Z, zOff, zLen, length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/PssSigner.cs.meta
vendored
Normal file
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/PssSigner.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1a3a3873d9ad8a438605da6d3c12377
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc80a8ca3e7289e4d95d20449fe315b7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
229
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/RsaDigestSigner.cs
vendored
Normal file
229
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/RsaDigestSigner.cs
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.TeleTrust;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Encodings;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
public class RsaDigestSigner
|
||||
: ISigner
|
||||
{
|
||||
private readonly IAsymmetricBlockCipher rsaEngine;
|
||||
private readonly AlgorithmIdentifier algId;
|
||||
private readonly IDigest digest;
|
||||
private bool forSigning;
|
||||
|
||||
private static readonly IDictionary<string, DerObjectIdentifier> OidMap =
|
||||
new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <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["SHA-512/224"] = NistObjectIdentifiers.IdSha512_224;
|
||||
OidMap["SHA-512/256"] = NistObjectIdentifiers.IdSha512_256;
|
||||
OidMap["SHA3-224"] = NistObjectIdentifiers.IdSha3_224;
|
||||
OidMap["SHA3-256"] = NistObjectIdentifiers.IdSha3_256;
|
||||
OidMap["SHA3-384"] = NistObjectIdentifiers.IdSha3_384;
|
||||
OidMap["SHA3-512"] = NistObjectIdentifiers.IdSha3_512;
|
||||
|
||||
OidMap["MD2"] = PkcsObjectIdentifiers.MD2;
|
||||
OidMap["MD4"] = PkcsObjectIdentifiers.MD4;
|
||||
OidMap["MD5"] = PkcsObjectIdentifiers.MD5;
|
||||
}
|
||||
|
||||
public RsaDigestSigner(IDigest digest)
|
||||
: this(digest, CollectionUtilities.GetValueOrNull(OidMap, digest.AlgorithmName))
|
||||
{
|
||||
}
|
||||
|
||||
public RsaDigestSigner(IDigest digest, DerObjectIdentifier digestOid)
|
||||
: this(digest, new AlgorithmIdentifier(digestOid, DerNull.Instance))
|
||||
{
|
||||
}
|
||||
|
||||
public RsaDigestSigner(IDigest digest, AlgorithmIdentifier algId)
|
||||
: this(new RsaCoreEngine(), digest, algId)
|
||||
{
|
||||
}
|
||||
|
||||
public RsaDigestSigner(IRsa rsa, IDigest digest, DerObjectIdentifier digestOid)
|
||||
: this(rsa, digest, new AlgorithmIdentifier(digestOid, DerNull.Instance))
|
||||
{
|
||||
}
|
||||
|
||||
public RsaDigestSigner(IRsa rsa, IDigest digest, AlgorithmIdentifier algId)
|
||||
: this(new RsaBlindedEngine(rsa), digest, algId)
|
||||
{
|
||||
}
|
||||
|
||||
public RsaDigestSigner(IAsymmetricBlockCipher rsaEngine, IDigest digest, AlgorithmIdentifier algId)
|
||||
{
|
||||
this.rsaEngine = new Pkcs1Encoding(rsaEngine);
|
||||
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);
|
||||
}
|
||||
|
||||
public virtual void Update(byte input)
|
||||
{
|
||||
digest.Update(input);
|
||||
}
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bca2abdd4279913468bd3fe2c52b2e1d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
268
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/SM2Signer.cs
vendored
Normal file
268
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/SM2Signer.cs
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
/// <summary>The SM2 Digital Signature algorithm.</summary>
|
||||
public class SM2Signer
|
||||
: ISigner
|
||||
{
|
||||
private readonly IDsaKCalculator kCalculator = new RandomDsaKCalculator();
|
||||
private readonly IDigest digest;
|
||||
private readonly IDsaEncoding encoding;
|
||||
|
||||
private ECDomainParameters ecParams;
|
||||
private ECPoint pubPoint;
|
||||
private ECKeyParameters ecKey;
|
||||
private byte[] z;
|
||||
|
||||
public SM2Signer()
|
||||
: this(StandardDsaEncoding.Instance, new SM3Digest())
|
||||
{
|
||||
}
|
||||
|
||||
public SM2Signer(IDigest digest)
|
||||
: this(StandardDsaEncoding.Instance, digest)
|
||||
{
|
||||
}
|
||||
|
||||
public SM2Signer(IDsaEncoding encoding)
|
||||
: this(encoding, new SM3Digest())
|
||||
{
|
||||
}
|
||||
|
||||
public SM2Signer(IDsaEncoding encoding, IDigest digest)
|
||||
{
|
||||
this.encoding = encoding;
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
public virtual string AlgorithmName
|
||||
{
|
||||
get { return "SM2Sign"; }
|
||||
}
|
||||
|
||||
public virtual void Init(bool forSigning, ICipherParameters parameters)
|
||||
{
|
||||
ICipherParameters baseParam;
|
||||
byte[] userID;
|
||||
|
||||
if (parameters is ParametersWithID)
|
||||
{
|
||||
baseParam = ((ParametersWithID)parameters).Parameters;
|
||||
userID = ((ParametersWithID)parameters).GetID();
|
||||
|
||||
if (userID.Length >= 8192)
|
||||
throw new ArgumentException("SM2 user ID must be less than 2^16 bits long");
|
||||
}
|
||||
else
|
||||
{
|
||||
baseParam = parameters;
|
||||
// the default value, string value is "1234567812345678"
|
||||
userID = Hex.DecodeStrict("31323334353637383132333435363738");
|
||||
}
|
||||
|
||||
if (forSigning)
|
||||
{
|
||||
if (baseParam is ParametersWithRandom rParam)
|
||||
{
|
||||
ecKey = (ECKeyParameters)rParam.Parameters;
|
||||
ecParams = ecKey.Parameters;
|
||||
kCalculator.Init(ecParams.N, rParam.Random);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecKey = (ECKeyParameters)baseParam;
|
||||
ecParams = ecKey.Parameters;
|
||||
kCalculator.Init(ecParams.N, CryptoServicesRegistrar.GetSecureRandom());
|
||||
}
|
||||
pubPoint = CreateBasePointMultiplier().Multiply(ecParams.G, ((ECPrivateKeyParameters)ecKey).D).Normalize();
|
||||
}
|
||||
else
|
||||
{
|
||||
ecKey = (ECKeyParameters)baseParam;
|
||||
ecParams = ecKey.Parameters;
|
||||
pubPoint = ((ECPublicKeyParameters)ecKey).Q;
|
||||
}
|
||||
|
||||
digest.Reset();
|
||||
z = GetZ(userID);
|
||||
|
||||
digest.BlockUpdate(z, 0, z.Length);
|
||||
}
|
||||
|
||||
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 bool VerifySignature(byte[] signature)
|
||||
{
|
||||
try
|
||||
{
|
||||
BigInteger[] rs = encoding.Decode(ecParams.N, signature);
|
||||
|
||||
return VerifySignature(rs[0], rs[1]);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
if (z != null)
|
||||
{
|
||||
digest.Reset();
|
||||
digest.BlockUpdate(z, 0, z.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual byte[] GenerateSignature()
|
||||
{
|
||||
byte[] eHash = DigestUtilities.DoFinal(digest);
|
||||
|
||||
BigInteger n = ecParams.N;
|
||||
BigInteger e = CalculateE(n, eHash);
|
||||
BigInteger d = ((ECPrivateKeyParameters)ecKey).D;
|
||||
|
||||
BigInteger r, s;
|
||||
|
||||
ECMultiplier basePointMultiplier = CreateBasePointMultiplier();
|
||||
|
||||
// 5.2.1 Draft RFC: SM2 Public Key Algorithms
|
||||
do // generate s
|
||||
{
|
||||
BigInteger k;
|
||||
do // generate r
|
||||
{
|
||||
// A3
|
||||
k = kCalculator.NextK();
|
||||
|
||||
// A4
|
||||
ECPoint p = basePointMultiplier.Multiply(ecParams.G, k).Normalize();
|
||||
|
||||
// A5
|
||||
r = e.Add(p.AffineXCoord.ToBigInteger()).Mod(n);
|
||||
}
|
||||
while (r.SignValue == 0 || r.Add(k).Equals(n));
|
||||
|
||||
// A6
|
||||
BigInteger dPlus1ModN = BigIntegers.ModOddInverse(n, d.Add(BigIntegers.One));
|
||||
|
||||
s = k.Subtract(r.Multiply(d)).Mod(n);
|
||||
s = dPlus1ModN.Multiply(s).Mod(n);
|
||||
}
|
||||
while (s.SignValue == 0);
|
||||
|
||||
// A7
|
||||
try
|
||||
{
|
||||
return encoding.Encode(ecParams.N, r, s);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CryptoException("unable to encode signature: " + ex.Message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private bool VerifySignature(BigInteger r, BigInteger s)
|
||||
{
|
||||
BigInteger n = ecParams.N;
|
||||
|
||||
// 5.3.1 Draft RFC: SM2 Public Key Algorithms
|
||||
// B1
|
||||
if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
|
||||
return false;
|
||||
|
||||
// B2
|
||||
if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0)
|
||||
return false;
|
||||
|
||||
// B3
|
||||
byte[] eHash = DigestUtilities.DoFinal(digest);
|
||||
|
||||
// B4
|
||||
BigInteger e = CalculateE(n, eHash);
|
||||
|
||||
// B5
|
||||
BigInteger t = r.Add(s).Mod(n);
|
||||
if (t.SignValue == 0)
|
||||
return false;
|
||||
|
||||
// B6
|
||||
ECPoint q = ((ECPublicKeyParameters)ecKey).Q;
|
||||
ECPoint x1y1 = ECAlgorithms.SumOfTwoMultiplies(ecParams.G, s, q, t).Normalize();
|
||||
if (x1y1.IsInfinity)
|
||||
return false;
|
||||
|
||||
// B7
|
||||
return r.Equals(e.Add(x1y1.AffineXCoord.ToBigInteger()).Mod(n));
|
||||
}
|
||||
|
||||
private byte[] GetZ(byte[] userID)
|
||||
{
|
||||
AddUserID(digest, userID);
|
||||
|
||||
AddFieldElement(digest, ecParams.Curve.A);
|
||||
AddFieldElement(digest, ecParams.Curve.B);
|
||||
AddFieldElement(digest, ecParams.G.AffineXCoord);
|
||||
AddFieldElement(digest, ecParams.G.AffineYCoord);
|
||||
AddFieldElement(digest, pubPoint.AffineXCoord);
|
||||
AddFieldElement(digest, pubPoint.AffineYCoord);
|
||||
|
||||
return DigestUtilities.DoFinal(digest);
|
||||
}
|
||||
|
||||
private void AddUserID(IDigest digest, byte[] userID)
|
||||
{
|
||||
int len = userID.Length * 8;
|
||||
digest.Update((byte)(len >> 8));
|
||||
digest.Update((byte)len);
|
||||
digest.BlockUpdate(userID, 0, userID.Length);
|
||||
}
|
||||
|
||||
private void AddFieldElement(IDigest digest, ECFieldElement v)
|
||||
{
|
||||
byte[] p = v.GetEncoded();
|
||||
digest.BlockUpdate(p, 0, p.Length);
|
||||
}
|
||||
|
||||
protected virtual BigInteger CalculateE(BigInteger n, byte[] message)
|
||||
{
|
||||
// TODO Should hashes larger than the order be truncated as with ECDSA?
|
||||
return new BigInteger(1, message);
|
||||
}
|
||||
|
||||
protected virtual ECMultiplier CreateBasePointMultiplier()
|
||||
{
|
||||
return new FixedPointCombMultiplier();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/SM2Signer.cs.meta
vendored
Normal file
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/SM2Signer.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bfbdd48354892d4e970fde72c4c1f37
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,60 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
|
||||
{
|
||||
public class StandardDsaEncoding
|
||||
: IDsaEncoding
|
||||
{
|
||||
public static readonly StandardDsaEncoding Instance = new StandardDsaEncoding();
|
||||
|
||||
public virtual BigInteger[] Decode(BigInteger n, byte[] encoding)
|
||||
{
|
||||
Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(encoding);
|
||||
if (seq.Count == 2)
|
||||
{
|
||||
BigInteger r = DecodeValue(n, seq, 0);
|
||||
BigInteger s = DecodeValue(n, seq, 1);
|
||||
|
||||
byte[] expectedEncoding = Encode(n, r, s);
|
||||
if (Arrays.AreEqual(expectedEncoding, encoding))
|
||||
return new BigInteger[]{ r, s };
|
||||
}
|
||||
|
||||
throw new ArgumentException("Malformed signature", "encoding");
|
||||
}
|
||||
|
||||
public virtual byte[] Encode(BigInteger n, BigInteger r, BigInteger s)
|
||||
{
|
||||
return new DerSequence(
|
||||
EncodeValue(n, r),
|
||||
EncodeValue(n, s)
|
||||
).GetEncoded(Asn1Encodable.Der);
|
||||
}
|
||||
|
||||
protected virtual BigInteger CheckValue(BigInteger n, BigInteger x)
|
||||
{
|
||||
if (x.SignValue < 0 || (null != n && x.CompareTo(n) >= 0))
|
||||
throw new ArgumentException("Value out of range", "x");
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
protected virtual BigInteger DecodeValue(BigInteger n, Asn1Sequence s, int pos)
|
||||
{
|
||||
return CheckValue(n, ((DerInteger)s[pos]).Value);
|
||||
}
|
||||
|
||||
protected virtual DerInteger EncodeValue(BigInteger n, BigInteger x)
|
||||
{
|
||||
return new DerInteger(CheckValue(n, x));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fbd5ad9390c76364e81c5f06a30b8577
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
203
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/X931Signer.cs
vendored
Normal file
203
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/X931Signer.cs
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
#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
|
||||
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/X931Signer.cs.meta
vendored
Normal file
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/signers/X931Signer.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c5139c4f29214e4dba5ffe2640d10e0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user