487 lines
12 KiB
C#
487 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Security;
|
|
using System.Security.Cryptography;
|
|
using Mono.Security.Cryptography;
|
|
using Mono.Security.X509;
|
|
|
|
namespace Mono.Security.Authenticode
|
|
{
|
|
// Token: 0x020000A0 RID: 160
|
|
internal class AuthenticodeDeformatter : AuthenticodeBase
|
|
{
|
|
// Token: 0x060008BC RID: 2236 RVA: 0x00021424 File Offset: 0x0001F624
|
|
public AuthenticodeDeformatter()
|
|
{
|
|
this.reason = -1;
|
|
this.signerChain = new X509Chain();
|
|
this.timestampChain = new X509Chain();
|
|
}
|
|
|
|
// Token: 0x060008BD RID: 2237 RVA: 0x0002144C File Offset: 0x0001F64C
|
|
public AuthenticodeDeformatter(string fileName)
|
|
: this()
|
|
{
|
|
this.FileName = fileName;
|
|
}
|
|
|
|
// Token: 0x170000EA RID: 234
|
|
// (get) Token: 0x060008BE RID: 2238 RVA: 0x0002145C File Offset: 0x0001F65C
|
|
// (set) Token: 0x060008BF RID: 2239 RVA: 0x00021464 File Offset: 0x0001F664
|
|
public string FileName
|
|
{
|
|
get
|
|
{
|
|
return this.filename;
|
|
}
|
|
set
|
|
{
|
|
this.Reset();
|
|
try
|
|
{
|
|
this.CheckSignature(value);
|
|
}
|
|
catch (SecurityException)
|
|
{
|
|
throw;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
this.reason = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000EB RID: 235
|
|
// (get) Token: 0x060008C0 RID: 2240 RVA: 0x000214D0 File Offset: 0x0001F6D0
|
|
public byte[] Hash
|
|
{
|
|
get
|
|
{
|
|
if (this.signedHash == null)
|
|
{
|
|
return null;
|
|
}
|
|
return (byte[])this.signedHash.Value.Clone();
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000EC RID: 236
|
|
// (get) Token: 0x060008C1 RID: 2241 RVA: 0x00021500 File Offset: 0x0001F700
|
|
public int Reason
|
|
{
|
|
get
|
|
{
|
|
if (this.reason == -1)
|
|
{
|
|
this.IsTrusted();
|
|
}
|
|
return this.reason;
|
|
}
|
|
}
|
|
|
|
// Token: 0x060008C2 RID: 2242 RVA: 0x0002151C File Offset: 0x0001F71C
|
|
public bool IsTrusted()
|
|
{
|
|
if (this.entry == null)
|
|
{
|
|
this.reason = 1;
|
|
return false;
|
|
}
|
|
if (this.signingCertificate == null)
|
|
{
|
|
this.reason = 7;
|
|
return false;
|
|
}
|
|
if (this.signerChain.Root == null || !this.trustedRoot)
|
|
{
|
|
this.reason = 6;
|
|
return false;
|
|
}
|
|
if (this.timestamp != DateTime.MinValue)
|
|
{
|
|
if (this.timestampChain.Root == null || !this.trustedTimestampRoot)
|
|
{
|
|
this.reason = 6;
|
|
return false;
|
|
}
|
|
if (!this.signingCertificate.WasCurrent(this.Timestamp))
|
|
{
|
|
this.reason = 4;
|
|
return false;
|
|
}
|
|
}
|
|
else if (!this.signingCertificate.IsCurrent)
|
|
{
|
|
this.reason = 8;
|
|
return false;
|
|
}
|
|
if (this.reason == -1)
|
|
{
|
|
this.reason = 0;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Token: 0x170000ED RID: 237
|
|
// (get) Token: 0x060008C3 RID: 2243 RVA: 0x00021600 File Offset: 0x0001F800
|
|
public byte[] Signature
|
|
{
|
|
get
|
|
{
|
|
if (this.entry == null)
|
|
{
|
|
return null;
|
|
}
|
|
return (byte[])this.entry.Clone();
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000EE RID: 238
|
|
// (get) Token: 0x060008C4 RID: 2244 RVA: 0x00021620 File Offset: 0x0001F820
|
|
public DateTime Timestamp
|
|
{
|
|
get
|
|
{
|
|
return this.timestamp;
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000EF RID: 239
|
|
// (get) Token: 0x060008C5 RID: 2245 RVA: 0x00021628 File Offset: 0x0001F828
|
|
public X509CertificateCollection Certificates
|
|
{
|
|
get
|
|
{
|
|
return this.coll;
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000F0 RID: 240
|
|
// (get) Token: 0x060008C6 RID: 2246 RVA: 0x00021630 File Offset: 0x0001F830
|
|
public X509Certificate SigningCertificate
|
|
{
|
|
get
|
|
{
|
|
return this.signingCertificate;
|
|
}
|
|
}
|
|
|
|
// Token: 0x060008C7 RID: 2247 RVA: 0x00021638 File Offset: 0x0001F838
|
|
private bool CheckSignature(string fileName)
|
|
{
|
|
this.filename = fileName;
|
|
base.Open(this.filename);
|
|
this.entry = base.GetSecurityEntry();
|
|
if (this.entry == null)
|
|
{
|
|
this.reason = 1;
|
|
base.Close();
|
|
return false;
|
|
}
|
|
PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo(this.entry);
|
|
if (contentInfo.ContentType != "1.2.840.113549.1.7.2")
|
|
{
|
|
base.Close();
|
|
return false;
|
|
}
|
|
PKCS7.SignedData signedData = new PKCS7.SignedData(contentInfo.Content);
|
|
if (signedData.ContentInfo.ContentType != "1.3.6.1.4.1.311.2.1.4")
|
|
{
|
|
base.Close();
|
|
return false;
|
|
}
|
|
this.coll = signedData.Certificates;
|
|
ASN1 content = signedData.ContentInfo.Content;
|
|
this.signedHash = content[0][1][1];
|
|
int length = this.signedHash.Length;
|
|
HashAlgorithm hashAlgorithm;
|
|
if (length != 16)
|
|
{
|
|
if (length != 20)
|
|
{
|
|
this.reason = 5;
|
|
base.Close();
|
|
return false;
|
|
}
|
|
hashAlgorithm = HashAlgorithm.Create("SHA1");
|
|
this.hash = base.GetHash(hashAlgorithm);
|
|
}
|
|
else
|
|
{
|
|
hashAlgorithm = HashAlgorithm.Create("MD5");
|
|
this.hash = base.GetHash(hashAlgorithm);
|
|
}
|
|
base.Close();
|
|
if (!this.signedHash.CompareValue(this.hash))
|
|
{
|
|
this.reason = 2;
|
|
}
|
|
byte[] value = content[0].Value;
|
|
hashAlgorithm.Initialize();
|
|
byte[] array = hashAlgorithm.ComputeHash(value);
|
|
bool flag = this.VerifySignature(signedData, array, hashAlgorithm);
|
|
return flag && this.reason == 0;
|
|
}
|
|
|
|
// Token: 0x060008C8 RID: 2248 RVA: 0x000217D8 File Offset: 0x0001F9D8
|
|
private bool CompareIssuerSerial(string issuer, byte[] serial, X509Certificate x509)
|
|
{
|
|
if (issuer != x509.IssuerName)
|
|
{
|
|
return false;
|
|
}
|
|
if (serial.Length != x509.SerialNumber.Length)
|
|
{
|
|
return false;
|
|
}
|
|
int num = serial.Length;
|
|
for (int i = 0; i < serial.Length; i++)
|
|
{
|
|
if (serial[i] != x509.SerialNumber[--num])
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Token: 0x060008C9 RID: 2249 RVA: 0x0002183C File Offset: 0x0001FA3C
|
|
private bool VerifySignature(PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha)
|
|
{
|
|
string text = null;
|
|
ASN1 asn = null;
|
|
int i = 0;
|
|
while (i < sd.SignerInfo.AuthenticatedAttributes.Count)
|
|
{
|
|
ASN1 asn2 = (ASN1)sd.SignerInfo.AuthenticatedAttributes[i];
|
|
string text2 = ASN1Convert.ToOid(asn2[0]);
|
|
string text3 = text2;
|
|
switch (text3)
|
|
{
|
|
case "1.2.840.113549.1.9.3":
|
|
text = ASN1Convert.ToOid(asn2[1][0]);
|
|
break;
|
|
case "1.2.840.113549.1.9.4":
|
|
asn = asn2[1][0];
|
|
break;
|
|
}
|
|
IL_F1:
|
|
i++;
|
|
continue;
|
|
goto IL_F1;
|
|
}
|
|
if (text != "1.3.6.1.4.1.311.2.1.4")
|
|
{
|
|
return false;
|
|
}
|
|
if (asn == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (!asn.CompareValue(calculatedMessageDigest))
|
|
{
|
|
return false;
|
|
}
|
|
string text4 = CryptoConfig.MapNameToOID(ha.ToString());
|
|
ASN1 asn3 = new ASN1(49);
|
|
foreach (object obj in sd.SignerInfo.AuthenticatedAttributes)
|
|
{
|
|
ASN1 asn4 = (ASN1)obj;
|
|
asn3.Add(asn4);
|
|
}
|
|
ha.Initialize();
|
|
byte[] array = ha.ComputeHash(asn3.GetBytes());
|
|
byte[] signature = sd.SignerInfo.Signature;
|
|
string issuerName = sd.SignerInfo.IssuerName;
|
|
byte[] serialNumber = sd.SignerInfo.SerialNumber;
|
|
foreach (X509Certificate x509Certificate in this.coll)
|
|
{
|
|
if (this.CompareIssuerSerial(issuerName, serialNumber, x509Certificate) && x509Certificate.PublicKey.Length > signature.Length >> 3)
|
|
{
|
|
this.signingCertificate = x509Certificate;
|
|
RSACryptoServiceProvider rsacryptoServiceProvider = (RSACryptoServiceProvider)x509Certificate.RSA;
|
|
if (rsacryptoServiceProvider.VerifyHash(array, text4, signature))
|
|
{
|
|
this.signerChain.LoadCertificates(this.coll);
|
|
this.trustedRoot = this.signerChain.Build(x509Certificate);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (sd.SignerInfo.UnauthenticatedAttributes.Count == 0)
|
|
{
|
|
this.trustedTimestampRoot = true;
|
|
}
|
|
else
|
|
{
|
|
int j = 0;
|
|
while (j < sd.SignerInfo.UnauthenticatedAttributes.Count)
|
|
{
|
|
ASN1 asn5 = (ASN1)sd.SignerInfo.UnauthenticatedAttributes[j];
|
|
string text5 = ASN1Convert.ToOid(asn5[0]);
|
|
string text3 = text5;
|
|
if (text3 != null)
|
|
{
|
|
if (AuthenticodeDeformatter.<>f__switch$map6 == null)
|
|
{
|
|
AuthenticodeDeformatter.<>f__switch$map6 = new Dictionary<string, int>(1) { { "1.2.840.113549.1.9.6", 0 } };
|
|
}
|
|
int num;
|
|
if (AuthenticodeDeformatter.<>f__switch$map6.TryGetValue(text3, out num))
|
|
{
|
|
if (num == 0)
|
|
{
|
|
PKCS7.SignerInfo signerInfo = new PKCS7.SignerInfo(asn5[1]);
|
|
this.trustedTimestampRoot = this.VerifyCounterSignature(signerInfo, signature);
|
|
}
|
|
}
|
|
}
|
|
IL_35D:
|
|
j++;
|
|
continue;
|
|
goto IL_35D;
|
|
}
|
|
}
|
|
return this.trustedRoot && this.trustedTimestampRoot;
|
|
}
|
|
|
|
// Token: 0x060008CA RID: 2250 RVA: 0x00021C0C File Offset: 0x0001FE0C
|
|
private bool VerifyCounterSignature(PKCS7.SignerInfo cs, byte[] signature)
|
|
{
|
|
if (cs.Version != 1)
|
|
{
|
|
return false;
|
|
}
|
|
string text = null;
|
|
ASN1 asn = null;
|
|
int i = 0;
|
|
while (i < cs.AuthenticatedAttributes.Count)
|
|
{
|
|
ASN1 asn2 = (ASN1)cs.AuthenticatedAttributes[i];
|
|
string text2 = ASN1Convert.ToOid(asn2[0]);
|
|
string text3 = text2;
|
|
switch (text3)
|
|
{
|
|
case "1.2.840.113549.1.9.3":
|
|
text = ASN1Convert.ToOid(asn2[1][0]);
|
|
break;
|
|
case "1.2.840.113549.1.9.4":
|
|
asn = asn2[1][0];
|
|
break;
|
|
case "1.2.840.113549.1.9.5":
|
|
this.timestamp = ASN1Convert.ToDateTime(asn2[1][0]);
|
|
break;
|
|
}
|
|
IL_FC:
|
|
i++;
|
|
continue;
|
|
goto IL_FC;
|
|
}
|
|
if (text != "1.2.840.113549.1.7.1")
|
|
{
|
|
return false;
|
|
}
|
|
if (asn == null)
|
|
{
|
|
return false;
|
|
}
|
|
string text4 = null;
|
|
int length = asn.Length;
|
|
if (length != 16)
|
|
{
|
|
if (length == 20)
|
|
{
|
|
text4 = "SHA1";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
text4 = "MD5";
|
|
}
|
|
HashAlgorithm hashAlgorithm = HashAlgorithm.Create(text4);
|
|
if (!asn.CompareValue(hashAlgorithm.ComputeHash(signature)))
|
|
{
|
|
return false;
|
|
}
|
|
byte[] signature2 = cs.Signature;
|
|
ASN1 asn3 = new ASN1(49);
|
|
foreach (object obj in cs.AuthenticatedAttributes)
|
|
{
|
|
ASN1 asn4 = (ASN1)obj;
|
|
asn3.Add(asn4);
|
|
}
|
|
byte[] array = hashAlgorithm.ComputeHash(asn3.GetBytes());
|
|
string issuerName = cs.IssuerName;
|
|
byte[] serialNumber = cs.SerialNumber;
|
|
foreach (X509Certificate x509Certificate in this.coll)
|
|
{
|
|
if (this.CompareIssuerSerial(issuerName, serialNumber, x509Certificate) && x509Certificate.PublicKey.Length > signature2.Length)
|
|
{
|
|
RSACryptoServiceProvider rsacryptoServiceProvider = (RSACryptoServiceProvider)x509Certificate.RSA;
|
|
RSAManaged rsamanaged = new RSAManaged();
|
|
rsamanaged.ImportParameters(rsacryptoServiceProvider.ExportParameters(false));
|
|
if (PKCS1.Verify_v15(rsamanaged, hashAlgorithm, array, signature2, true))
|
|
{
|
|
this.timestampChain.LoadCertificates(this.coll);
|
|
return this.timestampChain.Build(x509Certificate);
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Token: 0x060008CB RID: 2251 RVA: 0x00021F18 File Offset: 0x00020118
|
|
private void Reset()
|
|
{
|
|
this.filename = null;
|
|
this.entry = null;
|
|
this.hash = null;
|
|
this.signedHash = null;
|
|
this.signingCertificate = null;
|
|
this.reason = -1;
|
|
this.trustedRoot = false;
|
|
this.trustedTimestampRoot = false;
|
|
this.signerChain.Reset();
|
|
this.timestampChain.Reset();
|
|
this.timestamp = DateTime.MinValue;
|
|
}
|
|
|
|
// Token: 0x040001CB RID: 459
|
|
private string filename;
|
|
|
|
// Token: 0x040001CC RID: 460
|
|
private byte[] hash;
|
|
|
|
// Token: 0x040001CD RID: 461
|
|
private X509CertificateCollection coll;
|
|
|
|
// Token: 0x040001CE RID: 462
|
|
private ASN1 signedHash;
|
|
|
|
// Token: 0x040001CF RID: 463
|
|
private DateTime timestamp;
|
|
|
|
// Token: 0x040001D0 RID: 464
|
|
private X509Certificate signingCertificate;
|
|
|
|
// Token: 0x040001D1 RID: 465
|
|
private int reason;
|
|
|
|
// Token: 0x040001D2 RID: 466
|
|
private bool trustedRoot;
|
|
|
|
// Token: 0x040001D3 RID: 467
|
|
private bool trustedTimestampRoot;
|
|
|
|
// Token: 0x040001D4 RID: 468
|
|
private byte[] entry;
|
|
|
|
// Token: 0x040001D5 RID: 469
|
|
private X509Chain signerChain;
|
|
|
|
// Token: 0x040001D6 RID: 470
|
|
private X509Chain timestampChain;
|
|
}
|
|
}
|