510 lines
13 KiB
C#
510 lines
13 KiB
C#
using System;
|
|
using System.Security.Cryptography;
|
|
using Mono.Math;
|
|
|
|
namespace Mono.Security.Cryptography
|
|
{
|
|
// Token: 0x020000A4 RID: 164
|
|
internal class DSAManaged : DSA
|
|
{
|
|
// Token: 0x060008F2 RID: 2290 RVA: 0x0002324C File Offset: 0x0002144C
|
|
public DSAManaged()
|
|
: this(1024)
|
|
{
|
|
}
|
|
|
|
// Token: 0x060008F3 RID: 2291 RVA: 0x0002325C File Offset: 0x0002145C
|
|
public DSAManaged(int dwKeySize)
|
|
{
|
|
this.KeySizeValue = dwKeySize;
|
|
this.LegalKeySizesValue = new KeySizes[1];
|
|
this.LegalKeySizesValue[0] = new KeySizes(512, 1024, 64);
|
|
}
|
|
|
|
// Token: 0x14000001 RID: 1
|
|
// (add) Token: 0x060008F4 RID: 2292 RVA: 0x0002329C File Offset: 0x0002149C
|
|
// (remove) Token: 0x060008F5 RID: 2293 RVA: 0x000232B8 File Offset: 0x000214B8
|
|
public event DSAManaged.KeyGeneratedEventHandler KeyGenerated;
|
|
|
|
// Token: 0x060008F6 RID: 2294 RVA: 0x000232D4 File Offset: 0x000214D4
|
|
~DSAManaged()
|
|
{
|
|
this.Dispose(false);
|
|
}
|
|
|
|
// Token: 0x060008F7 RID: 2295 RVA: 0x00023310 File Offset: 0x00021510
|
|
private void Generate()
|
|
{
|
|
this.GenerateParams(base.KeySize);
|
|
this.GenerateKeyPair();
|
|
this.keypairGenerated = true;
|
|
if (this.KeyGenerated != null)
|
|
{
|
|
this.KeyGenerated(this, null);
|
|
}
|
|
}
|
|
|
|
// Token: 0x060008F8 RID: 2296 RVA: 0x00023350 File Offset: 0x00021550
|
|
private void GenerateKeyPair()
|
|
{
|
|
this.x = BigInteger.GenerateRandom(160);
|
|
while (this.x == 0U || this.x >= this.q)
|
|
{
|
|
this.x.Randomize();
|
|
}
|
|
this.y = this.g.ModPow(this.x, this.p);
|
|
}
|
|
|
|
// Token: 0x060008F9 RID: 2297 RVA: 0x000233C4 File Offset: 0x000215C4
|
|
private void add(byte[] a, byte[] b, int value)
|
|
{
|
|
uint num = (uint)((int)(b[b.Length - 1] & byte.MaxValue) + value);
|
|
a[b.Length - 1] = (byte)num;
|
|
num >>= 8;
|
|
for (int i = b.Length - 2; i >= 0; i--)
|
|
{
|
|
num += (uint)(b[i] & byte.MaxValue);
|
|
a[i] = (byte)num;
|
|
num >>= 8;
|
|
}
|
|
}
|
|
|
|
// Token: 0x060008FA RID: 2298 RVA: 0x0002341C File Offset: 0x0002161C
|
|
private void GenerateParams(int keyLength)
|
|
{
|
|
byte[] array = new byte[20];
|
|
byte[] array2 = new byte[20];
|
|
byte[] array3 = new byte[20];
|
|
byte[] array4 = new byte[20];
|
|
SHA1 sha = SHA1.Create();
|
|
int num = (keyLength - 1) / 160;
|
|
byte[] array5 = new byte[keyLength / 8];
|
|
bool flag = false;
|
|
while (!flag)
|
|
{
|
|
do
|
|
{
|
|
this.Random.GetBytes(array);
|
|
array2 = sha.ComputeHash(array);
|
|
Array.Copy(array, 0, array3, 0, array.Length);
|
|
this.add(array3, array, 1);
|
|
array3 = sha.ComputeHash(array3);
|
|
for (int num2 = 0; num2 != array4.Length; num2++)
|
|
{
|
|
array4[num2] = array2[num2] ^ array3[num2];
|
|
}
|
|
byte[] array6 = array4;
|
|
int num3 = 0;
|
|
array6[num3] |= 128;
|
|
byte[] array7 = array4;
|
|
int num4 = 19;
|
|
array7[num4] |= 1;
|
|
this.q = new BigInteger(array4);
|
|
}
|
|
while (!this.q.IsProbablePrime());
|
|
this.counter = 0;
|
|
int num5 = 2;
|
|
while (this.counter < 4096)
|
|
{
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
this.add(array2, array, num5 + i);
|
|
array2 = sha.ComputeHash(array2);
|
|
Array.Copy(array2, 0, array5, array5.Length - (i + 1) * array2.Length, array2.Length);
|
|
}
|
|
this.add(array2, array, num5 + num);
|
|
array2 = sha.ComputeHash(array2);
|
|
Array.Copy(array2, array2.Length - (array5.Length - num * array2.Length), array5, 0, array5.Length - num * array2.Length);
|
|
byte[] array8 = array5;
|
|
int num6 = 0;
|
|
array8[num6] |= 128;
|
|
BigInteger bigInteger = new BigInteger(array5);
|
|
BigInteger bigInteger2 = bigInteger % (this.q * 2);
|
|
this.p = bigInteger - (bigInteger2 - 1);
|
|
if (this.p.TestBit((uint)(keyLength - 1)) && this.p.IsProbablePrime())
|
|
{
|
|
flag = true;
|
|
break;
|
|
}
|
|
this.counter++;
|
|
num5 += num + 1;
|
|
}
|
|
}
|
|
BigInteger bigInteger3 = (this.p - 1) / this.q;
|
|
for (;;)
|
|
{
|
|
BigInteger bigInteger4 = BigInteger.GenerateRandom(keyLength);
|
|
if (!(bigInteger4 <= 1) && !(bigInteger4 >= this.p - 1))
|
|
{
|
|
this.g = bigInteger4.ModPow(bigInteger3, this.p);
|
|
if (!(this.g <= 1))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
this.seed = new BigInteger(array);
|
|
this.j = (this.p - 1) / this.q;
|
|
}
|
|
|
|
// Token: 0x170000F2 RID: 242
|
|
// (get) Token: 0x060008FB RID: 2299 RVA: 0x000236FC File Offset: 0x000218FC
|
|
private RandomNumberGenerator Random
|
|
{
|
|
get
|
|
{
|
|
if (this.rng == null)
|
|
{
|
|
this.rng = RandomNumberGenerator.Create();
|
|
}
|
|
return this.rng;
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000F3 RID: 243
|
|
// (get) Token: 0x060008FC RID: 2300 RVA: 0x0002371C File Offset: 0x0002191C
|
|
public override int KeySize
|
|
{
|
|
get
|
|
{
|
|
if (this.keypairGenerated)
|
|
{
|
|
return this.p.BitCount();
|
|
}
|
|
return base.KeySize;
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000F4 RID: 244
|
|
// (get) Token: 0x060008FD RID: 2301 RVA: 0x0002373C File Offset: 0x0002193C
|
|
public override string KeyExchangeAlgorithm
|
|
{
|
|
get
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000F5 RID: 245
|
|
// (get) Token: 0x060008FE RID: 2302 RVA: 0x00023740 File Offset: 0x00021940
|
|
public bool PublicOnly
|
|
{
|
|
get
|
|
{
|
|
return this.keypairGenerated && this.x == null;
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000F6 RID: 246
|
|
// (get) Token: 0x060008FF RID: 2303 RVA: 0x0002375C File Offset: 0x0002195C
|
|
public override string SignatureAlgorithm
|
|
{
|
|
get
|
|
{
|
|
return "http://www.w3.org/2000/09/xmldsig#dsa-sha1";
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000900 RID: 2304 RVA: 0x00023764 File Offset: 0x00021964
|
|
private byte[] NormalizeArray(byte[] array)
|
|
{
|
|
int num = array.Length % 4;
|
|
if (num > 0)
|
|
{
|
|
byte[] array2 = new byte[array.Length + 4 - num];
|
|
Array.Copy(array, 0, array2, 4 - num, array.Length);
|
|
return array2;
|
|
}
|
|
return array;
|
|
}
|
|
|
|
// Token: 0x06000901 RID: 2305 RVA: 0x0002379C File Offset: 0x0002199C
|
|
public override DSAParameters ExportParameters(bool includePrivateParameters)
|
|
{
|
|
if (this.m_disposed)
|
|
{
|
|
throw new ObjectDisposedException(Locale.GetText("Keypair was disposed"));
|
|
}
|
|
if (!this.keypairGenerated)
|
|
{
|
|
this.Generate();
|
|
}
|
|
if (includePrivateParameters && this.x == null)
|
|
{
|
|
throw new CryptographicException("no private key to export");
|
|
}
|
|
DSAParameters dsaparameters = default(DSAParameters);
|
|
dsaparameters.P = this.NormalizeArray(this.p.GetBytes());
|
|
dsaparameters.Q = this.NormalizeArray(this.q.GetBytes());
|
|
dsaparameters.G = this.NormalizeArray(this.g.GetBytes());
|
|
dsaparameters.Y = this.NormalizeArray(this.y.GetBytes());
|
|
if (!this.j_missing)
|
|
{
|
|
dsaparameters.J = this.NormalizeArray(this.j.GetBytes());
|
|
}
|
|
if (this.seed != 0U)
|
|
{
|
|
dsaparameters.Seed = this.NormalizeArray(this.seed.GetBytes());
|
|
dsaparameters.Counter = this.counter;
|
|
}
|
|
if (includePrivateParameters)
|
|
{
|
|
byte[] bytes = this.x.GetBytes();
|
|
if (bytes.Length == 20)
|
|
{
|
|
dsaparameters.X = this.NormalizeArray(bytes);
|
|
}
|
|
}
|
|
return dsaparameters;
|
|
}
|
|
|
|
// Token: 0x06000902 RID: 2306 RVA: 0x000238E4 File Offset: 0x00021AE4
|
|
public override void ImportParameters(DSAParameters parameters)
|
|
{
|
|
if (this.m_disposed)
|
|
{
|
|
throw new ObjectDisposedException(Locale.GetText("Keypair was disposed"));
|
|
}
|
|
if (parameters.P == null || parameters.Q == null || parameters.G == null)
|
|
{
|
|
throw new CryptographicException(Locale.GetText("Missing mandatory DSA parameters (P, Q or G)."));
|
|
}
|
|
if (parameters.X == null && parameters.Y == null)
|
|
{
|
|
throw new CryptographicException(Locale.GetText("Missing both public (Y) and private (X) keys."));
|
|
}
|
|
this.p = new BigInteger(parameters.P);
|
|
this.q = new BigInteger(parameters.Q);
|
|
this.g = new BigInteger(parameters.G);
|
|
if (parameters.X != null)
|
|
{
|
|
this.x = new BigInteger(parameters.X);
|
|
}
|
|
else
|
|
{
|
|
this.x = null;
|
|
}
|
|
if (parameters.Y != null)
|
|
{
|
|
this.y = new BigInteger(parameters.Y);
|
|
}
|
|
else
|
|
{
|
|
this.y = this.g.ModPow(this.x, this.p);
|
|
}
|
|
if (parameters.J != null)
|
|
{
|
|
this.j = new BigInteger(parameters.J);
|
|
}
|
|
else
|
|
{
|
|
this.j = (this.p - 1) / this.q;
|
|
this.j_missing = true;
|
|
}
|
|
if (parameters.Seed != null)
|
|
{
|
|
this.seed = new BigInteger(parameters.Seed);
|
|
this.counter = parameters.Counter;
|
|
}
|
|
else
|
|
{
|
|
this.seed = 0;
|
|
}
|
|
this.keypairGenerated = true;
|
|
}
|
|
|
|
// Token: 0x06000903 RID: 2307 RVA: 0x00023A98 File Offset: 0x00021C98
|
|
public override byte[] CreateSignature(byte[] rgbHash)
|
|
{
|
|
if (this.m_disposed)
|
|
{
|
|
throw new ObjectDisposedException(Locale.GetText("Keypair was disposed"));
|
|
}
|
|
if (rgbHash == null)
|
|
{
|
|
throw new ArgumentNullException("rgbHash");
|
|
}
|
|
if (rgbHash.Length != 20)
|
|
{
|
|
throw new CryptographicException("invalid hash length");
|
|
}
|
|
if (!this.keypairGenerated)
|
|
{
|
|
this.Generate();
|
|
}
|
|
if (this.x == null)
|
|
{
|
|
throw new CryptographicException("no private key available for signature");
|
|
}
|
|
BigInteger bigInteger = new BigInteger(rgbHash);
|
|
BigInteger bigInteger2 = BigInteger.GenerateRandom(160);
|
|
while (bigInteger2 >= this.q)
|
|
{
|
|
bigInteger2.Randomize();
|
|
}
|
|
BigInteger bigInteger3 = this.g.ModPow(bigInteger2, this.p) % this.q;
|
|
BigInteger bigInteger4 = bigInteger2.ModInverse(this.q) * (bigInteger + this.x * bigInteger3) % this.q;
|
|
byte[] array = new byte[40];
|
|
byte[] bytes = bigInteger3.GetBytes();
|
|
byte[] bytes2 = bigInteger4.GetBytes();
|
|
int num = 20 - bytes.Length;
|
|
Array.Copy(bytes, 0, array, num, bytes.Length);
|
|
num = 40 - bytes2.Length;
|
|
Array.Copy(bytes2, 0, array, num, bytes2.Length);
|
|
return array;
|
|
}
|
|
|
|
// Token: 0x06000904 RID: 2308 RVA: 0x00023BDC File Offset: 0x00021DDC
|
|
public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature)
|
|
{
|
|
if (this.m_disposed)
|
|
{
|
|
throw new ObjectDisposedException(Locale.GetText("Keypair was disposed"));
|
|
}
|
|
if (rgbHash == null)
|
|
{
|
|
throw new ArgumentNullException("rgbHash");
|
|
}
|
|
if (rgbSignature == null)
|
|
{
|
|
throw new ArgumentNullException("rgbSignature");
|
|
}
|
|
if (rgbHash.Length != 20)
|
|
{
|
|
throw new CryptographicException("invalid hash length");
|
|
}
|
|
if (rgbSignature.Length != 40)
|
|
{
|
|
throw new CryptographicException("invalid signature length");
|
|
}
|
|
if (!this.keypairGenerated)
|
|
{
|
|
return false;
|
|
}
|
|
bool flag;
|
|
try
|
|
{
|
|
BigInteger bigInteger = new BigInteger(rgbHash);
|
|
byte[] array = new byte[20];
|
|
Array.Copy(rgbSignature, 0, array, 0, 20);
|
|
BigInteger bigInteger2 = new BigInteger(array);
|
|
Array.Copy(rgbSignature, 20, array, 0, 20);
|
|
BigInteger bigInteger3 = new BigInteger(array);
|
|
if (bigInteger2 < 0 || this.q <= bigInteger2)
|
|
{
|
|
flag = false;
|
|
}
|
|
else if (bigInteger3 < 0 || this.q <= bigInteger3)
|
|
{
|
|
flag = false;
|
|
}
|
|
else
|
|
{
|
|
BigInteger bigInteger4 = bigInteger3.ModInverse(this.q);
|
|
BigInteger bigInteger5 = bigInteger * bigInteger4 % this.q;
|
|
BigInteger bigInteger6 = bigInteger2 * bigInteger4 % this.q;
|
|
bigInteger5 = this.g.ModPow(bigInteger5, this.p);
|
|
bigInteger6 = this.y.ModPow(bigInteger6, this.p);
|
|
BigInteger bigInteger7 = bigInteger5 * bigInteger6 % this.p % this.q;
|
|
flag = bigInteger7 == bigInteger2;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
throw new CryptographicException("couldn't compute signature verification");
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
// Token: 0x06000905 RID: 2309 RVA: 0x00023DAC File Offset: 0x00021FAC
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (!this.m_disposed)
|
|
{
|
|
if (this.x != null)
|
|
{
|
|
this.x.Clear();
|
|
this.x = null;
|
|
}
|
|
if (disposing)
|
|
{
|
|
if (this.p != null)
|
|
{
|
|
this.p.Clear();
|
|
this.p = null;
|
|
}
|
|
if (this.q != null)
|
|
{
|
|
this.q.Clear();
|
|
this.q = null;
|
|
}
|
|
if (this.g != null)
|
|
{
|
|
this.g.Clear();
|
|
this.g = null;
|
|
}
|
|
if (this.j != null)
|
|
{
|
|
this.j.Clear();
|
|
this.j = null;
|
|
}
|
|
if (this.seed != null)
|
|
{
|
|
this.seed.Clear();
|
|
this.seed = null;
|
|
}
|
|
if (this.y != null)
|
|
{
|
|
this.y.Clear();
|
|
this.y = null;
|
|
}
|
|
}
|
|
}
|
|
this.m_disposed = true;
|
|
}
|
|
|
|
// Token: 0x040001DF RID: 479
|
|
private const int defaultKeySize = 1024;
|
|
|
|
// Token: 0x040001E0 RID: 480
|
|
private bool keypairGenerated;
|
|
|
|
// Token: 0x040001E1 RID: 481
|
|
private bool m_disposed;
|
|
|
|
// Token: 0x040001E2 RID: 482
|
|
private BigInteger p;
|
|
|
|
// Token: 0x040001E3 RID: 483
|
|
private BigInteger q;
|
|
|
|
// Token: 0x040001E4 RID: 484
|
|
private BigInteger g;
|
|
|
|
// Token: 0x040001E5 RID: 485
|
|
private BigInteger x;
|
|
|
|
// Token: 0x040001E6 RID: 486
|
|
private BigInteger y;
|
|
|
|
// Token: 0x040001E7 RID: 487
|
|
private BigInteger j;
|
|
|
|
// Token: 0x040001E8 RID: 488
|
|
private BigInteger seed;
|
|
|
|
// Token: 0x040001E9 RID: 489
|
|
private int counter;
|
|
|
|
// Token: 0x040001EA RID: 490
|
|
private bool j_missing;
|
|
|
|
// Token: 0x040001EB RID: 491
|
|
private RandomNumberGenerator rng;
|
|
|
|
// Token: 0x020006C4 RID: 1732
|
|
// (Invoke) Token: 0x06004198 RID: 16792
|
|
public delegate void KeyGeneratedEventHandler(object sender, EventArgs e);
|
|
}
|
|
}
|