2 // AuthenticodeBase.cs: Authenticode signature base class
5 // Sebastien Pouliot (spouliot@motus.com)
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
12 using System.Security.Cryptography;
14 namespace Mono.Security.Authenticode {
17 // a. http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
24 enum AuthenticodeAuthority {
35 class AuthenticodeBase {
37 public const string spcIndirectDataContext = "1.3.6.1.4.1.311.2.1.4";
39 protected byte[] rawData;
41 public AuthenticodeBase ()
45 protected byte[] HashFile (string fileName, string hashName)
47 FileStream fs = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
48 byte[] file = new byte [fs.Length];
49 fs.Read (file, 0, file.Length);
53 if (BitConverterLE.ToUInt16 (file, 0) != 0x5A4D)
56 // find offset of PE header
57 int peOffset = BitConverterLE.ToInt32 (file, 60);
58 if (peOffset > file.Length)
62 if (BitConverterLE.ToUInt16 (file, peOffset) != 0x4550)
65 // IMAGE_DIRECTORY_ENTRY_SECURITY
66 int dirSecurityOffset = BitConverterLE.ToInt32 (file, peOffset + 152);
67 int dirSecuritySize = BitConverterLE.ToInt32 (file, peOffset + 156);
69 if (dirSecuritySize > 8) {
70 rawData = new byte [dirSecuritySize - 8];
71 Array.Copy (file, dirSecurityOffset + 8, rawData, 0, rawData.Length);
73 FileStream debug = new FileStream (fileName + ".sig", FileMode.Create, FileAccess.Write);
74 debug.Write (rawData, 0, rawData.Length);
80 HashAlgorithm hash = HashAlgorithm.Create (hashName);
81 // 0 to 215 (216) then skip 4 (checksum)
82 int pe = peOffset + 88;
83 hash.TransformBlock (file, 0, pe, file, 0);
85 // 220 to 279 (60) then skip 8 (IMAGE_DIRECTORY_ENTRY_SECURITY)
86 hash.TransformBlock (file, pe, 60, file, pe);
89 int n = file.Length - pe;
90 // minus any authenticode signature (with 8 bytes header)
91 if (dirSecurityOffset != 0)
92 n -= (dirSecuritySize);
93 hash.TransformFinalBlock (file, pe, n);