2004-10-29 Sebastien Pouliot <sebastien@ximian.com>
authorSebastien Pouliot <sebastien@ximian.com>
Fri, 29 Oct 2004 21:45:36 +0000 (21:45 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Fri, 29 Oct 2004 21:45:36 +0000 (21:45 -0000)
* AuthenticodeFormatter.cs: Fixed spcSpOpusInfo attribute (it wasn't
added) and contentType attribute (was added 2 times). Also fixed the
case where we signed an already Authenticode signed file (re-signing).
* SoftwarePublisherCertificate.cs: Support for base64 encoded ASN.1
files (either Unicode or ASCII).

svn path=/branches/mono-1-0/mcs/; revision=35487

mcs/class/Mono.Security/Mono.Security.Authenticode/AuthenticodeFormatter.cs
mcs/class/Mono.Security/Mono.Security.Authenticode/ChangeLog
mcs/class/Mono.Security/Mono.Security.Authenticode/SoftwarePublisherCertificate.cs

index 1c1540bae61b8f2a20de6bf057fad39f36483635..418f14483a5a2b556e37fdaa4811db28b54377a4 100755 (executable)
@@ -165,7 +165,7 @@ namespace Mono.Security.Authenticode {
                private const string commercialCodeSigning = "1.3.6.1.4.1.311.2.1.22";
                private const string timestampCountersignature = "1.3.6.1.4.1.311.3.2.1";
 
-               private static byte[] version = { 0x01 };
+               //private static byte[] version = { 0x01 };
                private static byte[] obsolete = { 0x03, 0x01, 0x00, 0xA0, 0x20, 0xA2, 0x1E, 0x80, 0x1C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x4F, 0x00, 0x62, 0x00, 0x73, 0x00, 0x6F, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x74, 0x00, 0x65, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x3E };
 
                private byte[] Header (byte[] fileHash, string hashAlgorithm) 
@@ -189,15 +189,12 @@ namespace Mono.Security.Authenticode {
 
                        ASN1 opus = null;
                        if (url == null)
-                               Attribute (spcSpOpusInfo, Opus (description, null));
+                               opus = Attribute (spcSpOpusInfo, Opus (description, null));
                        else
-                               Attribute (spcSpOpusInfo, Opus (description, url.ToString ()));
+                               opus = Attribute (spcSpOpusInfo, Opus (description, url.ToString ()));
                        pkcs7.SignerInfo.AuthenticatedAttributes.Add (opus);
-
-                       pkcs7.SignerInfo.AuthenticatedAttributes.Add (Attribute (contentType, ASN1Convert.FromOid (spcIndirectDataContext)));
                        pkcs7.SignerInfo.AuthenticatedAttributes.Add (Attribute (spcStatementType, new ASN1 (0x30, ASN1Convert.FromOid (commercialCodeSigning).GetBytes ())));
-
-                       ASN1 temp = pkcs7.ASN1; // sign
+                       pkcs7.GetASN1 (); // sign
                        return pkcs7.SignerInfo.Signature;
                }
 
@@ -225,10 +222,13 @@ namespace Mono.Security.Authenticode {
                public bool Sign (string fileName) 
                {
                        string hashAlgorithm = "MD5";
-                       FileStream fs = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
-                       byte[] file = new byte [fs.Length];
-                       fs.Read (file, 0, file.Length);
-                       fs.Close ();
+                       byte[] file = null;
+
+                       using (FileStream fs = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) {
+                               file = new byte [fs.Length];
+                               fs.Read (file, 0, file.Length);
+                               fs.Close ();
+                       }
 
                        // MZ - DOS header
                        if (BitConverter.ToUInt16 (file, 0) != 0x5A4D)
@@ -284,42 +284,46 @@ namespace Mono.Security.Authenticode {
                        sign.Content.Add (pkcs7.ASN1);
                        authenticode = sign.ASN1;
 
-                       // debug
-                       fs = File.Open (fileName + ".sig", FileMode.Create, FileAccess.Write);
                        byte[] asn = authenticode.GetBytes ();
-                       fs.Write (asn, 0, asn.Length);
-                       fs.Close ();
+                       // debug
+                       if (Environment.GetEnvironmentVariable ("MONO_DEBUG") != null) {
+                               using (FileStream fs = File.Open (fileName + ".sig", FileMode.Create, FileAccess.Write)) {
+                                       fs.Write (asn, 0, asn.Length);
+                                       fs.Close ();
+                               }
+                       }
 
                        File.Copy (fileName, fileName + ".bak", true);
 
-                       fs = File.Open (fileName, FileMode.Create, FileAccess.Write);
-                       // IMAGE_DIRECTORY_ENTRY_SECURITY (offset, size)
-                       byte[] data = BitConverter.GetBytes (file.Length);
-                       file [peOffset + 152] = data [0];
-                       file [peOffset + 153] = data [1];
-                       file [peOffset + 154] = data [2];
-                       file [peOffset + 155] = data [3];
-                       int size = asn.Length + 8;
-                       // must be a multiple of 8 bytes
-                       int addsize = (size % 8);
-                       if (addsize > 0)
-                               addsize = 8 - addsize;
-                       size += addsize;
-                       data = BitConverter.GetBytes (size);            // header
-                       file [peOffset + 156] = data [0];
-                       file [peOffset + 157] = data [1];
-                       file [peOffset + 158] = data [2];
-                       file [peOffset + 159] = data [3];
-                       fs.Write (file, 0, file.Length);
-                       fs.Write (data, 0, data.Length);                // length (again)
-                       data = BitConverter.GetBytes (0x00020200);      // magic
-                       fs.Write (data, 0, data.Length);
-                       fs.Write (asn, 0, asn.Length);
-                       // fill up
-                       byte[] fillup = new byte [addsize];
-                       fs.Write (fillup, 0, fillup.Length);
-                       fs.Close ();
-
+                       using (FileStream fs = File.Open (fileName, FileMode.Create, FileAccess.Write)) {\r
+                               int filesize = (dirSecurityOffset == 0) ? file.Length : dirSecurityOffset;\r
+                               // IMAGE_DIRECTORY_ENTRY_SECURITY (offset, size)\r
+                               byte[] data = BitConverter.GetBytes (filesize);\r
+                               file [peOffset + 152] = data [0];
+                               file [peOffset + 153] = data [1];
+                               file [peOffset + 154] = data [2];
+                               file [peOffset + 155] = data [3];
+                               int size = asn.Length + 8;
+                               // must be a multiple of 8 bytes
+                               int addsize = (size % 8);
+                               if (addsize > 0)
+                                       addsize = 8 - addsize;
+                               size += addsize;
+                               data = BitConverter.GetBytes (size);            // header
+                               file [peOffset + 156] = data [0];
+                               file [peOffset + 157] = data [1];
+                               file [peOffset + 158] = data [2];
+                               file [peOffset + 159] = data [3];\r
+                               fs.Write (file, 0, filesize);\r
+                               fs.Write (data, 0, data.Length);                // length (again)
+                               data = BitConverter.GetBytes (0x00020200);      // magic
+                               fs.Write (data, 0, data.Length);
+                               fs.Write (asn, 0, asn.Length);
+                               // fill up
+                               byte[] fillup = new byte [addsize];
+                               fs.Write (fillup, 0, fillup.Length);
+                               fs.Close ();
+                       }
                        return true;
                }
 
index c81a55d025dfe5b40444034065600bebe8a40c7c..04e07ac959d92a81e780036b73f31dec7841f053 100644 (file)
@@ -1,3 +1,11 @@
+2004-10-29  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * AuthenticodeFormatter.cs: Fixed spcSpOpusInfo attribute (it wasn't 
+       added) and contentType attribute (was added 2 times). Also fixed the
+       case where we signed an already Authenticode signed file (re-signing).
+       * SoftwarePublisherCertificate.cs: Support for base64 encoded ASN.1 
+       files (either Unicode or ASCII).
+
 2004-10-27  Sebastien Pouliot  <sebastien@ximian.com>
 
        * AuthenticodeFormatter.cs: Fix NullReferenceException from signcode
index d5be5ee44fd687f5b7b0d27d742b48b7a0b6008d..0a87385dc93f958080e310026c5556bd93608fa9 100644 (file)
@@ -34,6 +34,7 @@ using System;
 using System.Collections;
 using System.Globalization;
 using System.IO;
+using System.Text;
 
 using Mono.Security;
 using Mono.Security.X509;
@@ -89,6 +90,29 @@ namespace Mono.Security.Authenticode {
                                fs.Read (data, 0, data.Length);
                                fs.Close ();
                        }
+
+                       // It seems that VeriSign send the SPC file in Unicode
+                       // (base64 encoded) and Windows accept them.
+                       if (data.Length < 2)
+                               return null;
+
+                       if (data [0] != 0x30) {
+                               // this isn't an ASN.1 SEQUENCE (so not legal)
+                               if (data [1] == 0x00) {
+                                       // this could be base64/unicode (e.g. VeriSign)
+                                       data = Convert.FromBase64String (Encoding.Unicode.GetString (data));
+                               }
+                               else {
+                                       // default to base64/ascii
+                                       data = Convert.FromBase64String (Encoding.ASCII.GetString (data));
+                               }
+                       }
+#if DEBUG
+                       using (FileStream fs = File.OpenWrite (filename + ".der")) {
+                               fs.Write (data, 0, data.Length);
+                               fs.Close ();
+                       }
+#endif
                        return new SoftwarePublisherCertificate (data);
                }
        }