2004-03-25 Sebastien Pouliot <sebastien@ximian.com>
authorSebastien Pouliot <sebastien@ximian.com>
Thu, 25 Mar 2004 20:29:43 +0000 (20:29 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Thu, 25 Mar 2004 20:29:43 +0000 (20:29 -0000)
* attribute.cs: Added methods to get a string and a bool from an
attribute. Required to information from AssemblyKeyFileAttribute,
AttributeKeyNameAttribute (string) and AssemblyDelaySign (bool).
* codegen.cs: Modified AssemblyName creation to include support for
strongnames. Catch additional exceptions to report them as CS1548.
* compiler.csproj: Updated include CryptoConvert.cs.
* compiler.csproj.user: Removed file - user specific configuration.
* CryptoConvert.cs: New. A COPY of the class CryptoConvert from
Mono.Security assembly. The original class is maintained and tested in
/mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoConvert.cs.
* drivers.cs: Added support for /keyfile, /keycontainer and /delaysign
like CSC 8.0 (C# v2) supports.
* Makefile: Added CryptoConvert.cs to mcs sources.
* rootcontext.cs: Added new options for strongnames.

svn path=/trunk/mcs/; revision=24609

mcs/mcs/ChangeLog
mcs/mcs/CryptoConvert.cs [new file with mode: 0755]
mcs/mcs/Makefile
mcs/mcs/attribute.cs
mcs/mcs/codegen.cs
mcs/mcs/compiler.csproj
mcs/mcs/compiler.csproj.user [deleted file]
mcs/mcs/driver.cs
mcs/mcs/rootcontext.cs

index 8d39eb872b058cf7a6de0e685baf8d28daf33a74..e49affc72db6c5b626a9a12aee6c4d30c02dceea 100755 (executable)
@@ -1,3 +1,20 @@
+2004-03-25  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * attribute.cs: Added methods to get a string and a bool from an
+       attribute. Required to information from AssemblyKeyFileAttribute,
+       AttributeKeyNameAttribute (string) and AssemblyDelaySign (bool).
+       * codegen.cs: Modified AssemblyName creation to include support for
+       strongnames. Catch additional exceptions to report them as CS1548.
+       * compiler.csproj: Updated include CryptoConvert.cs.
+       * compiler.csproj.user: Removed file - user specific configuration.
+       * CryptoConvert.cs: New. A COPY of the class CryptoConvert from 
+       Mono.Security assembly. The original class is maintained and tested in
+       /mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoConvert.cs.
+       * drivers.cs: Added support for /keyfile, /keycontainer and /delaysign
+       like CSC 8.0 (C# v2) supports.
+       * Makefile: Added CryptoConvert.cs to mcs sources.
+       * rootcontext.cs: Added new options for strongnames.
+
 2004-03-24 Ben Maurer  <bmaurer@users.sourceforge.net>
 
        * driver.cs: For --expect-error, report error code `2'
diff --git a/mcs/mcs/CryptoConvert.cs b/mcs/mcs/CryptoConvert.cs
new file mode 100755 (executable)
index 0000000..1335b0b
--- /dev/null
@@ -0,0 +1,376 @@
+//
+// CryptoConvert.cs - Crypto Convertion Routines
+//
+// Author:
+//     Sebastien Pouliot  <sebastien@ximian.com>
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// (C) 2004 Novell (http://www.novell.com)
+//
+
+using System;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Mono.Security.Cryptography {
+
+#if INSIDE_CORLIB
+       internal
+#else
+       public
+#endif
+       class CryptoConvert {
+
+               static private byte[] Trim (byte[] array) 
+               {
+                       for (int i=0; i < array.Length; i++) {
+                               if (array [i] != 0x00) {
+                                       byte[] result = new byte [array.Length - i];
+                                       Array.Copy (array, i, result, 0, result.Length);
+                                       return result;
+                               }
+                       }
+                       return null;
+               }
+
+               // convert the key from PRIVATEKEYBLOB to RSA
+               // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/Security/private_key_blobs.asp
+               // e.g. SNK files, PVK files
+               static public RSA FromCapiPrivateKeyBlob (byte[] blob) 
+               {
+                       return FromCapiPrivateKeyBlob (blob, 0);
+               }
+
+               static public RSA FromCapiPrivateKeyBlob (byte[] blob, int offset) 
+               {
+                       if (blob == null)
+                               throw new ArgumentNullException ("blob");
+                       if (offset >= blob.Length)
+                               throw new ArgumentException ("blob is too small.");
+
+                       try {
+                               if ((blob [offset]   != 0x07) ||                                // PRIVATEKEYBLOB (0x07)
+                                   (blob [offset+1] != 0x02) ||                                // Version (0x02)
+                                   (blob [offset+2] != 0x00) ||                                // Reserved (word)
+                                   (blob [offset+3] != 0x00) ||
+                                   (BitConverter.ToUInt32 (blob, offset+8) != 0x32415352))     // DWORD magic = RSA2
+                                       throw new CryptographicException ("Invalid blob header");
+                               
+                               // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
+                               int algId = BitConverter.ToInt32 (blob, offset+4);
+
+                               // DWORD bitlen
+                               int bitLen = BitConverter.ToInt32 (blob, offset+12);
+
+                               // DWORD public exponent
+                               RSAParameters rsap = new RSAParameters ();
+                               byte[] exp = new byte [4];
+                               Array.Copy (blob, offset+16, exp, 0, 4);
+                               Array.Reverse (exp);
+                               rsap.Exponent = Trim (exp);
+                       
+                               int pos = offset+20;
+                               // BYTE modulus[rsapubkey.bitlen/8];
+                               int byteLen = (bitLen >> 3);
+                               rsap.Modulus = new byte [byteLen];
+                               Array.Copy (blob, pos, rsap.Modulus, 0, byteLen);
+                               Array.Reverse (rsap.Modulus);
+                               pos += byteLen;
+
+                               // BYTE prime1[rsapubkey.bitlen/16];
+                               int byteHalfLen = (byteLen >> 1);
+                               rsap.P = new byte [byteHalfLen];
+                               Array.Copy (blob, pos, rsap.P, 0, byteHalfLen);
+                               Array.Reverse (rsap.P);
+                               pos += byteHalfLen;
+
+                               // BYTE prime2[rsapubkey.bitlen/16];
+                               rsap.Q = new byte [byteHalfLen];
+                               Array.Copy (blob, pos, rsap.Q, 0, byteHalfLen);
+                               Array.Reverse (rsap.Q);
+                               pos += byteHalfLen;
+
+                               // BYTE exponent1[rsapubkey.bitlen/16];
+                               rsap.DP = new byte [byteHalfLen];
+                               Array.Copy (blob, pos, rsap.DP, 0, byteHalfLen);
+                               Array.Reverse (rsap.DP);
+                               pos += byteHalfLen;
+
+                               // BYTE exponent2[rsapubkey.bitlen/16];
+                               rsap.DQ = new byte [byteHalfLen];
+                               Array.Copy (blob, pos, rsap.DQ, 0, byteHalfLen);
+                               Array.Reverse (rsap.DQ);
+                               pos += byteHalfLen;
+
+                               // BYTE coefficient[rsapubkey.bitlen/16];
+                               rsap.InverseQ = new byte [byteHalfLen];
+                               Array.Copy (blob, pos, rsap.InverseQ, 0, byteHalfLen);
+                               Array.Reverse (rsap.InverseQ);
+                               pos += byteHalfLen;
+
+                               // BYTE privateExponent[rsapubkey.bitlen/8];
+                               rsap.D = new byte [byteLen];
+                               Array.Copy (blob, pos, rsap.D, 0, byteLen);
+                               Array.Reverse (rsap.D);
+
+                               RSA rsa = (RSA)RSA.Create ();
+                               rsa.ImportParameters (rsap);
+                               return rsa;
+                       }
+                       catch (Exception e) {
+                               throw new CryptographicException ("Invalid blob.", e);
+                       }
+               }
+
+               static public byte[] ToCapiPrivateKeyBlob (RSA rsa) 
+               {
+                       RSAParameters p = rsa.ExportParameters (true);
+                       int keyLength = p.Modulus.Length; // in bytes
+                       byte[] blob = new byte [20 + (keyLength << 2) + (keyLength >> 1)];
+
+                       blob [0] = 0x07;        // Type - PRIVATEKEYBLOB (0x07)
+                       blob [1] = 0x02;        // Version - Always CUR_BLOB_VERSION (0x02)
+                       // [2], [3]             // RESERVED - Always 0
+                       blob [5] = 0x24;        // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN)
+                       blob [8] = 0x52;        // Magic - RSA2 (ASCII in hex)
+                       blob [9] = 0x53;
+                       blob [10] = 0x41;
+                       blob [11] = 0x32;
+
+                       byte[] bitlen = BitConverter.GetBytes (keyLength << 3);
+                       blob [12] = bitlen [0]; // bitlen
+                       blob [13] = bitlen [1]; 
+                       blob [14] = bitlen [2]; 
+                       blob [15] = bitlen [3];
+
+                       // public exponent (DWORD)
+                       int pos = 16;
+                       int n = p.Exponent.Length;
+                       while (n > 0)
+                               blob [pos++] = p.Exponent [--n];
+                       // modulus
+                       pos = 20;
+                       byte[] part = p.Modulus;
+                       int len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Array.Copy (part, 0, blob, pos, len);
+                       pos += len;
+                       // private key
+                       part = p.P;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Array.Copy (part, 0, blob, pos, len);
+                       pos += len;
+
+                       part = p.Q;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Array.Copy (part, 0, blob, pos, len);
+                       pos += len;
+
+                       part = p.DP;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Array.Copy (part, 0, blob, pos, len);
+                       pos += len;
+
+                       part = p.DQ;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Array.Copy (part, 0, blob, pos, len);
+                       pos += len;
+
+                       part = p.InverseQ;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Array.Copy (part, 0, blob, pos, len);
+                       pos += len;
+
+                       part = p.D;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Array.Copy (part, 0, blob, pos, len);
+
+                       return blob;
+               }
+
+               static public RSA FromCapiPublicKeyBlob (byte[] blob) 
+               {
+                       return FromCapiPublicKeyBlob (blob, 0);
+               }
+
+               static public RSA FromCapiPublicKeyBlob (byte[] blob, int offset) 
+               {
+                       if (blob == null)
+                               throw new ArgumentNullException ("blob");
+                       if (offset >= blob.Length)
+                               throw new ArgumentException ("blob is too small.");
+
+                       try {
+                               if ((blob [offset]   != 0x06) ||                                // PUBLICKEYBLOB (0x06)
+                                   (blob [offset+1] != 0x02) ||                                // Version (0x02)
+                                   (blob [offset+2] != 0x00) ||                                // Reserved (word)
+                                   (blob [offset+3] != 0x00) || 
+                                   (BitConverter.ToUInt32 (blob, offset+8) != 0x31415352))     // DWORD magic = RSA1
+                                       throw new CryptographicException ("Invalid blob header");
+
+                               // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
+                               int algId = BitConverter.ToInt32 (blob, offset+4);
+
+                               // DWORD bitlen
+                               int bitLen = BitConverter.ToInt32 (blob, offset+12);
+
+                               // DWORD public exponent
+                               RSAParameters rsap = new RSAParameters ();
+                               rsap.Exponent = new byte [3];
+                               rsap.Exponent [0] = blob [offset+18];
+                               rsap.Exponent [1] = blob [offset+17];
+                               rsap.Exponent [2] = blob [offset+16];
+                       
+                               int pos = offset+20;
+                               // BYTE modulus[rsapubkey.bitlen/8];
+                               int byteLen = (bitLen >> 3);
+                               rsap.Modulus = new byte [byteLen];
+                               Array.Copy (blob, pos, rsap.Modulus, 0, byteLen);
+                               Array.Reverse (rsap.Modulus);
+
+                               RSA rsa = (RSA)RSA.Create ();
+                               rsa.ImportParameters (rsap);
+                               return rsa;
+                       }
+                       catch (Exception e) {
+                               throw new CryptographicException ("Invalid blob.", e);
+                       }
+               }
+
+               static public byte[] ToCapiPublicKeyBlob (RSA rsa) 
+               {
+                       RSAParameters p = rsa.ExportParameters (false);
+                       int keyLength = p.Modulus.Length; // in bytes
+                       byte[] blob = new byte [20 + keyLength];
+
+                       blob [0] = 0x06;        // Type - PUBLICKEYBLOB (0x06)
+                       blob [1] = 0x02;        // Version - Always CUR_BLOB_VERSION (0x02)
+                       // [2], [3]             // RESERVED - Always 0
+                       blob [5] = 0x24;        // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN)
+                       blob [8] = 0x52;        // Magic - RSA1 (ASCII in hex)
+                       blob [9] = 0x53;
+                       blob [10] = 0x41;
+                       blob [11] = 0x31;
+
+                       byte[] bitlen = BitConverter.GetBytes (keyLength << 3);
+                       blob [12] = bitlen [0]; // bitlen
+                       blob [13] = bitlen [1]; 
+                       blob [14] = bitlen [2]; 
+                       blob [15] = bitlen [3];
+
+                       // public exponent (DWORD)
+                       int pos = 16;
+                       int n = p.Exponent.Length;
+                       while (n > 0)
+                               blob [pos++] = p.Exponent [--n];
+                       // modulus
+                       pos = 20;
+                       byte[] part = p.Modulus;
+                       int len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Array.Copy (part, 0, blob, pos, len);
+                       pos += len;
+                       return blob;
+               }
+
+               // PRIVATEKEYBLOB
+               // PUBLICKEYBLOB
+               static public RSA FromCapiKeyBlob (byte[] blob) 
+               {
+                       return FromCapiKeyBlob (blob, 0);
+               }
+
+               static public RSA FromCapiKeyBlob (byte[] blob, int offset) 
+               {
+                       if (blob == null)
+                               throw new ArgumentNullException ("blob");
+                       if (offset >= blob.Length)
+                               throw new ArgumentException ("blob is too small.");
+
+                       switch (blob [offset]) {
+                               case 0x00:
+                                       // this could be a public key inside an header
+                                       // like "sn -e" would produce
+                                       if (blob [offset + 12] == 0x06) {
+                                               return FromCapiPublicKeyBlob (blob, offset + 12);
+                                       }
+                                       break;
+                               case 0x06:
+                                       return FromCapiPublicKeyBlob (blob, offset);
+                               case 0x07:
+                                       return FromCapiPrivateKeyBlob (blob, offset);
+                       }
+                       throw new CryptographicException ("Unknown blob format.");
+               }
+
+               static public byte[] ToCapiKeyBlob (AsymmetricAlgorithm keypair, bool includePrivateKey) 
+               {
+                       if (keypair == null)
+                               throw new ArgumentNullException ("keypair");
+
+                       // check between RSA and DSA (and potentially others like DH)
+                       if (keypair is RSA)
+                               return ToCapiKeyBlob ((RSA)keypair, includePrivateKey);
+                       else
+                               return null;    // TODO
+               }
+
+               static public byte[] ToCapiKeyBlob (RSA rsa, bool includePrivateKey) 
+               {
+                       if (rsa == null)
+                               throw new ArgumentNullException ("rsa");
+
+                       RSAParameters p = rsa.ExportParameters (includePrivateKey);
+                       if (includePrivateKey)
+                               return ToCapiPrivateKeyBlob (rsa);
+                       else
+                               return ToCapiPublicKeyBlob (rsa);
+               }
+
+               static public string ToHex (byte[] input) 
+               {
+                       if (input == null)
+                               return null;
+
+                       StringBuilder sb = new StringBuilder (input.Length * 2);
+                       foreach (byte b in input) {
+                               sb.Append (b.ToString ("X2"));
+                       }
+                       return sb.ToString ();
+               }
+
+               static private byte FromHexChar (char c) 
+               {
+                       if ((c >= 'a') && (c <= 'f'))
+                               return (byte) (c - 'a' + 10);
+                       if ((c >= 'A') && (c <= 'F'))
+                               return (byte) (c - 'A' + 10);
+                       if ((c >= '0') && (c <= '9'))
+                               return (byte) (c - '0');
+                       throw new ArgumentException ("invalid hex char");
+               }
+
+               static public byte[] FromHex (string hex) 
+               {
+                       if (hex == null)
+                               return null;
+                       if ((hex.Length & 0x1) == 0x1)
+                               throw new ArgumentException ("Length must be a multiple of 2");
+
+                       byte[] result = new byte [hex.Length >> 1];
+                       int n = 0;
+                       int i = 0;
+                       while (n < result.Length) {
+                               result [n] = (byte) (FromHexChar (hex [i++]) << 4);
+                               result [n++] += FromHexChar (hex [i++]);
+                       }
+                       return result;
+               }
+       }
+}
index 0905804972172e5d7a7badd8dc7f4944c8649289..bf89f9a16f2a660c270c8e8936e8de13876739cd 100644 (file)
@@ -35,14 +35,14 @@ COMPILER_SOURCES = \
        support.cs                      \
        typemanager.cs                  \
        symbolwriter.cs                 \
-       tree.cs
+       tree.cs                         \
+       CryptoConvert.cs
 
 all_sources = $(COMPILER_SOURCES) cs-parser.cs
 
 DISTFILES = \
        $(COMPILER_SOURCES)     \
        compiler.csproj         \
-       compiler.csproj.user    \
        compiler.doc            \
        compiler.sln            \
        cs-parser.jay           \
index f4522350cc47fc1a546f4cb56f1440d7bdad2132..b59e70a776dc65e694e5f2cf039c8a617191b2ef 100644 (file)
@@ -1166,7 +1166,35 @@ namespace Mono.CSharp {
                        
                        return mb;
                }
-               
+
+               private Expression GetValue () 
+               {
+                       if ((Arguments == null) || (Arguments.Count < 1))
+                               return null;
+                       ArrayList al = (ArrayList) Arguments [0];
+                       if ((al == null) || (al.Count < 1))
+                               return null;
+                       Argument arg = (Argument) al [0];
+                       if ((arg == null) || (arg.Expr == null))
+                               return null;
+                       return arg.Expr;
+               }
+
+               public string GetString () 
+               {
+                       Expression e = GetValue ();
+                       if (e is StringLiteral)
+                               return (e as StringLiteral).Value;
+                       return null;
+               }
+
+               public bool GetBoolean () 
+               {
+                       Expression e = GetValue ();
+                       if (e is BoolLiteral)
+                               return (e as BoolLiteral).Value;
+                       return false;
+               }
        }
        
        public class AttributeSection {
index f30a1b68f4d9808e4e097b7c57e5f0556ba98703..23ce22629650432aa4b3f8aa5f01c890c814ba9d 100755 (executable)
@@ -12,6 +12,9 @@ using System.IO;
 using System.Collections;
 using System.Reflection;
 using System.Reflection.Emit;
+using System.Security.Cryptography;
+
+using Mono.Security.Cryptography;
 
 namespace Mono.CSharp {
 
@@ -90,15 +93,31 @@ namespace Mono.CSharp {
                //
                static public void Init (string name, string output, bool want_debugging_support)
                {
-                       AssemblyName an;
-
                        FileName = output;
-                       an = new AssemblyName ();
-                       an.Name = Path.GetFileNameWithoutExtension (name);
+                       AssemblyName an = Assembly.GetAssemblyName (name, output);
                        
                        current_domain = AppDomain.CurrentDomain;
-                       Assembly.Builder = current_domain.DefineDynamicAssembly (
-                               an, AssemblyBuilderAccess.Save, Dirname (name));
+
+                       try {
+                               Assembly.Builder = current_domain.DefineDynamicAssembly (an,
+                                       AssemblyBuilderAccess.Save, Dirname (name));
+                       }
+                       catch (ArgumentException) {
+                               // specified key may not be exportable outside it's container
+                               if (RootContext.StrongNameKeyContainer != null) {
+                                       Report.Error (1548, "Could not access the key inside the container `" +
+                                               RootContext.StrongNameKeyContainer + "'.");
+                                       Environment.Exit (1);
+                               }
+                               throw;
+                       }
+                       catch (CryptographicException) {
+                               if ((RootContext.StrongNameKeyContainer != null) || (RootContext.StrongNameKeyFile != null)) {
+                                       Report.Error (1548, "Could not use the specified key to strongname the assembly.");
+                                       Environment.Exit (1);
+                               }
+                               throw;
+                       }
 
                        //
                        // Pass a path-less name to DefineDynamicModule.  Wonder how
