//
-// CryptoConfig.cs: Handles cryptographic implementations and OIDs.
+// CryptoConfig.cs: Handles cryptographic implementations and OIDs mappings.
//
// Author:
-// Sebastien Pouliot (spouliot@motus.com)
+// Sebastien Pouliot (sebastien@ximian.com)
+// Tim Coleman (tim@timcoleman.com)
//
// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) Tim Coleman, 2004
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
using System.Collections;
+using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
using System.Text;
using Mono.Xml;
namespace System.Security.Cryptography {
+#if NET_2_0
+[ComVisible (true)]
+#endif
public class CryptoConfig {
+ static private object lockObject;
static private Hashtable algorithms;
static private Hashtable oid;
// LAMESPEC: undocumented classes (also undocumented in CryptoConfig ;-)
private const string defaultDSASigDesc = defaultNamespace + "DSASignatureDescription";
private const string defaultRSASigDesc = defaultNamespace + "RSAPKCS1SHA1SignatureDescription";
+#if NET_2_0
+ private const string defaultRIPEMD160 = defaultNamespace + "RIPEMD160Managed";
+ private const string defaultHMACMD5 = defaultNamespace + "HMACMD5";
+ private const string defaultHMACRIPEMD160 = defaultNamespace + "HMACRIPEMD160";
+ private const string defaultHMACSHA256 = defaultNamespace + "HMACSHA256";
+ private const string defaultHMACSHA384 = defaultNamespace + "HMACSHA384";
+ private const string defaultHMACSHA512 = defaultNamespace + "HMACSHA512";
+#endif
+
// LAMESPEC: undocumented names in CryptoConfig
+#if (NET_2_0)
+ private const string xmlAssembly = ", System.Security, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
+#elif (NET_1_1)
+ private const string xmlAssembly = ", System.Security, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
+#elif (NET_1_0)
+ private const string xmlAssembly = ", System.Security, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
+#else
private const string xmlAssembly = ", System.Security, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
+#endif
private const string defaultC14N = defaultNamespace + "Xml.XmlDsigC14NTransform" + xmlAssembly;
private const string defaultC14NWithComments = defaultNamespace + "Xml.XmlDsigC14NWithCommentsTransform" + xmlAssembly;
private const string defaultBase64 = defaultNamespace + "Xml.XmlDsigBase64Transform" + xmlAssembly;
private const string defaultXPath = defaultNamespace + "Xml.XmlDsigXPathTransform" + xmlAssembly;
private const string defaultXslt = defaultNamespace + "Xml.XmlDsigXsltTransform" + xmlAssembly;
private const string defaultEnveloped = defaultNamespace + "Xml.XmlDsigEnvelopedSignatureTransform" + xmlAssembly;
+#if NET_2_0
+ private const string defaultXmlDecryption = defaultNamespace + "Xml.XmlDecryptionTransform" + xmlAssembly;
+ private const string defaultExcC14N = defaultNamespace + "Xml.XmlDsigExcC14NTransform" + xmlAssembly;
+ private const string defaultExcC14NWithComments = defaultNamespace + "Xml.XmlDsigExcC14NWithCommentsTransform" + xmlAssembly;
+#endif
+
// LAMESPEC: only documentated in ".NET Framework Security" book
private const string defaultX509Data = defaultNamespace + "Xml.KeyInfoX509Data" + xmlAssembly;
private const string defaultKeyName = defaultNamespace + "Xml.KeyInfoName" + xmlAssembly;
// Oddly OID seems only available for hash algorithms
private const string oidSHA1 = "1.3.14.3.2.26";
private const string oidMD5 = "1.2.840.113549.2.5";
+#if NET_2_0
+ // changed in 2.0
+ private const string oidSHA256 = "2.16.840.1.101.3.4.2.1";
+ private const string oidSHA384 = "2.16.840.1.101.3.4.2.2";
+ private const string oidSHA512 = "2.16.840.1.101.3.4.2.3";
+ // new in 2.0
+// private const string oidRSA = "1.2.840.113549.1.1.1";
+ private const string oidDSA = "1.2.840.10040.4.1";
+ private const string oidDES = "1.3.14.3.2.7";
+ private const string oid3DES = "1.2.840.113549.3.7";
+ private const string oidRC2 = "1.2.840.113549.3.2";
+#else
private const string oidSHA256 = "2.16.840.1.101.3.4.1";
private const string oidSHA384 = "2.16.840.1.101.3.4.2";
private const string oidSHA512 = "2.16.840.1.101.3.4.3";
+#endif
// LAMESPEC: only documentated in ".NET Framework Security" book
private const string oid3DESKeyWrap = "1.2.840.113549.1.9.16.3.6";
private const string nameRNGa = "RandomNumberGenerator";
private const string nameRNGb = "System.Security.Cryptography.RandomNumberGenerator";
private const string nameKeyHasha = "System.Security.Cryptography.KeyedHashAlgorithm";
- private const string nameHMACa = "HMACSHA1";
- private const string nameHMACb = "System.Security.Cryptography.HMACSHA1";
+ private const string nameHMACSHA1a = "HMACSHA1";
+ private const string nameHMACSHA1b = "System.Security.Cryptography.HMACSHA1";
private const string nameMAC3DESa = "MACTripleDES";
private const string nameMAC3DESb = "System.Security.Cryptography.MACTripleDES";
// LAMESPEC: only documentated in ".NET Framework Security" book
private const string name3DESKeyWrap = "TripleDESKeyWrap";
+#if NET_2_0
+ private const string nameRIPEMD160a = "RIPEMD160";
+ private const string nameRIPEMD160b = "RIPEMD-160";
+ private const string nameRIPEMD160c = "System.Security.Cryptography.RIPEMD160";
+ private const string nameHMACa = "HMAC";
+ private const string nameHMACb = "System.Security.Cryptography.HMAC";
+ private const string nameHMACMD5a = "HMACMD5";
+ private const string nameHMACMD5b = "System.Security.Cryptography.HMACMD5";
+ private const string nameHMACRIPEMD160a = "HMACRIPEMD160";
+ private const string nameHMACRIPEMD160b = "System.Security.Cryptography.HMACRIPEMD160";
+ private const string nameHMACSHA256a = "HMACSHA256";
+ private const string nameHMACSHA256b = "System.Security.Cryptography.HMACSHA256";
+ private const string nameHMACSHA384a = "HMACSHA384";
+ private const string nameHMACSHA384b = "System.Security.Cryptography.HMACSHA384";
+ private const string nameHMACSHA512a = "HMACSHA512";
+ private const string nameHMACSHA512b = "System.Security.Cryptography.HMACSHA512";
+#endif
private const string urlXmlDsig = "http://www.w3.org/2000/09/xmldsig#";
// LAMESPEC: undocumented URLs in CryptoConfig
private const string urlXPath = "http://www.w3.org/TR/1999/REC-xpath-19991116";
private const string urlXslt = "http://www.w3.org/TR/1999/REC-xslt-19991116";
private const string urlEnveloped = urlXmlDsig + "enveloped-signature"; // no space
+#if NET_2_0
+ private const string urlXmlDecryption = "http://www.w3.org/2002/07/decrypt#XML";
+ private const string urlExcC14N = "http://www.w3.org/2001/10/xml-exc-c14n#WithComments";
+ private const string urlExcC14NWithComments = "http://www.w3.org/2001/10/xml-exc-c14n#";
+#endif
+
// LAMESPEC: only documentated in ".NET Framework Security" book
private const string urlX509Data = urlXmlDsig + " X509Data"; // space is required
private const string urlKeyName = urlXmlDsig + " KeyName"; // space is required
private const string urlKeyValueRSA = urlXmlDsig + " KeyValue/RSAKeyValue"; // space is required
private const string urlRetrievalMethod = urlXmlDsig + " RetrievalMethod"; // space is required
- static CryptoConfig ()
+ static CryptoConfig ()
{
- algorithms = new Hashtable ();
+ // lock(this) is bad
+ // http://msdn.microsoft.com/library/en-us/dnaskdr/html/askgui06032003.asp?frame=true
+ lockObject = new object ();
+ }
+
+ private static void Initialize ()
+ {
+ Hashtable algorithms = new Hashtable ();
// see list @ http://msdn.microsoft.com/library/en-us/cpref/html/
// frlrfSystemSecurityCryptographyCryptoConfigClassTopic.asp
algorithms.Add (nameSHA1a, defaultSHA1);
algorithms.Add (nameDSAa, defaultDSA);
algorithms.Add (nameDSAb, defaultDSA);
-
+
algorithms.Add (nameDESa, defaultDES);
algorithms.Add (nameDESb, defaultDES);
-
+
algorithms.Add (name3DESa, default3DES);
algorithms.Add (name3DESb, default3DES);
algorithms.Add (name3DESc, default3DES);
algorithms.Add (name3DESd, default3DES);
-
+
algorithms.Add (nameRC2a, defaultRC2);
algorithms.Add (nameRC2b, defaultRC2);
algorithms.Add (nameRNGa, defaultRNG);
algorithms.Add (nameRNGb, defaultRNG);
algorithms.Add (nameKeyHasha, defaultHMAC);
- algorithms.Add (nameHMACa, defaultHMAC);
- algorithms.Add (nameHMACb, defaultHMAC);
+ algorithms.Add (nameHMACSHA1a, defaultHMAC);
+ algorithms.Add (nameHMACSHA1b, defaultHMAC);
algorithms.Add (nameMAC3DESa, defaultMAC3DES);
algorithms.Add (nameMAC3DESb, defaultMAC3DES);
+#if NET_2_0
+ algorithms.Add (nameRIPEMD160a, defaultRIPEMD160);
+ algorithms.Add (nameRIPEMD160b, defaultRIPEMD160);
+ algorithms.Add (nameRIPEMD160c, defaultRIPEMD160);
+ algorithms.Add (nameHMACb, defaultHMAC);
+ algorithms.Add (nameHMACMD5a, defaultHMACMD5);
+ algorithms.Add (nameHMACMD5b, defaultHMACMD5);
+ algorithms.Add (nameHMACRIPEMD160a, defaultHMACRIPEMD160);
+ algorithms.Add (nameHMACRIPEMD160b, defaultHMACRIPEMD160);
+ algorithms.Add (nameHMACSHA256a, defaultHMACSHA256);
+ algorithms.Add (nameHMACSHA256b, defaultHMACSHA256);
+ algorithms.Add (nameHMACSHA384a, defaultHMACSHA384);
+ algorithms.Add (nameHMACSHA384b, defaultHMACSHA384);
+ algorithms.Add (nameHMACSHA512a, defaultHMACSHA512);
+ algorithms.Add (nameHMACSHA512b, defaultHMACSHA512);
+#endif
// LAMESPEC These URLs aren't documented but (hint) installing the WSDK
// add some of the XMLDSIG urls into machine.config (and they make a LOT
algorithms.Add (urlXPath, defaultXPath);
algorithms.Add (urlXslt, defaultXslt);
algorithms.Add (urlEnveloped, defaultEnveloped);
+#if NET_2_0
+ algorithms.Add (urlExcC14N, defaultExcC14N);
+ algorithms.Add (urlExcC14NWithComments, defaultExcC14NWithComments);
+ algorithms.Add (urlXmlDecryption, defaultXmlDecryption);
+#endif
// LAMESPEC: only documentated in ".NET Framework Security" book
algorithms.Add (urlX509Data, defaultX509Data);
algorithms.Add (urlKeyName, defaultKeyName);
algorithms.Add (urlKeyValueRSA, defaultKeyValueRSA);
algorithms.Add (urlRetrievalMethod, defaultRetrievalMethod);
- oid = new Hashtable ();
+ Hashtable oid = new Hashtable ();
// comments here are to match with MS implementation (but not with doc)
// LAMESPEC: only HashAlgorithm seems to have their OID included
oid.Add (defaultSHA1, oidSHA1);
// surprise! documented in ".NET Framework Security" book
oid.Add (name3DESKeyWrap, oid3DESKeyWrap);
+#if NET_2_0
+// oid.Add (nameRSAa, oidRSA);
+ oid.Add (nameDSAa, oidDSA);
+ oid.Add (nameDESa, oidDES);
+ oid.Add (name3DESa, oid3DES);
+ oid.Add (name3DESb, oid3DES);
+ oid.Add (nameRC2a, oidRC2);
+#endif
+
// Add/modify the config as specified by machine.config
- string config = GetMachineConfigPath ();
- // debug @"D:\Program Files\Mono-0.25\etc\mono\machine.config";
- if (config != null)
- LoadConfig (config);
+ string config = Environment.GetMachineConfigPath ();
+ LoadConfig (config, algorithms, oid);
+
+ // update
+ CryptoConfig.algorithms = algorithms;
+ CryptoConfig.oid = oid;
}
- internal static void LoadConfig (string filename)
+ [FileIOPermission (SecurityAction.Assert, Unrestricted = true)]
+ private static void LoadConfig (string filename, Hashtable algorithms, Hashtable oid)
{
if (!File.Exists (filename))
return;
}
}
- // managed version of "get_machine_config_path"
- internal static string GetMachineConfigPath ()
- {
- string env = Environment.GetEnvironmentVariable ("MONO_CONFIG");
- if (env != null)
- return env;
- env = Environment.GetEnvironmentVariable ("MONO_BASEPATH");
- if (env == null)
- return null;
-
- StringBuilder sb = new StringBuilder ();
- sb.Append (env);
- sb.Append (Path.DirectorySeparatorChar);
- sb.Append ("etc");
- sb.Append (Path.DirectorySeparatorChar);
- sb.Append ("mono");
- sb.Append (Path.DirectorySeparatorChar);
- sb.Append ("machine.config");
- return sb.ToString ();
- }
-
public static object CreateFromName (string name)
{
return CreateFromName (name, null);
}
+ [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
public static object CreateFromName (string name, object[] args)
{
if (name == null)
- throw new ArgumentNullException ();
+ throw new ArgumentNullException ("name");
+
+ lock (lockObject) {
+ if (algorithms == null) {
+ Initialize ();
+ }
+ }
try {
Type algoClass = null;
return Activator.CreateInstance (algoClass, args);
}
catch {
- // method deosn't throw any exception
+ // method doesn't throw any exception
return null;
}
}
// for MS BCL compatibility
// comment next two lines to remove restriction
if ((x > Int32.MaxValue) || (x < Int32.MinValue))
- throw new OverflowException ("part of OID doesn't fit in Int32");
+ throw new OverflowException (Locale.GetText ("Part of OID doesn't fit in Int32"));
long y = x;
// number of bytes required to encode this number
public static byte[] EncodeOID (string str)
{
+#if NET_2_0
+ if (str == null)
+ throw new ArgumentNullException ("str");
+#endif
char[] delim = { '.' };
string[] parts = str.Split (delim);
// according to X.208 n is always at least 2
- if (parts.Length < 2)
- throw new CryptographicUnexpectedOperationException ();
+ if (parts.Length < 2) {
+ throw new CryptographicUnexpectedOperationException (
+ Locale.GetText ("OID must have at least two parts"));
+ }
+
// we're sure that the encoded OID is shorter than its string representation
byte[] oid = new byte [str.Length];
// now encoding value
oid[2] = Convert.ToByte (part0 * 40 + part1);
}
catch {
- throw new CryptographicUnexpectedOperationException ();
+ throw new CryptographicUnexpectedOperationException (
+ Locale.GetText ("Invalid OID"));
}
int j = 3;
for (int i = 2; i < parts.Length; i++) {
- long x = Convert.ToInt64( parts [i]);
+ long x = Convert.ToInt64 (parts [i]);
if (x > 0x7F) {
byte[] num = EncodeLongNumber (x);
- Array.Copy(num, 0, oid, j, num.Length);
+ Buffer.BlockCopy (num, 0, oid, j, num.Length);
j += num.Length;
}
else
// Length (of value)
if (j > 0x7F) {
// for compatibility with MS BCL
- throw new CryptographicUnexpectedOperationException ("OID > 127 bytes");
+ throw new CryptographicUnexpectedOperationException (
+ Locale.GetText ("OID > 127 bytes"));
// comment exception and uncomment next 3 lines to remove restriction
//byte[] num = EncodeLongNumber (j);
- //Array.Copy (num, 0, oid, j, num.Length);
+ //Buffer.BlockCopy (num, 0, oid, j, num.Length);
//k = num.Length + 1;
}
else
oid2 [1] = Convert.ToByte (j - 2);
- Array.Copy (oid, k, oid2, k, j - k);
+ Buffer.BlockCopy (oid, k, oid2, k, j - k);
return oid2;
}
if (name == null)
throw new ArgumentNullException ("name");
+ lock (lockObject) {
+ if (oid == null) {
+ Initialize ();
+ }
+ }
+
return (string)oid [name];
}
}
-}
\ No newline at end of file
+}