[xbuild] Update printed version/copyright
[mono.git] / mcs / tools / security / sn.cs
index 7c4ccbca7ca12ed1100dc52747ea159e74c59579..4f6660077050d007c56f426b49c7265bf1271f60 100644 (file)
@@ -5,7 +5,7 @@
 //     Sebastien Pouliot  <sebastien@ximian.com>
 //
 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
-// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2006,2008 Novell, Inc (http://www.novell.com)
 //
 
 using System;
@@ -16,6 +16,7 @@ using System.Text;
 
 using Mono.Security;
 using Mono.Security.Cryptography;
+using Mono.Security.X509;
 
 [assembly: AssemblyTitle("Mono StrongName")]
 [assembly: AssemblyDescription("StrongName utility for signing assemblies")]
@@ -117,6 +118,29 @@ namespace Mono.Tools {
                        return sb.ToString ();
                }
 
+               static RSA GetKeyFromFile (string filename)
+               {
+                       byte[] data = ReadFromFile (filename);
+                       try {
+                               // for SNK files (including the ECMA pseudo-key)
+                               return new StrongName (data).RSA;
+                       }
+                       catch {
+                               if (data.Length == 0 || data [0] != 0x30)
+                                       throw;
+                               // this could be a PFX file
+                               Console.Write ("Enter password for private key (will be visible when typed): ");
+                               PKCS12 pfx = new PKCS12 (data, Console.ReadLine ());
+                               // works only if a single key is present
+                               if (pfx.Keys.Count != 1)
+                                       throw;
+                               RSA rsa = (pfx.Keys [0] as RSA);
+                               if (rsa == null)
+                                       throw;
+                               return rsa;
+                       }
+               }
+#if false
                // is assembly signed (or delayed signed) ?
                static bool IsStrongNamed (Assembly assembly) 
                {
@@ -132,12 +156,17 @@ namespace Mono.Tools {
                        }
                        return false;
                }
