[coop] Temporarily restore MonoThreadInfo when TLS destructor runs. Fixes #43099
[mono.git] / mcs / class / referencesource / mscorlib / system / security / cryptography / cryptoconfig.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 // <OWNER>[....]</OWNER>
7 // 
8
9 //
10 // CryptoConfig.cs
11 //
12
13 namespace System.Security.Cryptography {
14     using System;
15     using System.Collections;
16     using System.Collections.Generic;
17     using System.IO;
18     using System.Reflection;
19     using System.Security.Cryptography.X509Certificates;
20     using System.Security.Permissions;
21     using System.Threading;
22     using System.Globalization;
23     using System.Runtime.Versioning;
24     using Microsoft.Win32;
25     using System.Diagnostics.Contracts;
26
27     [System.Runtime.InteropServices.ComVisible(true)]
28     public class CryptoConfig {
29         private static volatile Dictionary<string, string> defaultOidHT = null;
30         private static volatile Dictionary<string, object> defaultNameHT = null;
31         private static volatile Dictionary<string, string> machineOidHT = null;
32         private static volatile Dictionary<string, string> machineNameHT = null;
33         private static volatile Dictionary<string, Type> appNameHT = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
34         private static volatile Dictionary<string, string> appOidHT = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
35
36         private const string MachineConfigFilename = "machine.config";
37
38         private static volatile string version = null;
39
40 #if FEATURE_CRYPTO
41         private static volatile bool s_fipsAlgorithmPolicy;
42         private static volatile bool s_haveFipsAlgorithmPolicy;
43
44         /// <summary>
45         ///     Determine if the runtime should enforce that only FIPS certified algorithms are created. This
46         ///     property returns true if this policy should be enforced, false if any algorithm may be created.
47         /// </summary>
48         public static bool AllowOnlyFipsAlgorithms {
49             [System.Security.SecuritySafeCritical]  // auto-generated
50             [ResourceExposure(ResourceScope.None)]
51             [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
52             get {
53                 if (!s_haveFipsAlgorithmPolicy)
54                 {
55                     //
56                     // If the user has not disabled FIPS enforcement in a config file, check the CNG settings
57                     // on Vista and the FIPS registry key downlevel.
58                     //
59
60 #if !FEATURE_CORECLR
61                     if (Utils._GetEnforceFipsPolicySetting()) {
62                         if (Environment.OSVersion.Version.Major >= 6) {
63                             bool fipsEnabled;
64                             uint policyReadStatus = Win32Native.BCryptGetFipsAlgorithmMode(out fipsEnabled);
65
66                             bool readPolicy = policyReadStatus == Win32Native.STATUS_SUCCESS ||
67                                               policyReadStatus == Win32Native.STATUS_OBJECT_NAME_NOT_FOUND;
68
69                             s_fipsAlgorithmPolicy = !readPolicy || fipsEnabled;
70                             s_haveFipsAlgorithmPolicy = true;
71                         }
72                         else {
73                             s_fipsAlgorithmPolicy = Utils.ReadLegacyFipsPolicy();
74                             s_haveFipsAlgorithmPolicy = true;
75                         }
76                     }
77                     else
78 #endif // !FEATURE_CORECLR
79                     {
80                         s_fipsAlgorithmPolicy = false;
81                         s_haveFipsAlgorithmPolicy = true;
82                     }
83                 }
84
85                 return s_fipsAlgorithmPolicy;
86             }
87         }
88 #endif // FEATURE_CRYPTO
89
90         private static string Version
91         {
92             [System.Security.SecurityCritical]  // auto-generated
93             get
94             {
95                 if(version == null)
96                     version = ((RuntimeType)typeof(CryptoConfig)).GetRuntimeAssembly().GetVersion().ToString();
97
98                 return version;
99             }
100         }
101
102         // Private object for locking instead of locking on a public type for SQL reliability work.
103         private static Object s_InternalSyncObject;
104         private static Object InternalSyncObject {
105             get {
106                 if (s_InternalSyncObject == null) {
107                     Object o = new Object();
108                     Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
109                 }
110                 return s_InternalSyncObject;
111             }
112         }
113
114         private static Dictionary<string, string> DefaultOidHT {
115             get {
116                 if (defaultOidHT == null) {
117                     Dictionary<string, string> ht = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
118 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
119                     ht.Add("SHA", Constants.OID_OIWSEC_SHA1);
120                     ht.Add("SHA1", Constants.OID_OIWSEC_SHA1);
121                     ht.Add("System.Security.Cryptography.SHA1", Constants.OID_OIWSEC_SHA1);
122 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
123 #if FEATURE_CRYPTO
124                     ht.Add("System.Security.Cryptography.SHA1CryptoServiceProvider", Constants.OID_OIWSEC_SHA1);
125 #endif //FEATURE_CRYPTO
126 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
127                     ht.Add("System.Security.Cryptography.SHA1Managed", Constants.OID_OIWSEC_SHA1);
128                     ht.Add("SHA256", Constants.OID_OIWSEC_SHA256);
129                     ht.Add("System.Security.Cryptography.SHA256", Constants.OID_OIWSEC_SHA256);
130 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
131 #if FEATURE_CRYPTO 
132                     ht.Add("System.Security.Cryptography.SHA256CryptoServiceProvider", Constants.OID_OIWSEC_SHA256);
133                     ht.Add("System.Security.Cryptography.SHA256Cng", Constants.OID_OIWSEC_SHA256);
134 #endif //FEATURE_CRYPTO
135 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
136                     ht.Add("System.Security.Cryptography.SHA256Managed", Constants.OID_OIWSEC_SHA256);
137 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
138 #if FEATURE_CRYPTO
139                     ht.Add("SHA384", Constants.OID_OIWSEC_SHA384);
140                     ht.Add("System.Security.Cryptography.SHA384", Constants.OID_OIWSEC_SHA384);
141                     ht.Add("System.Security.Cryptography.SHA384CryptoServiceProvider", Constants.OID_OIWSEC_SHA384);
142                     ht.Add("System.Security.Cryptography.SHA384Cng", Constants.OID_OIWSEC_SHA384);
143                     ht.Add("System.Security.Cryptography.SHA384Managed", Constants.OID_OIWSEC_SHA384);
144                     ht.Add("SHA512", Constants.OID_OIWSEC_SHA512);
145                     ht.Add("System.Security.Cryptography.SHA512", Constants.OID_OIWSEC_SHA512);
146                     ht.Add("System.Security.Cryptography.SHA512CryptoServiceProvider", Constants.OID_OIWSEC_SHA512);
147                     ht.Add("System.Security.Cryptography.SHA512Cng", Constants.OID_OIWSEC_SHA512);
148                     ht.Add("System.Security.Cryptography.SHA512Managed", Constants.OID_OIWSEC_SHA512);
149                     ht.Add("RIPEMD160", Constants.OID_OIWSEC_RIPEMD160);
150                     ht.Add("System.Security.Cryptography.RIPEMD160", Constants.OID_OIWSEC_RIPEMD160);
151                     ht.Add("System.Security.Cryptography.RIPEMD160Managed", Constants.OID_OIWSEC_RIPEMD160);
152                     ht.Add("MD5", Constants.OID_RSA_MD5);
153                     ht.Add("System.Security.Cryptography.MD5", Constants.OID_RSA_MD5);
154                     ht.Add("System.Security.Cryptography.MD5CryptoServiceProvider", Constants.OID_RSA_MD5);
155                     ht.Add("System.Security.Cryptography.MD5Managed", Constants.OID_RSA_MD5);
156                     ht.Add("TripleDESKeyWrap", Constants.OID_RSA_SMIMEalgCMS3DESwrap);
157                     ht.Add("RC2", Constants.OID_RSA_RC2CBC);
158                     ht.Add("System.Security.Cryptography.RC2CryptoServiceProvider", Constants.OID_RSA_RC2CBC);
159                     ht.Add("DES", Constants.OID_OIWSEC_desCBC);
160                     ht.Add("System.Security.Cryptography.DESCryptoServiceProvider", Constants.OID_OIWSEC_desCBC);
161                     ht.Add("TripleDES", Constants.OID_RSA_DES_EDE3_CBC);
162                     ht.Add("System.Security.Cryptography.TripleDESCryptoServiceProvider", Constants.OID_RSA_DES_EDE3_CBC);
163 #endif // FEATURE_CRYPTO
164                     defaultOidHT = ht;
165                 }
166                 return defaultOidHT;
167             }
168         }
169
170         private static Dictionary<string, object> DefaultNameHT {
171             get {
172                 if (defaultNameHT == null) {
173                     Dictionary<string, object> ht = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
174 #if FEATURE_CRYPTO
175                     Type SHA1CryptoServiceProviderType = typeof(System.Security.Cryptography.SHA1CryptoServiceProvider);
176                     Type MD5CryptoServiceProviderType = typeof(System.Security.Cryptography.MD5CryptoServiceProvider);
177 #endif //FEATURE_CRYPTO
178 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
179                     Type SHA256ManagedType = typeof(SHA256Managed);
180 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
181 #if FEATURE_CRYPTO
182                     Type SHA384ManagedType = typeof(SHA384Managed);
183                     Type SHA512ManagedType = typeof(SHA512Managed);
184                     Type RIPEMD160ManagedType  = typeof(System.Security.Cryptography.RIPEMD160Managed); 
185                     Type HMACMD5Type       = typeof(System.Security.Cryptography.HMACMD5);
186                     Type HMACRIPEMD160Type = typeof(System.Security.Cryptography.HMACRIPEMD160);
187 #endif //FEATURE_CRYPTO
188 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
189                     Type HMACSHA1Type      = typeof(System.Security.Cryptography.HMACSHA1);
190                     Type HMACSHA256Type    = typeof(System.Security.Cryptography.HMACSHA256);
191 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
192 #if FEATURE_CRYPTO
193                     Type HMACSHA384Type    = typeof(System.Security.Cryptography.HMACSHA384);
194                     Type HMACSHA512Type    = typeof(System.Security.Cryptography.HMACSHA512);
195                     Type MAC3DESType       = typeof(System.Security.Cryptography.MACTripleDES);
196 #endif //FEATURE_CRYPTO
197 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
198                     Type RSACryptoServiceProviderType = typeof(System.Security.Cryptography.RSACryptoServiceProvider); 
199 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
200 #if FEATURE_CRYPTO && !FEATURE_CORECLR
201                     Type DSACryptoServiceProviderType = typeof(System.Security.Cryptography.DSACryptoServiceProvider); 
202                     Type DESCryptoServiceProviderType = typeof(System.Security.Cryptography.DESCryptoServiceProvider); 
203                     Type TripleDESCryptoServiceProviderType = typeof(System.Security.Cryptography.TripleDESCryptoServiceProvider); 
204                     Type RC2CryptoServiceProviderType = typeof(System.Security.Cryptography.RC2CryptoServiceProvider); 
205 #endif //FEATURE_CRYPTO
206 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
207                     Type RijndaelManagedType = typeof(System.Security.Cryptography.RijndaelManaged); 
208 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
209 #if FEATURE_CRYPTO
210                     Type DSASignatureDescriptionType = typeof(System.Security.Cryptography.DSASignatureDescription);
211                     Type RSAPKCS1SHA1SignatureDescriptionType = typeof(System.Security.Cryptography.RSAPKCS1SHA1SignatureDescription);
212 #endif //FEATURE_CRYPTO
213 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
214                     Type RNGCryptoServiceProviderType = typeof(System.Security.Cryptography.RNGCryptoServiceProvider);
215 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
216 #if FEATURE_CRYPTO
217
218                     // Cryptography algorithms in System.Core are referenced by name rather than type so
219                     // that we don't force System.Core to load if we don't need any of its algorithms
220                     string AesCryptoServiceProviderType = "System.Security.Cryptography.AesCryptoServiceProvider, " + AssemblyRef.SystemCore;
221 #endif //FEATURE_CRYPTO
222 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
223                     string AesManagedType = "System.Security.Cryptography.AesManaged, " + AssemblyRef.SystemCore;
224 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
225 #if FEATURE_CRYPTO
226                     string ECDiffieHellmanCngType = "System.Security.Cryptography.ECDiffieHellmanCng, " + AssemblyRef.SystemCore;
227                     string ECDsaCngType = "System.Security.Cryptography.ECDsaCng, " + AssemblyRef.SystemCore;
228                     string MD5CngType = "System.Security.Cryptography.MD5Cng, " + AssemblyRef.SystemCore;
229                     string SHA1CngType = "System.Security.Cryptography.SHA1Cng, " + AssemblyRef.SystemCore;
230                     string SHA256CngType = "System.Security.Cryptography.SHA256Cng, " + AssemblyRef.SystemCore;
231                     string SHA256CryptoServiceProviderType = "System.Security.Cryptography.SHA256CryptoServiceProvider, " + AssemblyRef.SystemCore;
232                     string SHA384CngType = "System.Security.Cryptography.SHA384Cng, " + AssemblyRef.SystemCore;
233                     string SHA384CryptoSerivceProviderType = "System.Security.Cryptography.SHA384CryptoServiceProvider, " + AssemblyRef.SystemCore;
234                     string SHA512CngType = "System.Security.Cryptography.SHA512Cng, " + AssemblyRef.SystemCore;
235                     string SHA512CryptoServiceProviderType = "System.Security.Cryptography.SHA512CryptoServiceProvider, " + AssemblyRef.SystemCore;
236
237                     // Cryptography algorithms in System.Security
238                     string DpapiDataProtectorType = "System.Security.Cryptography.DpapiDataProtector, " + AssemblyRef.SystemSecurity;
239
240 #endif //FEATURE_CRYPTO
241 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
242                     // Random number generator
243                     ht.Add("RandomNumberGenerator", RNGCryptoServiceProviderType);
244                     ht.Add("System.Security.Cryptography.RandomNumberGenerator", RNGCryptoServiceProviderType);
245 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
246 #if FEATURE_CRYPTO
247
248                     // Hash functions
249                     ht.Add("SHA", SHA1CryptoServiceProviderType);
250                     ht.Add("SHA1", SHA1CryptoServiceProviderType);
251                     ht.Add("System.Security.Cryptography.SHA1", SHA1CryptoServiceProviderType);
252                     ht.Add("System.Security.Cryptography.SHA1Cng", SHA1CngType);
253                     ht.Add("System.Security.Cryptography.HashAlgorithm", SHA1CryptoServiceProviderType);
254                     ht.Add("MD5", MD5CryptoServiceProviderType);
255                     ht.Add("System.Security.Cryptography.MD5", MD5CryptoServiceProviderType);
256                     ht.Add("System.Security.Cryptography.MD5Cng", MD5CngType);
257 #endif //FEATURE_CRYPTO
258 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
259                     ht.Add("SHA256", SHA256ManagedType);
260                     ht.Add("SHA-256", SHA256ManagedType);
261                     ht.Add("System.Security.Cryptography.SHA256", SHA256ManagedType);
262 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
263 #if FEATURE_CRYPTO
264                     ht.Add("System.Security.Cryptography.SHA256Cng", SHA256CngType);
265                     ht.Add("System.Security.Cryptography.SHA256CryptoServiceProvider", SHA256CryptoServiceProviderType);
266                     ht.Add("SHA384", SHA384ManagedType);
267                     ht.Add("SHA-384", SHA384ManagedType);
268                     ht.Add("System.Security.Cryptography.SHA384", SHA384ManagedType);
269                     ht.Add("System.Security.Cryptography.SHA384Cng", SHA384CngType);
270                     ht.Add("System.Security.Cryptography.SHA384CryptoServiceProvider", SHA384CryptoSerivceProviderType);
271                     ht.Add("SHA512", SHA512ManagedType);
272                     ht.Add("SHA-512", SHA512ManagedType);
273                     ht.Add("System.Security.Cryptography.SHA512", SHA512ManagedType);
274                     ht.Add("System.Security.Cryptography.SHA512Cng", SHA512CngType);
275                     ht.Add("System.Security.Cryptography.SHA512CryptoServiceProvider", SHA512CryptoServiceProviderType);
276                     ht.Add("RIPEMD160", RIPEMD160ManagedType);
277                     ht.Add("RIPEMD-160", RIPEMD160ManagedType);
278                     ht.Add("System.Security.Cryptography.RIPEMD160", RIPEMD160ManagedType);
279                     ht.Add("System.Security.Cryptography.RIPEMD160Managed", RIPEMD160ManagedType);
280
281                     // Keyed Hash Algorithms
282 #endif //FEATURE_CRYPTO
283 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
284                     ht.Add("System.Security.Cryptography.HMAC", HMACSHA1Type);
285                     ht.Add("System.Security.Cryptography.KeyedHashAlgorithm", HMACSHA1Type);
286 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
287 #if FEATURE_CRYPTO
288                     ht.Add("HMACMD5", HMACMD5Type);
289                     ht.Add("System.Security.Cryptography.HMACMD5", HMACMD5Type);
290                     ht.Add("HMACRIPEMD160", HMACRIPEMD160Type);
291                     ht.Add("System.Security.Cryptography.HMACRIPEMD160", HMACRIPEMD160Type);
292 #endif //FEATURE_CRYPTO
293 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
294                     ht.Add("HMACSHA1", HMACSHA1Type);
295                     ht.Add("System.Security.Cryptography.HMACSHA1", HMACSHA1Type);
296                     ht.Add("HMACSHA256", HMACSHA256Type);
297                     ht.Add("System.Security.Cryptography.HMACSHA256", HMACSHA256Type);
298 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
299 #if FEATURE_CRYPTO
300                     ht.Add("HMACSHA384", HMACSHA384Type);
301                     ht.Add("System.Security.Cryptography.HMACSHA384", HMACSHA384Type);
302                     ht.Add("HMACSHA512", HMACSHA512Type);
303                     ht.Add("System.Security.Cryptography.HMACSHA512", HMACSHA512Type);
304                     ht.Add("MACTripleDES", MAC3DESType);
305                     ht.Add("System.Security.Cryptography.MACTripleDES", MAC3DESType);
306
307                     // Asymmetric algorithms
308 #endif //FEATURE_CRYPTO
309 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
310                     ht.Add("RSA", RSACryptoServiceProviderType);
311                     ht.Add("System.Security.Cryptography.RSA", RSACryptoServiceProviderType);
312                     ht.Add("System.Security.Cryptography.AsymmetricAlgorithm", RSACryptoServiceProviderType);
313 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
314 #if FEATURE_CRYPTO && !FEATURE_CORECLR
315                     ht.Add("DSA", DSACryptoServiceProviderType);
316                     ht.Add("System.Security.Cryptography.DSA", DSACryptoServiceProviderType);
317                     ht.Add("ECDsa", ECDsaCngType);
318                     ht.Add("ECDsaCng", ECDsaCngType);
319                     ht.Add("System.Security.Cryptography.ECDsaCng", ECDsaCngType);
320                     ht.Add("ECDH", ECDiffieHellmanCngType);
321                     ht.Add("ECDiffieHellman", ECDiffieHellmanCngType);
322                     ht.Add("ECDiffieHellmanCng", ECDiffieHellmanCngType);
323                     ht.Add("System.Security.Cryptography.ECDiffieHellmanCng", ECDiffieHellmanCngType);
324
325                     // Symmetric algorithms
326                     ht.Add("DES", DESCryptoServiceProviderType);
327                     ht.Add("System.Security.Cryptography.DES", DESCryptoServiceProviderType);
328                     ht.Add("3DES", TripleDESCryptoServiceProviderType);
329                     ht.Add("TripleDES", TripleDESCryptoServiceProviderType);
330                     ht.Add("Triple DES", TripleDESCryptoServiceProviderType);
331                     ht.Add("System.Security.Cryptography.TripleDES", TripleDESCryptoServiceProviderType);
332                     ht.Add("RC2", RC2CryptoServiceProviderType);
333                     ht.Add("System.Security.Cryptography.RC2", RC2CryptoServiceProviderType);
334 #endif //FEATURE_CRYPTO
335 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
336                     ht.Add("Rijndael", RijndaelManagedType);
337                     ht.Add("System.Security.Cryptography.Rijndael", RijndaelManagedType);
338                     // Rijndael is the default symmetric cipher because (a) it's the strongest and (b) we know we have an implementation everywhere
339                     ht.Add("System.Security.Cryptography.SymmetricAlgorithm", RijndaelManagedType);
340 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
341 #if FEATURE_CRYPTO
342                     ht.Add("AES", AesCryptoServiceProviderType);
343                     ht.Add("AesCryptoServiceProvider", AesCryptoServiceProviderType);
344                     ht.Add("System.Security.Cryptography.AesCryptoServiceProvider", AesCryptoServiceProviderType);
345 #endif //FEATURE_CRYPTO
346 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
347                     ht.Add("AesManaged", AesManagedType);
348                     ht.Add("System.Security.Cryptography.AesManaged", AesManagedType);
349 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
350 #if FEATURE_CRYPTO
351                     // Data protectors
352                     ht.Add("DpapiDataProtector", DpapiDataProtectorType);
353                     ht.Add("System.Security.Cryptography.DpapiDataProtector", DpapiDataProtectorType);
354
355                     // Asymmetric signature descriptions
356                     ht.Add("http://www.w3.org/2000/09/xmldsig#dsa-sha1", DSASignatureDescriptionType);
357                     ht.Add("System.Security.Cryptography.DSASignatureDescription", DSASignatureDescriptionType);
358                     ht.Add("http://www.w3.org/2000/09/xmldsig#rsa-sha1", RSAPKCS1SHA1SignatureDescriptionType);
359                     ht.Add("System.Security.Cryptography.RSASignatureDescription", RSAPKCS1SHA1SignatureDescriptionType);
360
361                     // Xml Dsig/Enc Hash algorithms
362                     ht.Add("http://www.w3.org/2000/09/xmldsig#sha1", SHA1CryptoServiceProviderType);
363                     // Add the other hash algorithms introduced with XML Encryption
364 #endif //FEATURE_CRYPTO
365 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
366                     ht.Add("http://www.w3.org/2001/04/xmlenc#sha256", SHA256ManagedType);
367 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
368 #if FEATURE_CRYPTO && !FEATURE_CORECLR
369                     ht.Add("http://www.w3.org/2001/04/xmlenc#sha512", SHA512ManagedType);
370                     ht.Add("http://www.w3.org/2001/04/xmlenc#ripemd160", RIPEMD160ManagedType);
371
372                     // Xml Encryption symmetric keys
373                     ht.Add("http://www.w3.org/2001/04/xmlenc#des-cbc", DESCryptoServiceProviderType);
374                     ht.Add("http://www.w3.org/2001/04/xmlenc#tripledes-cbc", TripleDESCryptoServiceProviderType);
375                     ht.Add("http://www.w3.org/2001/04/xmlenc#kw-tripledes", TripleDESCryptoServiceProviderType);
376 #endif //FEATURE_CRYPTO
377 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
378                     ht.Add("http://www.w3.org/2001/04/xmlenc#aes128-cbc", RijndaelManagedType);
379                     ht.Add("http://www.w3.org/2001/04/xmlenc#kw-aes128", RijndaelManagedType);
380                     ht.Add("http://www.w3.org/2001/04/xmlenc#aes192-cbc", RijndaelManagedType);
381                     ht.Add("http://www.w3.org/2001/04/xmlenc#kw-aes192", RijndaelManagedType);
382                     ht.Add("http://www.w3.org/2001/04/xmlenc#aes256-cbc", RijndaelManagedType);
383                     ht.Add("http://www.w3.org/2001/04/xmlenc#kw-aes256", RijndaelManagedType);
384 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
385 #if FEATURE_CRYPTO
386
387                     // Xml Dsig Transforms
388                     // First arg must match the constants defined in System.Security.Cryptography.Xml.SignedXml
389                     ht.Add("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", "System.Security.Cryptography.Xml.XmlDsigC14NTransform, " + AssemblyRef.SystemSecurity);
390                     ht.Add("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments", "System.Security.Cryptography.Xml.XmlDsigC14NWithCommentsTransform, " + AssemblyRef.SystemSecurity);
391                     ht.Add("http://www.w3.org/2001/10/xml-exc-c14n#", "System.Security.Cryptography.Xml.XmlDsigExcC14NTransform, " + AssemblyRef.SystemSecurity);
392                     ht.Add("http://www.w3.org/2001/10/xml-exc-c14n#WithComments", "System.Security.Cryptography.Xml.XmlDsigExcC14NWithCommentsTransform, " + AssemblyRef.SystemSecurity);
393                     ht.Add("http://www.w3.org/2000/09/xmldsig#base64", "System.Security.Cryptography.Xml.XmlDsigBase64Transform, " + AssemblyRef.SystemSecurity);
394                     ht.Add("http://www.w3.org/TR/1999/REC-xpath-19991116", "System.Security.Cryptography.Xml.XmlDsigXPathTransform, " + AssemblyRef.SystemSecurity);
395                     ht.Add("http://www.w3.org/TR/1999/REC-xslt-19991116", "System.Security.Cryptography.Xml.XmlDsigXsltTransform, " + AssemblyRef.SystemSecurity);
396                     ht.Add("http://www.w3.org/2000/09/xmldsig#enveloped-signature", "System.Security.Cryptography.Xml.XmlDsigEnvelopedSignatureTransform, " + AssemblyRef.SystemSecurity);
397
398                     // the decryption transform
399                     ht.Add("http://www.w3.org/2002/07/decrypt#XML", "System.Security.Cryptography.Xml.XmlDecryptionTransform, " + AssemblyRef.SystemSecurity);
400
401                     // Xml licence transform.
402                     ht.Add("urn:mpeg:mpeg21:2003:01-REL-R-NS:licenseTransform", "System.Security.Cryptography.Xml.XmlLicenseTransform, " + AssemblyRef.SystemSecurity);
403
404                     // Xml Dsig KeyInfo
405                     // First arg (the key) is formed as elem.NamespaceURI + " " + elem.LocalName
406                     ht.Add("http://www.w3.org/2000/09/xmldsig# X509Data", "System.Security.Cryptography.Xml.KeyInfoX509Data, " + AssemblyRef.SystemSecurity);
407                     ht.Add("http://www.w3.org/2000/09/xmldsig# KeyName", "System.Security.Cryptography.Xml.KeyInfoName, " + AssemblyRef.SystemSecurity);
408                     ht.Add("http://www.w3.org/2000/09/xmldsig# KeyValue/DSAKeyValue", "System.Security.Cryptography.Xml.DSAKeyValue, " + AssemblyRef.SystemSecurity);
409                     ht.Add("http://www.w3.org/2000/09/xmldsig# KeyValue/RSAKeyValue", "System.Security.Cryptography.Xml.RSAKeyValue, " + AssemblyRef.SystemSecurity);
410                     ht.Add("http://www.w3.org/2000/09/xmldsig# RetrievalMethod", "System.Security.Cryptography.Xml.KeyInfoRetrievalMethod, " + AssemblyRef.SystemSecurity);
411
412                     // Xml EncryptedKey
413                     ht.Add("http://www.w3.org/2001/04/xmlenc# EncryptedKey", "System.Security.Cryptography.Xml.KeyInfoEncryptedKey, " + AssemblyRef.SystemSecurity);
414
415 #endif //FEATURE_CRYPTO
416 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
417                     // Xml Dsig HMAC URIs from http://www.w3.org/TR/xmldsig-core/
418                     ht.Add("http://www.w3.org/2000/09/xmldsig#hmac-sha1", HMACSHA1Type);
419 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
420 #if FEATURE_CRYPTO
421
422                     // Xml Dsig-more Uri's as defined in http://www.ietf.org/rfc/rfc4051.txt
423                     ht.Add("http://www.w3.org/2001/04/xmldsig-more#md5", MD5CryptoServiceProviderType);
424                     ht.Add("http://www.w3.org/2001/04/xmldsig-more#sha384", SHA384ManagedType);
425                     ht.Add("http://www.w3.org/2001/04/xmldsig-more#hmac-md5", HMACMD5Type);
426                     ht.Add("http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160", HMACRIPEMD160Type);
427 #endif //FEATURE_CRYPTO
428 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
429                     ht.Add("http://www.w3.org/2001/04/xmldsig-more#hmac-sha256", HMACSHA256Type);
430 #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
431 #if FEATURE_CRYPTO
432                     ht.Add("http://www.w3.org/2001/04/xmldsig-more#hmac-sha384", HMACSHA384Type);
433                     ht.Add("http://www.w3.org/2001/04/xmldsig-more#hmac-sha512", HMACSHA512Type);
434                     // X509 Extensions (custom decoders)
435                     // Basic Constraints OID value
436                     ht.Add("2.5.29.10", "System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension, " + AssemblyRef.System);
437                     ht.Add("2.5.29.19", "System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension, " + AssemblyRef.System);
438                     // Subject Key Identifier OID value
439                     ht.Add("2.5.29.14", "System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierExtension, " + AssemblyRef.System);
440                     // Key Usage OID value
441                     ht.Add("2.5.29.15", "System.Security.Cryptography.X509Certificates.X509KeyUsageExtension, " + AssemblyRef.System);
442                     // Enhanced Key Usage OID value
443                     ht.Add("2.5.29.37", "System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension, " + AssemblyRef.System);
444
445                     // X509Chain class can be overridden to use a different chain engine.
446                     ht.Add("X509Chain", "System.Security.Cryptography.X509Certificates.X509Chain, " + AssemblyRef.System);
447
448                     // PKCS9 attributes
449                     ht.Add("1.2.840.113549.1.9.3", "System.Security.Cryptography.Pkcs.Pkcs9ContentType, " + AssemblyRef.SystemSecurity);
450                     ht.Add("1.2.840.113549.1.9.4", "System.Security.Cryptography.Pkcs.Pkcs9MessageDigest, " + AssemblyRef.SystemSecurity);
451                     ht.Add("1.2.840.113549.1.9.5", "System.Security.Cryptography.Pkcs.Pkcs9SigningTime, " + AssemblyRef.SystemSecurity);
452                     ht.Add("1.3.6.1.4.1.311.88.2.1", "System.Security.Cryptography.Pkcs.Pkcs9DocumentName, " + AssemblyRef.SystemSecurity);
453                     ht.Add("1.3.6.1.4.1.311.88.2.2", "System.Security.Cryptography.Pkcs.Pkcs9DocumentDescription, " + AssemblyRef.SystemSecurity);
454 #endif // FEATURE_CRYPTO
455
456                     defaultNameHT = ht;
457                 }
458                 return defaultNameHT;
459             }
460         }
461
462         [System.Security.SecurityCritical]  // auto-generated
463         [ResourceExposure(ResourceScope.None)]
464         [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
465         private static void InitializeConfigInfo()
466         {
467 #if FEATURE_CRYPTO && !FEATURE_CORECLR
468             if (machineNameHT == null)
469             {
470                 lock(InternalSyncObject)
471                 {
472                     if(machineNameHT == null)
473                     {
474                         ConfigNode cryptoConfig = OpenCryptoConfig();
475                         if (cryptoConfig != null)
476                         {
477                             foreach (ConfigNode node in cryptoConfig.Children)
478                             {
479                                 if (machineNameHT != null && machineOidHT != null)
480                                 {
481                                     break;
482                                 }
483                                 else if (machineNameHT == null &&
484                                     String.Compare(node.Name, "cryptoNameMapping", StringComparison.Ordinal) == 0)
485                                 {
486                                     machineNameHT = InitializeNameMappings(node);
487                                 }
488                                 else if (machineOidHT == null &&
489                                          String.Compare(node.Name, "oidMap", StringComparison.Ordinal) == 0)
490                                 {
491                                     machineOidHT = InitializeOidMappings(node);
492                                 }
493                             }
494                         }
495
496                         // if we couldn't access the config file, or it didn't contain our config section
497                         // just create empty tables so that we don't end up trying to read the file
498                         // on every access to InitializeConfigInfo()
499                         if (machineNameHT == null)
500                             machineNameHT = new Dictionary<string, string>();
501                         if (machineOidHT == null)
502                             machineOidHT = new Dictionary<string, string>();
503
504                     }
505                 }
506             }
507
508 #else
509             if (machineNameHT == null)
510                 machineNameHT = new Dictionary<string, string>();
511             if (machineOidHT == null)
512                 machineOidHT = new Dictionary<string, string>();
513
514 #endif //FEATURE_CRYPTO
515         }
516
517         /// <summary>
518         ///     Add a set of name -> algorithm mappings to be used for the current AppDomain.  These mappings
519         ///     take precidense over the built-in mappings and the mappings in machine.config.  This API is
520         ///     critical to prevent partial trust code from hooking trusted crypto operations.
521         /// </summary>
522         [SecurityCritical]
523         public static void AddAlgorithm(Type algorithm, params string[] names) {
524             if (algorithm == null)
525                 throw new ArgumentNullException("algorithm");
526             if (!algorithm.IsVisible)
527                 throw new ArgumentException(Environment.GetResourceString("Cryptography_AlgorithmTypesMustBeVisible"), "algorithm");
528             if (names == null)
529                 throw new ArgumentNullException("names");
530             Contract.EndContractBlock();
531
532             string[] algorithmNames = new string[names.Length];
533             Array.Copy(names, algorithmNames, algorithmNames.Length);
534
535             // Pre-check the algorithm names for validity so that we don't add a few of the names and then
536             // throw an exception if we find an invalid name partway through the list.
537             foreach (string name in algorithmNames) {
538                 if (String.IsNullOrEmpty(name)) {
539                     throw new ArgumentException(Environment.GetResourceString("Cryptography_AddNullOrEmptyName"));
540                 }
541             }
542
543             // Everything looks valid, so we're safe to take the table lock and add the name mappings.
544             lock (InternalSyncObject) {
545                 foreach (string name in algorithmNames) {
546                     appNameHT[name] = algorithm;
547                 }
548             }
549         }
550
551         [System.Security.SecuritySafeCritical]  // auto-generated
552         public static object CreateFromName (string name, params object[] args) {
553             if (name == null)
554                 throw new ArgumentNullException("name");
555             Contract.EndContractBlock();
556
557             Type retvalType = null;
558             Object retval;
559
560             // First we'll do the machine-wide stuff, initializing if necessary
561             InitializeConfigInfo();
562
563             // Check to see if we have an applicaiton defined mapping
564             lock (InternalSyncObject) {
565                 retvalType = appNameHT.GetValueOrDefault(name);
566             }
567
568             // If we don't have a application defined mapping, search the machine table
569             if (retvalType == null) {
570                 BCLDebug.Assert(machineNameHT != null, "machineNameHT != null");
571                 String retvalTypeString = machineNameHT.GetValueOrDefault(name);
572                 if (retvalTypeString != null) {
573                     retvalType = Type.GetType(retvalTypeString, false, false);
574                     if (retvalType != null && !retvalType.IsVisible) 
575                         retvalType = null;
576                 }
577             }
578
579             // If we didn't find it in the machine-wide table,  look in the default table
580             if (retvalType == null) {
581                 // We allow the default table to Types and Strings
582                 // Types get used for other stuff in mscorlib.dll
583                 // strings get used for delay-loaded stuff like System.Security.dll
584                 Object retvalObj  = DefaultNameHT.GetValueOrDefault(name);
585                 if (retvalObj != null) {
586                     if (retvalObj is Type) {
587                         retvalType = (Type) retvalObj;
588                     } else if (retvalObj is String) {
589                         retvalType = Type.GetType((String) retvalObj, false, false);
590                         if (retvalType != null && !retvalType.IsVisible) 
591                             retvalType = null;
592                     }
593                 }
594             }
595
596             // Maybe they gave us a classname.
597             if (retvalType == null) {
598                 retvalType = Type.GetType(name, false, false);
599                 if (retvalType != null && !retvalType.IsVisible) 
600                     retvalType = null;
601             }
602
603             // Still null? Then we didn't find it 
604             if (retvalType == null)
605                 return null;
606
607             // Perform a CreateInstance by hand so we can check that the
608             // constructor doesn't have a linktime demand attached (which would
609             // be incorrrectly applied against mscorlib otherwise).
610             RuntimeType rtType = retvalType as RuntimeType;
611             if (rtType == null)
612                 return null;
613             if (args == null)
614                 args = new Object[]{};
615
616             // Locate all constructors.
617             MethodBase[] cons = rtType.GetConstructors(Activator.ConstructorDefault);
618
619             if (cons == null)
620                 return null;
621
622             List<MethodBase> candidates = new List<MethodBase>();
623             for (int i = 0; i < cons.Length; i ++) {
624                 MethodBase con = cons[i];
625                 if (con.GetParameters().Length == args.Length) {
626                     candidates.Add(con);
627                 }
628             }
629
630             if (candidates.Count == 0) 
631                 return null;
632
633             cons = candidates.ToArray();
634
635             // Bind to matching ctor.
636             Object state;
637             RuntimeConstructorInfo rci = Type.DefaultBinder.BindToMethod(Activator.ConstructorDefault,
638                                                                          cons,
639                                                                          ref args,
640                                                                          null,
641                                                                          null,
642                                                                          null,
643                                                                          out state) as RuntimeConstructorInfo;
644
645             // Check for ctor we don't like (non-existant, delegate or decorated
646             // with declarative linktime demand).
647             if (rci == null || typeof(Delegate).IsAssignableFrom(rci.DeclaringType))
648                 return null;
649
650             // Ctor invoke (actually causes the allocation as well).
651             retval = rci.Invoke(Activator.ConstructorDefault, Type.DefaultBinder, args, null);
652
653             // Reset any parameter re-ordering performed by the binder.
654             if (state != null)
655                 Type.DefaultBinder.ReorderArgumentArray(ref args, state);
656
657             return retval;
658         }
659
660         public static object CreateFromName (string name) {
661             return CreateFromName(name, null);
662         }
663
664         /// <summary>
665         ///     Add a set of name -> OID mappings to be used for the current AppDomain.  These mappings
666         ///     take precidense over the built-in mappings and the mappings in machine.config.  This API is
667         ///     critical to prevent partial trust code from hooking trusted crypto operations.
668         /// </summary>
669         [SecurityCritical]
670         public static void AddOID(string oid, params string[] names) {
671             if (oid == null)
672                 throw new ArgumentNullException("oid");
673             if (names == null)
674                 throw new ArgumentNullException("names");
675             Contract.EndContractBlock();
676
677             string[] oidNames = new string[names.Length];
678             Array.Copy(names, oidNames, oidNames.Length);
679
680             // Pre-check the input names for validity, so that we don't add a few of the names and throw an
681             // exception if an invalid name is found further down the array. 
682             foreach (string name in oidNames) {
683                 if (String.IsNullOrEmpty(name)) {
684                     throw new ArgumentException(Environment.GetResourceString("Cryptography_AddNullOrEmptyName"));
685                 }
686             }
687
688             // Everything is valid, so we're good to lock the hash table and add the application mappings
689             lock (InternalSyncObject) {
690                 foreach (string name in oidNames) {
691                     appOidHT[name] = oid;
692                 }
693             }
694         }
695
696         public static string MapNameToOID (string name) {
697             return MapNameToOID(name, OidGroup.AllGroups);
698         }
699
700         [SecuritySafeCritical]
701         internal static string MapNameToOID(string name, OidGroup oidGroup) {
702             if (name == null) 
703                 throw new ArgumentNullException("name");
704             Contract.EndContractBlock();
705
706             // First we'll do the machine-wide stuff, initializing if necessary
707             InitializeConfigInfo();
708
709             string oid = null;
710
711             // Check to see if we have an application defined mapping
712             lock (InternalSyncObject) {
713                 oid = appOidHT.GetValueOrDefault(name);
714             }
715
716             // If we didn't find an application defined mapping, search the machine table
717             if (oid == null)
718                 oid = machineOidHT.GetValueOrDefault(name);
719
720             // If we didn't find it in the machine-wide table, look in the default table
721             if (oid == null)
722                 oid = DefaultOidHT.GetValueOrDefault(name);
723
724 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
725             // Try the CAPI table association
726             if (oid == null)
727                 oid = X509Utils.GetOidFromFriendlyName(name, oidGroup);
728 #endif // FEATURE_CRYPTO
729
730             return oid;
731         }
732
733         static public byte[] EncodeOID (string str) {
734             if (str == null) {
735                 throw new ArgumentNullException("str");
736             }
737             Contract.EndContractBlock();
738             char[] sepArray = { '.' }; // valid ASN.1 separators
739             String[] oidString = str.Split(sepArray);
740             uint[] oidNums = new uint[oidString.Length];
741             for (int i = 0; i < oidString.Length; i++) {
742                 oidNums[i] = (uint) Int32.Parse(oidString[i], CultureInfo.InvariantCulture);
743             }
744
745             // Allocate the array to receive encoded oidNums
746             byte[] encodedOidNums = new byte[oidNums.Length * 5]; // this is guaranteed to be longer than necessary
747             int encodedOidNumsIndex = 0;
748             // Handle the first two oidNums special
749             if (oidNums.Length < 2) {
750                 throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_InvalidOID"));
751             }
752             uint firstTwoOidNums = (oidNums[0] * 40) + oidNums[1];
753             byte[] retval = EncodeSingleOIDNum(firstTwoOidNums);
754             Array.Copy(retval, 0, encodedOidNums, encodedOidNumsIndex, retval.Length);
755             encodedOidNumsIndex += retval.Length;
756             for (int i = 2; i < oidNums.Length; i++) {
757                 retval = EncodeSingleOIDNum(oidNums[i]);
758                 Buffer.InternalBlockCopy(retval, 0, encodedOidNums, encodedOidNumsIndex, retval.Length);
759                 encodedOidNumsIndex += retval.Length;
760             }
761
762             // final return value is 06 <length> || encodedOidNums
763             if (encodedOidNumsIndex > 0x7f) {
764                 throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_Config_EncodedOIDError"));
765             }
766             retval = new byte[ encodedOidNumsIndex + 2];
767             retval[0] = (byte) 0x06;
768             retval[1] = (byte) encodedOidNumsIndex;
769             Buffer.InternalBlockCopy(encodedOidNums, 0, retval, 2, encodedOidNumsIndex);
770             return retval;
771         }
772
773         static private byte[] EncodeSingleOIDNum(uint dwValue) {
774             byte[] retval;
775
776             if ((int)dwValue < 0x80) {
777                 retval = new byte[1];
778                 retval[0] = (byte) dwValue;
779                 return retval;
780             }
781             else if (dwValue < 0x4000) {
782                 retval = new byte[2];
783                 retval[0]   = (byte) ((dwValue >> 7) | 0x80);
784                 retval[1] = (byte) (dwValue & 0x7f);
785                 return retval;
786             }
787             else if (dwValue < 0x200000) {
788                 retval = new byte[3];
789                 retval[0] = (byte) ((dwValue >> 14) | 0x80);
790                 retval[1] = (byte) ((dwValue >> 7) | 0x80);
791                 retval[2] = (byte) (dwValue & 0x7f);
792                 return retval;
793             }
794             else if (dwValue < 0x10000000) {
795                 retval = new byte[4];
796                 retval[0] = (byte) ((dwValue >> 21) | 0x80);
797                 retval[1] = (byte) ((dwValue >> 14) | 0x80);
798                 retval[2] = (byte) ((dwValue >> 7) | 0x80);
799                 retval[3] = (byte) (dwValue & 0x7f);
800                 return retval;
801             }
802             else {
803                 retval = new byte[5];
804                 retval[0] = (byte) ((dwValue >> 28) | 0x80);
805                 retval[1] = (byte) ((dwValue >> 21) | 0x80);
806                 retval[2] = (byte) ((dwValue >> 14) | 0x80);
807                 retval[3] = (byte) ((dwValue >> 7) | 0x80);
808                 retval[4] = (byte) (dwValue & 0x7f);
809                 return retval;
810             }
811         }
812
813         private static Dictionary<string, string> InitializeNameMappings(ConfigNode nameMappingNode)
814         {
815             Contract.Assert(nameMappingNode != null, "No name mappings");
816             Contract.Assert(String.Compare(nameMappingNode.Name, "cryptoNameMapping", StringComparison.Ordinal) == 0, "Invalid name mapping root");
817
818             Dictionary<string, string> nameMappings = new Dictionary<string, string>();
819             Dictionary<string, string> typeAliases = new Dictionary<string, string>();
820
821             // find the cryptoClases element
822             foreach (ConfigNode node in nameMappingNode.Children)
823             {
824                 if (String.Compare(node.Name, "cryptoClasses", StringComparison.Ordinal) == 0)
825                 {
826                     foreach(ConfigNode cryptoClass in node.Children)
827                     {
828                         if (String.Compare(cryptoClass.Name, "cryptoClass", StringComparison.Ordinal) == 0)
829                         {
830                             if (cryptoClass.Attributes.Count > 0)
831                             {
832                                 DictionaryEntry attribute = (DictionaryEntry)cryptoClass.Attributes[0];
833                                 typeAliases.Add((string)attribute.Key, (string)attribute.Value);
834                             }
835                         }
836                     }
837                 }
838                 else if(String.Compare(node.Name, "nameEntry", StringComparison.Ordinal) == 0)
839                 {
840                     string friendlyName = null;
841                     string className = null;
842
843                     foreach(DictionaryEntry attribute in node.Attributes)
844                     {
845                         if(String.Compare((string)attribute.Key, "name", StringComparison.Ordinal) == 0)
846                             friendlyName = (string)attribute.Value;
847                         else if(String.Compare((string)attribute.Key, "class", StringComparison.Ordinal) == 0)
848                             className = (string)attribute.Value;
849                     }
850
851                     if (friendlyName != null && className != null)
852                     {
853                         string typeName = typeAliases.GetValueOrDefault(className);
854                         if (typeName != null)
855                             nameMappings.Add(friendlyName, typeName);
856                     }
857                 }
858             }
859
860             return nameMappings;
861         }
862
863         private static Dictionary<string, string> InitializeOidMappings(ConfigNode oidMappingNode)
864         {
865             Contract.Assert(oidMappingNode != null, "No OID mappings");
866             Contract.Assert(String.Compare(oidMappingNode.Name, "oidMap", StringComparison.Ordinal) == 0, "Invalid OID mapping root");
867
868             Dictionary<string, string> oidMap = new Dictionary<string, string>();
869             foreach (ConfigNode node in oidMappingNode.Children)
870             {
871                 if (String.Compare(node.Name, "oidEntry", StringComparison.Ordinal) == 0)
872                 {
873                     string oidString = null;
874                     string friendlyName = null;
875
876                     foreach (DictionaryEntry attribute in node.Attributes)
877                     {
878                         if (String.Compare((string)attribute.Key, "OID", StringComparison.Ordinal) == 0)
879                             oidString = (string)attribute.Value;
880                         else if (String.Compare((string)attribute.Key, "name", StringComparison.Ordinal) == 0)
881                             friendlyName = (string)attribute.Value;
882                     }
883
884                     if ((friendlyName != null) && (oidString != null))
885                         oidMap.Add(friendlyName, oidString);
886                 }
887             }
888
889             return oidMap;
890         }
891
892         [System.Security.SecurityCritical]  // auto-generated
893         [ResourceExposure(ResourceScope.None)]
894         [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
895         private static ConfigNode OpenCryptoConfig()
896         {
897             string machineConfigFile = System.Security.Util.Config.MachineDirectory + MachineConfigFilename;
898             new FileIOPermission(FileIOPermissionAccess.Read, machineConfigFile).Assert();
899             if (!File.Exists(machineConfigFile))
900                 return null;
901             CodeAccessPermission.RevertAssert();
902
903             ConfigTreeParser parser = new ConfigTreeParser();
904             ConfigNode rootNode = parser.Parse(machineConfigFile, "configuration", true);
905             if (rootNode == null)
906                 return null;
907
908             // now, find the mscorlib tag with our version
909             ConfigNode mscorlibNode = null;
910             foreach (ConfigNode node in rootNode.Children)
911             {
912                 bool versionSpecificMscorlib = false;
913
914                 if (String.Compare(node.Name, "mscorlib", StringComparison.Ordinal) == 0)
915                 {
916                     foreach (DictionaryEntry attribute in node.Attributes)
917                     {
918                         if (String.Compare((string)attribute.Key, "version", StringComparison.Ordinal) == 0)
919                         {
920                             versionSpecificMscorlib = true;
921
922                             if (String.Compare((string)attribute.Value, Version, StringComparison.Ordinal) == 0)
923                             {
924                                 mscorlibNode = node;
925                                 break;
926                             }
927                         }
928                     }
929
930                     // if this mscorlib element did not have a version attribute, then use it
931                     if (!versionSpecificMscorlib)
932                         mscorlibNode = node;
933                 }
934
935                 // use the first matching mscorlib we find
936                 if (mscorlibNode != null)
937                     break;
938             }
939
940             if (mscorlibNode == null)
941                 return null;
942
943             // now look for the first crypto settings element
944             foreach (ConfigNode node in mscorlibNode.Children)
945             {
946                 if (String.Compare(node.Name, "cryptographySettings", StringComparison.Ordinal) == 0)
947                     return node;
948             }
949
950             return null;
951         }
952     }
953 }