using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net; using System.Security.Cryptography; using System.Text; using Mono.Security.X509; namespace Mono.Security.Authenticode { // Token: 0x02000020 RID: 32 public class AuthenticodeFormatter : AuthenticodeBase { // Token: 0x06000148 RID: 328 RVA: 0x00008E1C File Offset: 0x0000701C public AuthenticodeFormatter() { this.certs = new X509CertificateCollection(); this.crls = new ArrayList(); this.authority = Authority.Maximum; this.pkcs7 = new PKCS7.SignedData(); } // Token: 0x17000048 RID: 72 // (get) Token: 0x0600014A RID: 330 RVA: 0x00008E74 File Offset: 0x00007074 // (set) Token: 0x0600014B RID: 331 RVA: 0x00008E7C File Offset: 0x0000707C public Authority Authority { get { return this.authority; } set { this.authority = value; } } // Token: 0x17000049 RID: 73 // (get) Token: 0x0600014C RID: 332 RVA: 0x00008E88 File Offset: 0x00007088 public X509CertificateCollection Certificates { get { return this.certs; } } // Token: 0x1700004A RID: 74 // (get) Token: 0x0600014D RID: 333 RVA: 0x00008E90 File Offset: 0x00007090 public ArrayList Crl { get { return this.crls; } } // Token: 0x1700004B RID: 75 // (get) Token: 0x0600014E RID: 334 RVA: 0x00008E98 File Offset: 0x00007098 // (set) Token: 0x0600014F RID: 335 RVA: 0x00008EB8 File Offset: 0x000070B8 public string Hash { get { if (this.hash == null) { this.hash = "MD5"; } return this.hash; } set { if (value == null) { throw new ArgumentNullException("Hash"); } string text = value.ToUpper(CultureInfo.InvariantCulture); string text2 = text; if (text2 != null) { if (AuthenticodeFormatter.<>f__switch$map4 == null) { AuthenticodeFormatter.<>f__switch$map4 = new Dictionary(2) { { "MD5", 0 }, { "SHA1", 0 } }; } int num; if (AuthenticodeFormatter.<>f__switch$map4.TryGetValue(text2, out num)) { if (num == 0) { this.hash = text; return; } } } throw new ArgumentException("Invalid Authenticode hash algorithm"); } } // Token: 0x1700004C RID: 76 // (get) Token: 0x06000150 RID: 336 RVA: 0x00008F50 File Offset: 0x00007150 // (set) Token: 0x06000151 RID: 337 RVA: 0x00008F58 File Offset: 0x00007158 public RSA RSA { get { return this.rsa; } set { this.rsa = value; } } // Token: 0x1700004D RID: 77 // (get) Token: 0x06000152 RID: 338 RVA: 0x00008F64 File Offset: 0x00007164 // (set) Token: 0x06000153 RID: 339 RVA: 0x00008F6C File Offset: 0x0000716C public Uri TimestampUrl { get { return this.timestamp; } set { this.timestamp = value; } } // Token: 0x1700004E RID: 78 // (get) Token: 0x06000154 RID: 340 RVA: 0x00008F78 File Offset: 0x00007178 // (set) Token: 0x06000155 RID: 341 RVA: 0x00008F80 File Offset: 0x00007180 public string Description { get { return this.description; } set { this.description = value; } } // Token: 0x1700004F RID: 79 // (get) Token: 0x06000156 RID: 342 RVA: 0x00008F8C File Offset: 0x0000718C // (set) Token: 0x06000157 RID: 343 RVA: 0x00008F94 File Offset: 0x00007194 public Uri Url { get { return this.url; } set { this.url = value; } } // Token: 0x06000158 RID: 344 RVA: 0x00008FA0 File Offset: 0x000071A0 private ASN1 AlgorithmIdentifier(string oid) { ASN1 asn = new ASN1(48); asn.Add(ASN1Convert.FromOid(oid)); asn.Add(new ASN1(5)); return asn; } // Token: 0x06000159 RID: 345 RVA: 0x00008FD0 File Offset: 0x000071D0 private ASN1 Attribute(string oid, ASN1 value) { ASN1 asn = new ASN1(48); asn.Add(ASN1Convert.FromOid(oid)); ASN1 asn2 = asn.Add(new ASN1(49)); asn2.Add(value); return asn; } // Token: 0x0600015A RID: 346 RVA: 0x0000900C File Offset: 0x0000720C private ASN1 Opus(string description, string url) { ASN1 asn = new ASN1(48); if (description != null) { ASN1 asn2 = asn.Add(new ASN1(160)); asn2.Add(new ASN1(128, Encoding.BigEndianUnicode.GetBytes(description))); } if (url != null) { ASN1 asn3 = asn.Add(new ASN1(161)); asn3.Add(new ASN1(128, Encoding.ASCII.GetBytes(url))); } return asn; } // Token: 0x0600015B RID: 347 RVA: 0x00009088 File Offset: 0x00007288 private byte[] Header(byte[] fileHash, string hashAlgorithm) { string text = CryptoConfig.MapNameToOID(hashAlgorithm); ASN1 asn = new ASN1(48); ASN1 asn2 = asn.Add(new ASN1(48)); asn2.Add(ASN1Convert.FromOid("1.3.6.1.4.1.311.2.1.15")); asn2.Add(new ASN1(48, AuthenticodeFormatter.obsolete)); ASN1 asn3 = asn.Add(new ASN1(48)); asn3.Add(this.AlgorithmIdentifier(text)); asn3.Add(new ASN1(4, fileHash)); this.pkcs7.HashName = hashAlgorithm; this.pkcs7.Certificates.AddRange(this.certs); this.pkcs7.ContentInfo.ContentType = "1.3.6.1.4.1.311.2.1.4"; this.pkcs7.ContentInfo.Content.Add(asn); this.pkcs7.SignerInfo.Certificate = this.certs[0]; this.pkcs7.SignerInfo.Key = this.rsa; ASN1 asn4; if (this.url == null) { asn4 = this.Attribute("1.3.6.1.4.1.311.2.1.12", this.Opus(this.description, null)); } else { asn4 = this.Attribute("1.3.6.1.4.1.311.2.1.12", this.Opus(this.description, this.url.ToString())); } this.pkcs7.SignerInfo.AuthenticatedAttributes.Add(asn4); this.pkcs7.GetASN1(); return this.pkcs7.SignerInfo.Signature; } // Token: 0x0600015C RID: 348 RVA: 0x0000920C File Offset: 0x0000740C public ASN1 TimestampRequest(byte[] signature) { PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo("1.2.840.113549.1.7.1"); contentInfo.Content.Add(new ASN1(4, signature)); return PKCS7.AlgorithmIdentifier("1.3.6.1.4.1.311.3.2.1", contentInfo.ASN1); } // Token: 0x0600015D RID: 349 RVA: 0x00009248 File Offset: 0x00007448 public void ProcessTimestamp(byte[] response) { ASN1 asn = new ASN1(Convert.FromBase64String(Encoding.ASCII.GetString(response))); for (int i = 0; i < asn[1][0][3].Count; i++) { this.pkcs7.Certificates.Add(new X509Certificate(asn[1][0][3][i].GetBytes())); } this.pkcs7.SignerInfo.UnauthenticatedAttributes.Add(this.Attribute("1.2.840.113549.1.9.6", asn[1][0][4][0])); } // Token: 0x0600015E RID: 350 RVA: 0x00009304 File Offset: 0x00007504 private byte[] Timestamp(byte[] signature) { ASN1 asn = this.TimestampRequest(signature); WebClient webClient = new WebClient(); webClient.Headers.Add("Content-Type", "application/octet-stream"); webClient.Headers.Add("Accept", "application/octet-stream"); byte[] bytes = Encoding.ASCII.GetBytes(Convert.ToBase64String(asn.GetBytes())); return webClient.UploadData(this.timestamp.ToString(), bytes); } // Token: 0x0600015F RID: 351 RVA: 0x00009374 File Offset: 0x00007574 private bool Save(string fileName, byte[] asn) { File.Copy(fileName, fileName + ".bak", true); using (FileStream fileStream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite)) { int num; if (base.SecurityOffset > 0) { num = base.SecurityOffset; } else if (base.CoffSymbolTableOffset > 0) { fileStream.Seek((long)(base.PEOffset + 12), SeekOrigin.Begin); for (int i = 0; i < 8; i++) { fileStream.WriteByte(0); } num = base.CoffSymbolTableOffset; } else { num = (int)fileStream.Length; } int num2 = num & 7; if (num2 > 0) { num2 = 8 - num2; } byte[] array = BitConverterLE.GetBytes(num + num2); fileStream.Seek((long)(base.PEOffset + 152), SeekOrigin.Begin); fileStream.Write(array, 0, 4); int num3 = asn.Length + 8; int num4 = num3 & 7; if (num4 > 0) { num4 = 8 - num4; } array = BitConverterLE.GetBytes(num3 + num4); fileStream.Seek((long)(base.PEOffset + 156), SeekOrigin.Begin); fileStream.Write(array, 0, 4); fileStream.Seek((long)num, SeekOrigin.Begin); if (num2 > 0) { byte[] array2 = new byte[num2]; fileStream.Write(array2, 0, array2.Length); } fileStream.Write(array, 0, array.Length); array = BitConverterLE.GetBytes(131584); fileStream.Write(array, 0, array.Length); fileStream.Write(asn, 0, asn.Length); if (num4 > 0) { byte[] array3 = new byte[num4]; fileStream.Write(array3, 0, array3.Length); } fileStream.Close(); } return true; } // Token: 0x06000160 RID: 352 RVA: 0x00009528 File Offset: 0x00007728 public bool Sign(string fileName) { try { base.Open(fileName); HashAlgorithm hashAlgorithm = HashAlgorithm.Create(this.Hash); byte[] array = base.GetHash(hashAlgorithm); byte[] array2 = this.Header(array, this.Hash); if (this.timestamp != null) { byte[] array3 = this.Timestamp(array2); this.ProcessTimestamp(array3); } PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo("1.2.840.113549.1.7.2"); contentInfo.Content.Add(this.pkcs7.ASN1); this.authenticode = contentInfo.ASN1; base.Close(); return this.Save(fileName, this.authenticode.GetBytes()); } catch (Exception ex) { Console.WriteLine(ex); } return false; } // Token: 0x06000161 RID: 353 RVA: 0x00009604 File Offset: 0x00007804 public bool Timestamp(string fileName) { try { AuthenticodeDeformatter authenticodeDeformatter = new AuthenticodeDeformatter(fileName); byte[] signature = authenticodeDeformatter.Signature; if (signature != null) { base.Open(fileName); PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo(signature); this.pkcs7 = new PKCS7.SignedData(contentInfo.Content); byte[] array = this.Timestamp(this.pkcs7.SignerInfo.Signature); ASN1 asn = new ASN1(Convert.FromBase64String(Encoding.ASCII.GetString(array))); ASN1 asn2 = new ASN1(signature); ASN1 asn3 = asn2.Element(1, 160); if (asn3 == null) { return false; } ASN1 asn4 = asn3.Element(0, 48); if (asn4 == null) { return false; } ASN1 asn5 = asn4.Element(3, 160); if (asn5 == null) { asn5 = new ASN1(160); asn4.Add(asn5); } for (int i = 0; i < asn[1][0][3].Count; i++) { asn5.Add(asn[1][0][3][i]); } ASN1 asn6 = asn4[asn4.Count - 1]; ASN1 asn7 = asn6[0]; ASN1 asn8 = asn7[asn7.Count - 1]; if (asn8.Tag != 161) { asn8 = new ASN1(161); asn7.Add(asn8); } asn8.Add(this.Attribute("1.2.840.113549.1.9.6", asn[1][0][4][0])); return this.Save(fileName, asn2.GetBytes()); } } catch (Exception ex) { Console.WriteLine(ex); } return false; } // Token: 0x0400008E RID: 142 private const string signedData = "1.2.840.113549.1.7.2"; // Token: 0x0400008F RID: 143 private const string countersignature = "1.2.840.113549.1.9.6"; // Token: 0x04000090 RID: 144 private const string spcStatementType = "1.3.6.1.4.1.311.2.1.11"; // Token: 0x04000091 RID: 145 private const string spcSpOpusInfo = "1.3.6.1.4.1.311.2.1.12"; // Token: 0x04000092 RID: 146 private const string spcPelmageData = "1.3.6.1.4.1.311.2.1.15"; // Token: 0x04000093 RID: 147 private const string commercialCodeSigning = "1.3.6.1.4.1.311.2.1.22"; // Token: 0x04000094 RID: 148 private const string timestampCountersignature = "1.3.6.1.4.1.311.3.2.1"; // Token: 0x04000095 RID: 149 private Authority authority; // Token: 0x04000096 RID: 150 private X509CertificateCollection certs; // Token: 0x04000097 RID: 151 private ArrayList crls; // Token: 0x04000098 RID: 152 private string hash; // Token: 0x04000099 RID: 153 private RSA rsa; // Token: 0x0400009A RID: 154 private Uri timestamp; // Token: 0x0400009B RID: 155 private ASN1 authenticode; // Token: 0x0400009C RID: 156 private PKCS7.SignedData pkcs7; // Token: 0x0400009D RID: 157 private string description; // Token: 0x0400009E RID: 158 private Uri url; // Token: 0x0400009F RID: 159 private static byte[] obsolete = new byte[] { 3, 1, 0, 160, 32, 162, 30, 128, 28, 0, 60, 0, 60, 0, 60, 0, 79, 0, 98, 0, 115, 0, 111, 0, 108, 0, 101, 0, 116, 0, 101, 0, 62, 0, 62, 0, 62 }; } }