2 // AuthenticodeBase.cs: Authenticode signature base class
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // (C) 2004 Novell (http://www.novell.com)
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System.Security.Cryptography;
38 namespace Mono.Security.Authenticode {
41 // a. http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
59 class AuthenticodeBase {
61 public const string spcIndirectDataContext = "1.3.6.1.4.1.311.2.1.4";
63 internal byte[] rawData;
65 public AuthenticodeBase ()
69 protected byte[] HashFile (string fileName, string hashName)
71 FileStream fs = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
72 byte[] file = new byte [fs.Length];
73 fs.Read (file, 0, file.Length);
77 if (BitConverterLE.ToUInt16 (file, 0) != 0x5A4D)
80 // find offset of PE header
81 int peOffset = BitConverterLE.ToInt32 (file, 60);
82 if (peOffset > file.Length)
86 if (BitConverterLE.ToUInt16 (file, peOffset) != 0x4550)
89 // IMAGE_DIRECTORY_ENTRY_SECURITY
90 int dirSecurityOffset = BitConverterLE.ToInt32 (file, peOffset + 152);
91 int dirSecuritySize = BitConverterLE.ToInt32 (file, peOffset + 156);
93 if (dirSecuritySize > 8) {
94 rawData = new byte [dirSecuritySize - 8];
95 Buffer.BlockCopy (file, dirSecurityOffset + 8, rawData, 0, rawData.Length);
97 FileStream debug = new FileStream (fileName + ".sig", FileMode.Create, FileAccess.Write);
98 debug.Write (rawData, 0, rawData.Length);
104 HashAlgorithm hash = HashAlgorithm.Create (hashName);
105 // 0 to 215 (216) then skip 4 (checksum)
106 int pe = peOffset + 88;
107 hash.TransformBlock (file, 0, pe, file, 0);
109 // 220 to 279 (60) then skip 8 (IMAGE_DIRECTORY_ENTRY_SECURITY)
110 hash.TransformBlock (file, pe, 60, file, pe);
112 // 288 to end of file
113 int n = file.Length - pe;
114 // minus any authenticode signature (with 8 bytes header)
115 if (dirSecurityOffset != 0)
116 n -= (dirSecuritySize);
117 hash.TransformFinalBlock (file, pe, n);