Null constant cannot be used for ref/out variables
[mono.git] / mcs / tools / security / sn.cs
index b1e1cd987cebf37cf592b24b76f96d9a18c5187a..28ee366d4e46d0efc9a5cfdf056cf2fd6d3af38a 100644 (file)
@@ -5,7 +5,7 @@
 //     Sebastien Pouliot  <sebastien@ximian.com>
 //
 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
-// Copyright (C) 2004-2006 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")]
@@ -116,6 +117,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 [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) 
@@ -199,7 +223,7 @@ 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);
@@ -208,7 +232,7 @@ namespace Mono.Tools {
                                        return 0;
                                }
                                else {
-                                       Console.WriteLine ("Assembly {0} isn't strongnamed", assemblyName);
+                                       Console.WriteLine ("Assembly {0} is delay-signed but not strongnamed", assemblyName);
                                        return 1;
                                }
                        }
@@ -266,9 +290,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);
@@ -284,15 +308,8 @@ namespace Mono.Tools {
                        }
                }
 
-               [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"));
@@ -382,8 +399,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]);
@@ -399,8 +416,7 @@ 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])))
                                                return 1;
                                        break;
                                case "-Rc":
@@ -475,5 +491,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;
+               }
        }
 }