-
-               static bool ReSign (string assemblyName, RSA key) 
+#endif
+               static bool ReSign (string assemblyName, RSA key, bool quiet
                {
                        // this doesn't load the assembly (well it unloads it ;)
                        // http://weblogs.asp.net/nunitaddin/posts/9991.aspx
-                       AssemblyName an = AssemblyName.GetAssemblyName (assemblyName);
+                       AssemblyName an = null;
+                       try {
+                               an = AssemblyName.GetAssemblyName (assemblyName);
+                       }
+                       catch {
+                       }
                        if (an == null) {
                                Console.WriteLine ("Unable to load assembly: {0}", assemblyName);
                                return false;
@@ -159,8 +188,10 @@ namespace Mono.Tools {
 
                        if (same) {
                                bool signed = sign.Sign (assemblyName);
-                               Console.WriteLine (signed ? "Assembly {0} signed." : "Couldn't sign the assembly {0}.", 
-                                                  assemblyName);
+                               if (!quiet || !signed) {
+                                       Console.WriteLine (signed ? "Assembly {0} signed." : "Couldn't sign the assembly {0}.", 
+                                                          assemblyName);
+                               }
                                return signed;
                        }
                        
@@ -168,11 +199,16 @@ namespace Mono.Tools {
                        return false;
                }
 
-               static int Verify (string assemblyName, bool forceVerification) 
+               static int Verify (string assemblyName, bool forceVerification, bool quiet
                {
                        // this doesn't load the assembly (well it unloads it ;)
                        // http://weblogs.asp.net/nunitaddin/posts/9991.aspx
-                       AssemblyName an = AssemblyName.GetAssemblyName (assemblyName);
+                       AssemblyName an = null;
+                       try {
+                               an = AssemblyName.GetAssemblyName (assemblyName);
+                       }
+                       catch {
+                       }
                        if (an == null) {
                                Console.WriteLine ("Unable to load assembly: {0}", assemblyName);
                                return 2;
@@ -189,16 +225,17 @@ namespace Mono.Tools {
                        }
 
                        // Note: MustVerify is based on the original token (by design). Public key
-                       // remapping won't affect if the assebmly is verified or not.
+                       // remapping won't affect if the assembly is verified or not.
                        if (forceVerification || StrongNameManager.MustVerify (an)) {
                                RSA rsa = CryptoConvert.FromCapiPublicKeyBlob (publicKey, 12);
                                StrongName sn = new StrongName (rsa);
                                if (sn.Verify (assemblyName)) {
-                                       Console.WriteLine ("Assembly {0} is strongnamed.", assemblyName);
+                                       if (!quiet)
+                                               Console.WriteLine ("Assembly {0} is strongnamed.", assemblyName);
                                        return 0;
                                }
                                else {
-                                       Console.WriteLine ("Assembly {0} isn't strongnamed", assemblyName);
+                                       Console.WriteLine ("Assembly {0} is delay-signed but not strongnamed", assemblyName);
                                        return 1;
                                }
                        }
@@ -235,6 +272,7 @@ namespace Mono.Tools {
                                        Console.WriteLine (" -Vr assembly [userlist]{0}\tExempt the specified assembly from verification for the user list", Environment.NewLine);
                                        Console.WriteLine (" -Vu assembly{0}\tRemove exemption entry for the specified assembly", Environment.NewLine);
                                        Console.WriteLine (" -Vx{0}\tRemove all exemptions entries", Environment.NewLine);
+                                       Console.WriteLine ("{0}<1> Currently not implemented in the tool", Environment.NewLine);
                                        break;
                                case "csp":
                                        Console.WriteLine ("CSP related options");
@@ -255,9 +293,9 @@ namespace Mono.Tools {
                                        Console.WriteLine (" -k keypair.snk{0}\tCreate a new keypair in the specified file", Environment.NewLine);
                                        Console.WriteLine (" -R assembly keypair.snk{0}\tResign the assembly with the specified StrongName key file", Environment.NewLine);
                                        Console.WriteLine (" -Rc assembly container{0}\tResign the assembly with the specified CSP container", Environment.NewLine);
-                                       Console.WriteLine (" -t file{0}\tShow the public key from the specified file", Environment.NewLine);
+                                       Console.WriteLine (" -t file{0}\tShow the public key token from the specified file", Environment.NewLine);
                                        Console.WriteLine (" -tp file{0}\tShow the public key and pk token from the specified file", Environment.NewLine);
-                                       Console.WriteLine (" -T assembly{0}\tShow the public key from the specified assembly", Environment.NewLine);
+                                       Console.WriteLine (" -T assembly{0}\tShow the public key token from the specified assembly", Environment.NewLine);
                                        Console.WriteLine (" -Tp assembly{0}\tShow the public key and pk token from the specified assembly", Environment.NewLine);
                                        Console.WriteLine (" -v assembly{0}\tVerify the specified assembly signature", Environment.NewLine);
                                        Console.WriteLine (" -vf assembly{0}\tVerify the specified assembly signature (even if disabled).", Environment.NewLine);
@@ -271,18 +309,10 @@ namespace Mono.Tools {
                                        Console.WriteLine (" -? | -h sn     \tStrongName signing options");
                                        break;
                        }
-                       Console.WriteLine ("{0}<1> Currently not implemented in the tool", Environment.NewLine);
                }
 
-               [STAThread]
-               static int Main (string[] args)
+               static int Process (string[] args)
                {
-                       if (args.Length < 1) {
-                               Header ();
-                               Help (null);
-                               return 1;
-                       }
-
                        int i = 0;
                        string param = args [i];
                        bool quiet = ((param == "-quiet") || (param == "-q"));
@@ -363,7 +393,7 @@ namespace Mono.Tools {
                                        byte[] infileD = ReadFromFile (args [i++]);
                                        WriteCSVToFile (args [i], infileD, "D");
                                        if (!quiet)
-                                               Console.WriteLine ("Output CVS file is {0} (decimal format)", args [i]);
+                                               Console.WriteLine ("Output CSV file is {0} (decimal format)", args [i]);
                                        break;
                                case "-oh":
                                        byte[] infileX2 = ReadFromFile (args [i++]);
@@ -372,8 +402,8 @@ namespace Mono.Tools {
                                                Console.WriteLine ("Output CVS file is {0} (hexadecimal format)", args [i]);
                                        break;
                                case "-p":
-                                       // Extract public key from SNK file
-                                       sn = new StrongName (ReadFromFile (args [i++]));
+                                       // Extract public key from SNK or PKCS#12/PFX file
+                                       sn = new StrongName (GetKeyFromFile (args [i++]));
                                        WriteToFile (args[i], sn.PublicKey);
                                        if (!quiet)
                                                Console.WriteLine ("Public Key extracted to file {0}", args [i]);
@@ -389,15 +419,14 @@ namespace Mono.Tools {
                                        break;
                                case "-R":
                                        string filename = args [i++];
-                                       sn = new StrongName (ReadFromFile (args [i]));
-                                       if (! ReSign (filename, sn.RSA))
+                                       if (! ReSign (filename, GetKeyFromFile (args [i]), quiet))
                                                return 1;
                                        break;
                                case "-Rc":
                                        filename = args [i++];
                                        csp.KeyContainerName = args [i];
                                        rsa = new RSACryptoServiceProvider (csp);
-                                       if (! ReSign (filename, rsa))
+                                       if (! ReSign (filename, rsa, quiet))
                                                return 1;
                                        break;
                                case "-t":
@@ -437,10 +466,10 @@ namespace Mono.Tools {
                                        break;
                                case "-v":
                                        filename = args [i++];
-                                       return Verify (filename, false);
+                                       return Verify (filename, false, quiet);
                                case "-vf":
                                        filename = args [i++];
-                                       return Verify (filename, true); // force verification
+                                       return Verify (filename, true, quiet);  // force verification
                                case "-Vl":
                                        Console.WriteLine (new StrongNameManager ().ToString ());
                                        break;
@@ -465,5 +494,30 @@ namespace Mono.Tools {
                        }
                        return 0;
                }
+
+               [STAThread]
+               static int Main (string[] args)
+               {
+                       try {
+                               if (args.Length < 1) {
+                                       Header ();
+                                       Help (null);
+                               } else {
+                                       return Process (args);
+                               }
+                       }
+                       catch (IndexOutOfRangeException) {
+                               Console.WriteLine ("ERROR: Invalid number of parameters.{0}", Environment.NewLine);
+                               Help (null);
+                       }
+                       catch (CryptographicException ce) {
+                               Console.WriteLine ("ERROR: {0}", ce.Message);
+                       }
+                       catch (Exception e) {
+                               Console.WriteLine ("ERROR: Unknown error during processing: {0}", e);
+                       }
+
+                       return 1;
+               }
        }
 }