// Sebastien Pouliot <sebastien@ximian.com>
//
// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
-// (C) 2004 Novell (http://www.novell.com)
+// Copyright (C) 2004-2006,2008 Novell, Inc (http://www.novell.com)
//
using System;
using Mono.Security;
using Mono.Security.Cryptography;
+using Mono.Security.X509;
[assembly: AssemblyTitle("Mono StrongName")]
[assembly: AssemblyDescription("StrongName utility for signing assemblies")]
if ((i % 39 == 0) && (data.Length > 39))
sb.Append (Environment.NewLine);
sb.Append (data [i].ToString ("x2"));
- if (i > 1000) {
+ if (i > 2080) {
+ // ensure we can display up to 16384 bits keypair
sb.Append (" !!! TOO LONG !!!");
break;
}
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)
{
}
return false;
}
-
+#endif
static bool ReSign (string assemblyName, RSA key)
{
// 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;
{
// 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;
}
// 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);
return 0;
}
else {
- Console.WriteLine ("Assembly {0} isn't strongnamed", assemblyName);
+ Console.WriteLine ("Assembly {0} is delay-signed but not strongnamed", assemblyName);
return 1;
}
}
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");
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);
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"));
else
Header();
- bool config = LoadConfig (quiet);
+ LoadConfig (quiet);
StrongName sn = null;
AssemblyName an = null;
case "-k":
// Create a new strong name key pair
// (a new RSA keypair automagically if none is present)
- sn = new StrongName ();
+ int size = 1024;
+ if (i < args.Length + 2) {
+ try {
+ size = Int32.Parse (args[i++]);
+ }
+ catch {
+ // oops, that wasn't a valid key size (assume 1024 bits)
+ i--;
+ }
+ }
+ sn = new StrongName (size);
WriteToFile (args[i], CryptoConvert.ToCapiKeyBlob (sn.RSA, true));
if (!quiet)
- Console.WriteLine ("A new strong name keypair has been generated in {0}", args [i]);
+ Console.WriteLine ("A new {0} bits strong name keypair has been generated in file '{1}'.", size, args [i]);
break;
case "-m":
Console.WriteLine ("Unimplemented option");
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++]);
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]);
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":
}
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;
+ }
}
}