@@ -728,7 +747,7 @@ namespace Mono.CSharp {
 
 
        public abstract class CommonAssemblyModulClass: IAttributeSupport {
-               Hashtable m_attributes;
+               protected Hashtable m_attributes;
 
                protected CommonAssemblyModulClass () 
                {
@@ -794,6 +813,102 @@ namespace Mono.CSharp {
                        }
                }
 
+               public AssemblyName GetAssemblyName (string name, string output) 
+               {
+                       // scan assembly attributes for strongname related attr
+                       foreach (DictionaryEntry nsattr in m_attributes) {
+                               ArrayList list = ((Attributes)nsattr.Value).AttributeSections;
+                               for (int i=0; i < list.Count; i++) {
+                                       AttributeSection asect = (AttributeSection) list [i];
+                                       if (asect.Target != "assembly")
+                                               continue;
+                                       // strongname attributes don't support AllowMultiple
+                                       Attribute a = (Attribute) asect.Attributes [0];
+                                       switch (a.Name) {
+                                               case "AssemblyKeyFile":
+                                                       if (RootContext.StrongNameKeyFile != null) {
+                                                               Report.Warning (1616, "Compiler option -keyfile overrides " +
+                                                                       "AssemblyKeyFileAttribute");
+                                                       }
+                                                       else {
+                                                               string value = a.GetString ();
+                                                               if (value != String.Empty)
+                                                                       RootContext.StrongNameKeyFile = value;
+                                                       }
+                                                       break;
+                                               case "AssemblyKeyName":
+                                                       if (RootContext.StrongNameKeyContainer != null) {
+                                                               Report.Warning (1616, "Compiler option -keycontainer overrides " +
+                                                                       "AssemblyKeyNameAttribute");
+                                                       }
+                                                       else {
+                                                               string value = a.GetString ();
+                                                               if (value != String.Empty)
+                                                                       RootContext.StrongNameKeyContainer = value;
+                                                       }
+                                                       break;
+                                               case "AssemblyDelaySign":
+                                                       RootContext.StrongNameDelaySign = a.GetBoolean ();
+                                                       break;
+                                       }
+                               }
+                       }
+
+                       AssemblyName an = new AssemblyName ();
+                       an.Name = Path.GetFileNameWithoutExtension (name);
+
+                       // note: delay doesn't apply when using a key container
+                       if (RootContext.StrongNameKeyContainer != null) {
+                               an.KeyPair = new StrongNameKeyPair (RootContext.StrongNameKeyContainer);
+                               return an;
+                       }
+
+                       // strongname is optional
+                       if (RootContext.StrongNameKeyFile == null)
+                               return an;
+
+                       string AssemblyDir = Path.GetDirectoryName (output);
+
+                       // the StrongName key file may be relative to (a) the compiled
+                       // file or (b) to the output assembly. See bugzilla #55320
+                       // http://bugzilla.ximian.com/show_bug.cgi?id=55320
+
+                       // (a) relative to the compiled file
+                       string filename = Path.GetFullPath (RootContext.StrongNameKeyFile);
+                       bool exist = File.Exists (filename);
+                       if ((!exist) && (AssemblyDir != null) && (AssemblyDir != String.Empty)) {
+                               // (b) relative to the outputed assembly
+                               filename = Path.GetFullPath (Path.Combine (AssemblyDir, RootContext.StrongNameKeyFile));
+                               exist = File.Exists (filename);
+                       }
+
+                       if (exist) {
+                               using (FileStream fs = new FileStream (filename, FileMode.Open)) {
+                                       byte[] snkeypair = new byte [fs.Length];
+                                       fs.Read (snkeypair, 0, snkeypair.Length);
+
+                                       try {
+                                               // this will import public or private/public keys
+                                               RSA rsa = CryptoConvert.FromCapiKeyBlob (snkeypair);
+                                               // only the public part must be supplied if signature is delayed
+                                               byte[] key = CryptoConvert.ToCapiKeyBlob (rsa, !RootContext.StrongNameDelaySign);
+                                               an.KeyPair = new StrongNameKeyPair (key);
+                                       }
+                                       catch (CryptographicException) {
+                                               Report.Error (1548, "Could not strongname the assembly. File `" +
+                                                       RootContext.StrongNameKeyFile + "' incorrectly encoded.");
+                                               Environment.Exit (1);
+                                       }
+                               }
+                       }
+                       else {
+                               Report.Error (1548, "Could not strongname the assembly. File `" +
+                                       RootContext.StrongNameKeyFile + "' not found.");
+                               Environment.Exit (1);
+                       }
+                       return an;
+               }
+
                public override void SetCustomAttribute(CustomAttributeBuilder customBuilder)
                {
                        Builder.SetCustomAttribute (customBuilder);
index 4d3b0ae597c1b2f201c6b788257f3f32c3dab9be..615c97c35310ce1dd0c8d99bb0fbdf7dbc84d66f 100755 (executable)
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
+                <File
+                    RelPath = "CryptoConvert.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
                 <File
                     RelPath = "cs-parser.cs"
                     SubType = "Code"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
-                <File
-                    RelPath = "interface.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
                 <File
                     RelPath = "iterators.cs"
                     SubType = "Code"
diff --git a/mcs/mcs/compiler.csproj.user b/mcs/mcs/compiler.csproj.user
deleted file mode 100755 (executable)
index 21d133e..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-<VisualStudioProject>
-    <CSHARP LastOpenVersion = "7.10.3077" >
-        <Build>
-            <Settings ReferencePath = "" >
-                <Config
-                    Name = "Debug"
-                    EnableASPDebugging = "false"
-                    EnableASPXDebugging = "false"
-                    EnableUnmanagedDebugging = "false"
-                    EnableSQLServerDebugging = "false"
-                    RemoteDebugEnabled = "false"
-                    RemoteDebugMachine = ""
-                    StartAction = "Project"
-                    StartArguments = ""
-                    StartPage = ""
-                    StartProgram = ""
-                    StartURL = ""
-                    StartWorkingDirectory = ""
-                    StartWithIE = "false"
-                />
-                <Config
-                    Name = "Release"
-                    EnableASPDebugging = "false"
-                    EnableASPXDebugging = "false"
-                    EnableUnmanagedDebugging = "false"
-                    EnableSQLServerDebugging = "false"
-                    RemoteDebugEnabled = "false"
-                    RemoteDebugMachine = ""
-                    StartAction = "Project"
-                    StartArguments = ""
-                    StartPage = ""
-                    StartProgram = ""
-                    StartURL = ""
-                    StartWorkingDirectory = ""
-                    StartWithIE = "false"
-                />
-            </Settings>
-        </Build>
-        <OtherProjectSettings
-            CopyProjectDestinationFolder = ""
-            CopyProjectUncPath = ""
-            CopyProjectOption = "0"
-            ProjectView = "ShowAllFiles"
-            ProjectTrust = "0"
-        />
-    </CSHARP>
-</VisualStudioProject>
-
index 876178dc4be3f1bdb0416a37544cacac011d7acb..fc3293de99960e402765e2e78ebd975c86198997 100755 (executable)
@@ -196,10 +196,13 @@ namespace Mono.CSharp
                                "   -codepage:ID       Sets code page to the one in ID\n" +
                                "                      (number, `utf8' or `reset')\n" +
                                "   -define:S1[;S2]    Defines one or more symbols (short: /d:)\n" +
-                               "   -debug[+-]         Generate debugging information\n" + 
+                               "   -debug[+|-]        Generate debugging information\n" + 
+                               "   -delaysign[+|-]    Only insert the public key into the assembly (no signing)\n" +
                                "   -doc:FILE          XML Documentation file to generate\n" + 
                                "   -g                 Generate debugging information\n" +
                                "   --fatal            Makes errors fatal\n" +
+                               "   -keycontainer:NAME The key pair container used to strongname the assembly\n" +
+                               "   -keyfile:FILE      The strongname key file used to strongname the assembly\n" +
                                "   -lib:PATH1,PATH2   Adds the paths to the assembly link path\n" +
                                "   -main:class        Specified the class that contains the entry point\n" +
                                "   -noconfig[+|-]     Disables implicit references to assemblies\n" +
@@ -1158,6 +1161,27 @@ namespace Mono.CSharp
                        case "/fullpaths":
                                return true;
 
+                       case "/keyfile":
+                               if (value == String.Empty) {
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               RootContext.StrongNameKeyFile = value;
+                               return true;
+                       case "/keycontainer":
+                               if (value == String.Empty) {
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               RootContext.StrongNameKeyContainer = value;
+                               return true;
+                       case "/delaysign+":
+                               RootContext.StrongNameDelaySign = true;
+                               return true;
+                       case "/delaysign-":
+                               RootContext.StrongNameDelaySign = false;
+                               return true;
+
                        case "/v2":
                        case "/2":
                                SetupV2 ();
index 96f40a2593e2c67f0e66016ad69152d21181bbc6..79dd32441d45f5fbebd9c2822d581e33093e968b 100755 (executable)
@@ -66,6 +66,15 @@ namespace Mono.CSharp {
                // If set, enable C# version 2 features
                //
                public static bool V2 = true;
+
+               //
+               // We keep strongname related info here because
+               // it's also used as complier options from CSC 8.x
+               //
+               public static string StrongNameKeyFile;
+               public static string StrongNameKeyContainer;
+               public static bool StrongNameDelaySign = false;
+
                //
                // Constructor
                //