547 lines
13 KiB
C#
547 lines
13 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using Mono.Security.X509.Extensions;
|
|
|
|
namespace Mono.Security.X509
|
|
{
|
|
// Token: 0x020000BA RID: 186
|
|
internal class X509Crl
|
|
{
|
|
// Token: 0x06000A09 RID: 2569 RVA: 0x0002CAF8 File Offset: 0x0002ACF8
|
|
public X509Crl(byte[] crl)
|
|
{
|
|
if (crl == null)
|
|
{
|
|
throw new ArgumentNullException("crl");
|
|
}
|
|
this.encoded = (byte[])crl.Clone();
|
|
this.Parse(this.encoded);
|
|
}
|
|
|
|
// Token: 0x06000A0A RID: 2570 RVA: 0x0002CB3C File Offset: 0x0002AD3C
|
|
private void Parse(byte[] crl)
|
|
{
|
|
string text = "Input data cannot be coded as a valid CRL.";
|
|
try
|
|
{
|
|
ASN1 asn = new ASN1(this.encoded);
|
|
if (asn.Tag != 48 || asn.Count != 3)
|
|
{
|
|
throw new CryptographicException(text);
|
|
}
|
|
ASN1 asn2 = asn[0];
|
|
if (asn2.Tag != 48 || asn2.Count < 3)
|
|
{
|
|
throw new CryptographicException(text);
|
|
}
|
|
int num = 0;
|
|
if (asn2[num].Tag == 2)
|
|
{
|
|
this.version = asn2[num++].Value[0] + 1;
|
|
}
|
|
else
|
|
{
|
|
this.version = 1;
|
|
}
|
|
this.signatureOID = ASN1Convert.ToOid(asn2[num++][0]);
|
|
this.issuer = X501.ToString(asn2[num++]);
|
|
this.thisUpdate = ASN1Convert.ToDateTime(asn2[num++]);
|
|
ASN1 asn3 = asn2[num++];
|
|
if (asn3.Tag == 23 || asn3.Tag == 24)
|
|
{
|
|
this.nextUpdate = ASN1Convert.ToDateTime(asn3);
|
|
asn3 = asn2[num++];
|
|
}
|
|
this.entries = new ArrayList();
|
|
if (asn3 != null && asn3.Tag == 48)
|
|
{
|
|
ASN1 asn4 = asn3;
|
|
for (int i = 0; i < asn4.Count; i++)
|
|
{
|
|
this.entries.Add(new X509Crl.X509CrlEntry(asn4[i]));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
num--;
|
|
}
|
|
ASN1 asn5 = asn2[num];
|
|
if (asn5 != null && asn5.Tag == 160 && asn5.Count == 1)
|
|
{
|
|
this.extensions = new X509ExtensionCollection(asn5[0]);
|
|
}
|
|
else
|
|
{
|
|
this.extensions = new X509ExtensionCollection(null);
|
|
}
|
|
string text2 = ASN1Convert.ToOid(asn[1][0]);
|
|
if (this.signatureOID != text2)
|
|
{
|
|
throw new CryptographicException(text + " [Non-matching signature algorithms in CRL]");
|
|
}
|
|
byte[] value = asn[2].Value;
|
|
this.signature = new byte[value.Length - 1];
|
|
Buffer.BlockCopy(value, 1, this.signature, 0, this.signature.Length);
|
|
}
|
|
catch
|
|
{
|
|
throw new CryptographicException(text);
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700012A RID: 298
|
|
// (get) Token: 0x06000A0B RID: 2571 RVA: 0x0002CDBC File Offset: 0x0002AFBC
|
|
public ArrayList Entries
|
|
{
|
|
get
|
|
{
|
|
return ArrayList.ReadOnly(this.entries);
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700012B RID: 299
|
|
public X509Crl.X509CrlEntry this[int index]
|
|
{
|
|
get
|
|
{
|
|
return (X509Crl.X509CrlEntry)this.entries[index];
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700012C RID: 300
|
|
public X509Crl.X509CrlEntry this[byte[] serialNumber]
|
|
{
|
|
get
|
|
{
|
|
return this.GetCrlEntry(serialNumber);
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700012D RID: 301
|
|
// (get) Token: 0x06000A0E RID: 2574 RVA: 0x0002CDEC File Offset: 0x0002AFEC
|
|
public X509ExtensionCollection Extensions
|
|
{
|
|
get
|
|
{
|
|
return this.extensions;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700012E RID: 302
|
|
// (get) Token: 0x06000A0F RID: 2575 RVA: 0x0002CDF4 File Offset: 0x0002AFF4
|
|
public byte[] Hash
|
|
{
|
|
get
|
|
{
|
|
if (this.hash_value == null)
|
|
{
|
|
ASN1 asn = new ASN1(this.encoded);
|
|
byte[] bytes = asn[0].GetBytes();
|
|
HashAlgorithm hashAlgorithm = HashAlgorithm.Create(this.GetHashName());
|
|
this.hash_value = hashAlgorithm.ComputeHash(bytes);
|
|
}
|
|
return this.hash_value;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700012F RID: 303
|
|
// (get) Token: 0x06000A10 RID: 2576 RVA: 0x0002CE44 File Offset: 0x0002B044
|
|
public string IssuerName
|
|
{
|
|
get
|
|
{
|
|
return this.issuer;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000130 RID: 304
|
|
// (get) Token: 0x06000A11 RID: 2577 RVA: 0x0002CE4C File Offset: 0x0002B04C
|
|
public DateTime NextUpdate
|
|
{
|
|
get
|
|
{
|
|
return this.nextUpdate;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000131 RID: 305
|
|
// (get) Token: 0x06000A12 RID: 2578 RVA: 0x0002CE54 File Offset: 0x0002B054
|
|
public DateTime ThisUpdate
|
|
{
|
|
get
|
|
{
|
|
return this.thisUpdate;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000132 RID: 306
|
|
// (get) Token: 0x06000A13 RID: 2579 RVA: 0x0002CE5C File Offset: 0x0002B05C
|
|
public string SignatureAlgorithm
|
|
{
|
|
get
|
|
{
|
|
return this.signatureOID;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000133 RID: 307
|
|
// (get) Token: 0x06000A14 RID: 2580 RVA: 0x0002CE64 File Offset: 0x0002B064
|
|
public byte[] Signature
|
|
{
|
|
get
|
|
{
|
|
if (this.signature == null)
|
|
{
|
|
return null;
|
|
}
|
|
return (byte[])this.signature.Clone();
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000134 RID: 308
|
|
// (get) Token: 0x06000A15 RID: 2581 RVA: 0x0002CE84 File Offset: 0x0002B084
|
|
public byte[] RawData
|
|
{
|
|
get
|
|
{
|
|
return (byte[])this.encoded.Clone();
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000135 RID: 309
|
|
// (get) Token: 0x06000A16 RID: 2582 RVA: 0x0002CE98 File Offset: 0x0002B098
|
|
public byte Version
|
|
{
|
|
get
|
|
{
|
|
return this.version;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000136 RID: 310
|
|
// (get) Token: 0x06000A17 RID: 2583 RVA: 0x0002CEA0 File Offset: 0x0002B0A0
|
|
public bool IsCurrent
|
|
{
|
|
get
|
|
{
|
|
return this.WasCurrent(DateTime.Now);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000A18 RID: 2584 RVA: 0x0002CEB0 File Offset: 0x0002B0B0
|
|
public bool WasCurrent(DateTime instant)
|
|
{
|
|
if (this.nextUpdate == DateTime.MinValue)
|
|
{
|
|
return instant >= this.thisUpdate;
|
|
}
|
|
return instant >= this.thisUpdate && instant <= this.nextUpdate;
|
|
}
|
|
|
|
// Token: 0x06000A19 RID: 2585 RVA: 0x0002CF00 File Offset: 0x0002B100
|
|
public byte[] GetBytes()
|
|
{
|
|
return (byte[])this.encoded.Clone();
|
|
}
|
|
|
|
// Token: 0x06000A1A RID: 2586 RVA: 0x0002CF14 File Offset: 0x0002B114
|
|
private bool Compare(byte[] array1, byte[] array2)
|
|
{
|
|
if (array1 == null && array2 == null)
|
|
{
|
|
return true;
|
|
}
|
|
if (array1 == null || array2 == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (array1.Length != array2.Length)
|
|
{
|
|
return false;
|
|
}
|
|
for (int i = 0; i < array1.Length; i++)
|
|
{
|
|
if (array1[i] != array2[i])
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Token: 0x06000A1B RID: 2587 RVA: 0x0002CF6C File Offset: 0x0002B16C
|
|
public X509Crl.X509CrlEntry GetCrlEntry(X509Certificate x509)
|
|
{
|
|
if (x509 == null)
|
|
{
|
|
throw new ArgumentNullException("x509");
|
|
}
|
|
return this.GetCrlEntry(x509.SerialNumber);
|
|
}
|
|
|
|
// Token: 0x06000A1C RID: 2588 RVA: 0x0002CF8C File Offset: 0x0002B18C
|
|
public X509Crl.X509CrlEntry GetCrlEntry(byte[] serialNumber)
|
|
{
|
|
if (serialNumber == null)
|
|
{
|
|
throw new ArgumentNullException("serialNumber");
|
|
}
|
|
for (int i = 0; i < this.entries.Count; i++)
|
|
{
|
|
X509Crl.X509CrlEntry x509CrlEntry = (X509Crl.X509CrlEntry)this.entries[i];
|
|
if (this.Compare(serialNumber, x509CrlEntry.SerialNumber))
|
|
{
|
|
return x509CrlEntry;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Token: 0x06000A1D RID: 2589 RVA: 0x0002CFF0 File Offset: 0x0002B1F0
|
|
public bool VerifySignature(X509Certificate x509)
|
|
{
|
|
if (x509 == null)
|
|
{
|
|
throw new ArgumentNullException("x509");
|
|
}
|
|
if (x509.Version >= 3)
|
|
{
|
|
X509Extension x509Extension = x509.Extensions["2.5.29.15"];
|
|
if (x509Extension != null)
|
|
{
|
|
KeyUsageExtension keyUsageExtension = new KeyUsageExtension(x509Extension);
|
|
if (!keyUsageExtension.Support(KeyUsages.cRLSign))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
x509Extension = x509.Extensions["2.5.29.19"];
|
|
if (x509Extension != null)
|
|
{
|
|
BasicConstraintsExtension basicConstraintsExtension = new BasicConstraintsExtension(x509Extension);
|
|
if (!basicConstraintsExtension.CertificateAuthority)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
if (this.issuer != x509.SubjectName)
|
|
{
|
|
return false;
|
|
}
|
|
string text = this.signatureOID;
|
|
if (text != null)
|
|
{
|
|
if (X509Crl.<>f__switch$map11 == null)
|
|
{
|
|
X509Crl.<>f__switch$map11 = new Dictionary<string, int>(1) { { "1.2.840.10040.4.3", 0 } };
|
|
}
|
|
int num;
|
|
if (X509Crl.<>f__switch$map11.TryGetValue(text, out num))
|
|
{
|
|
if (num == 0)
|
|
{
|
|
return this.VerifySignature(x509.DSA);
|
|
}
|
|
}
|
|
}
|
|
return this.VerifySignature(x509.RSA);
|
|
}
|
|
|
|
// Token: 0x06000A1E RID: 2590 RVA: 0x0002D0F4 File Offset: 0x0002B2F4
|
|
private string GetHashName()
|
|
{
|
|
string text = this.signatureOID;
|
|
switch (text)
|
|
{
|
|
case "1.2.840.113549.1.1.2":
|
|
return "MD2";
|
|
case "1.2.840.113549.1.1.4":
|
|
return "MD5";
|
|
case "1.2.840.10040.4.3":
|
|
case "1.2.840.113549.1.1.5":
|
|
return "SHA1";
|
|
}
|
|
throw new CryptographicException("Unsupported hash algorithm: " + this.signatureOID);
|
|
}
|
|
|
|
// Token: 0x06000A1F RID: 2591 RVA: 0x0002D1A8 File Offset: 0x0002B3A8
|
|
internal bool VerifySignature(DSA dsa)
|
|
{
|
|
if (this.signatureOID != "1.2.840.10040.4.3")
|
|
{
|
|
throw new CryptographicException("Unsupported hash algorithm: " + this.signatureOID);
|
|
}
|
|
DSASignatureDeformatter dsasignatureDeformatter = new DSASignatureDeformatter(dsa);
|
|
dsasignatureDeformatter.SetHashAlgorithm("SHA1");
|
|
ASN1 asn = new ASN1(this.signature);
|
|
if (asn == null || asn.Count != 2)
|
|
{
|
|
return false;
|
|
}
|
|
byte[] value = asn[0].Value;
|
|
byte[] value2 = asn[1].Value;
|
|
byte[] array = new byte[40];
|
|
int num = Math.Max(0, value.Length - 20);
|
|
int num2 = Math.Max(0, 20 - value.Length);
|
|
Buffer.BlockCopy(value, num, array, num2, value.Length - num);
|
|
int num3 = Math.Max(0, value2.Length - 20);
|
|
int num4 = Math.Max(20, 40 - value2.Length);
|
|
Buffer.BlockCopy(value2, num3, array, num4, value2.Length - num3);
|
|
return dsasignatureDeformatter.VerifySignature(this.Hash, array);
|
|
}
|
|
|
|
// Token: 0x06000A20 RID: 2592 RVA: 0x0002D2A0 File Offset: 0x0002B4A0
|
|
internal bool VerifySignature(RSA rsa)
|
|
{
|
|
RSAPKCS1SignatureDeformatter rsapkcs1SignatureDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
|
|
rsapkcs1SignatureDeformatter.SetHashAlgorithm(this.GetHashName());
|
|
return rsapkcs1SignatureDeformatter.VerifySignature(this.Hash, this.signature);
|
|
}
|
|
|
|
// Token: 0x06000A21 RID: 2593 RVA: 0x0002D2D4 File Offset: 0x0002B4D4
|
|
public bool VerifySignature(AsymmetricAlgorithm aa)
|
|
{
|
|
if (aa == null)
|
|
{
|
|
throw new ArgumentNullException("aa");
|
|
}
|
|
if (aa is RSA)
|
|
{
|
|
return this.VerifySignature(aa as RSA);
|
|
}
|
|
if (aa is DSA)
|
|
{
|
|
return this.VerifySignature(aa as DSA);
|
|
}
|
|
throw new NotSupportedException("Unknown Asymmetric Algorithm " + aa.ToString());
|
|
}
|
|
|
|
// Token: 0x06000A22 RID: 2594 RVA: 0x0002D338 File Offset: 0x0002B538
|
|
public static X509Crl CreateFromFile(string filename)
|
|
{
|
|
byte[] array = null;
|
|
using (FileStream fileStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
|
|
{
|
|
array = new byte[fileStream.Length];
|
|
fileStream.Read(array, 0, array.Length);
|
|
fileStream.Close();
|
|
}
|
|
return new X509Crl(array);
|
|
}
|
|
|
|
// Token: 0x04000283 RID: 643
|
|
private string issuer;
|
|
|
|
// Token: 0x04000284 RID: 644
|
|
private byte version;
|
|
|
|
// Token: 0x04000285 RID: 645
|
|
private DateTime thisUpdate;
|
|
|
|
// Token: 0x04000286 RID: 646
|
|
private DateTime nextUpdate;
|
|
|
|
// Token: 0x04000287 RID: 647
|
|
private ArrayList entries;
|
|
|
|
// Token: 0x04000288 RID: 648
|
|
private string signatureOID;
|
|
|
|
// Token: 0x04000289 RID: 649
|
|
private byte[] signature;
|
|
|
|
// Token: 0x0400028A RID: 650
|
|
private X509ExtensionCollection extensions;
|
|
|
|
// Token: 0x0400028B RID: 651
|
|
private byte[] encoded;
|
|
|
|
// Token: 0x0400028C RID: 652
|
|
private byte[] hash_value;
|
|
|
|
// Token: 0x020000BB RID: 187
|
|
public class X509CrlEntry
|
|
{
|
|
// Token: 0x06000A23 RID: 2595 RVA: 0x0002D3A4 File Offset: 0x0002B5A4
|
|
internal X509CrlEntry(byte[] serialNumber, DateTime revocationDate, X509ExtensionCollection extensions)
|
|
{
|
|
this.sn = serialNumber;
|
|
this.revocationDate = revocationDate;
|
|
if (extensions == null)
|
|
{
|
|
this.extensions = new X509ExtensionCollection();
|
|
}
|
|
else
|
|
{
|
|
this.extensions = extensions;
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000A24 RID: 2596 RVA: 0x0002D3D8 File Offset: 0x0002B5D8
|
|
internal X509CrlEntry(ASN1 entry)
|
|
{
|
|
this.sn = entry[0].Value;
|
|
Array.Reverse(this.sn);
|
|
this.revocationDate = ASN1Convert.ToDateTime(entry[1]);
|
|
this.extensions = new X509ExtensionCollection(entry[2]);
|
|
}
|
|
|
|
// Token: 0x17000137 RID: 311
|
|
// (get) Token: 0x06000A25 RID: 2597 RVA: 0x0002D42C File Offset: 0x0002B62C
|
|
public byte[] SerialNumber
|
|
{
|
|
get
|
|
{
|
|
return (byte[])this.sn.Clone();
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000138 RID: 312
|
|
// (get) Token: 0x06000A26 RID: 2598 RVA: 0x0002D440 File Offset: 0x0002B640
|
|
public DateTime RevocationDate
|
|
{
|
|
get
|
|
{
|
|
return this.revocationDate;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000139 RID: 313
|
|
// (get) Token: 0x06000A27 RID: 2599 RVA: 0x0002D448 File Offset: 0x0002B648
|
|
public X509ExtensionCollection Extensions
|
|
{
|
|
get
|
|
{
|
|
return this.extensions;
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000A28 RID: 2600 RVA: 0x0002D450 File Offset: 0x0002B650
|
|
public byte[] GetBytes()
|
|
{
|
|
ASN1 asn = new ASN1(48);
|
|
asn.Add(new ASN1(2, this.sn));
|
|
asn.Add(ASN1Convert.FromDateTime(this.revocationDate));
|
|
if (this.extensions.Count > 0)
|
|
{
|
|
asn.Add(new ASN1(this.extensions.GetBytes()));
|
|
}
|
|
return asn.GetBytes();
|
|
}
|
|
|
|
// Token: 0x0400028F RID: 655
|
|
private byte[] sn;
|
|
|
|
// Token: 0x04000290 RID: 656
|
|
private DateTime revocationDate;
|
|
|
|
// Token: 0x04000291 RID: 657
|
|
private X509ExtensionCollection extensions;
|
|
}
|
|
}
|
|
}
|