3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>[....]</OWNER>
13 namespace System.Security.Cryptography {
15 using System.Collections;
16 using System.Collections.Generic;
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;
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);
36 private const string MachineConfigFilename = "machine.config";
38 private static volatile string version = null;
41 private static volatile bool s_fipsAlgorithmPolicy;
42 private static volatile bool s_haveFipsAlgorithmPolicy;
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.
48 public static bool AllowOnlyFipsAlgorithms {
49 [System.Security.SecuritySafeCritical] // auto-generated
50 [ResourceExposure(ResourceScope.None)]
51 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
53 if (!s_haveFipsAlgorithmPolicy)
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.
61 if (Utils._GetEnforceFipsPolicySetting()) {
62 if (Environment.OSVersion.Version.Major >= 6) {
64 uint policyReadStatus = Win32Native.BCryptGetFipsAlgorithmMode(out fipsEnabled);
66 bool readPolicy = policyReadStatus == Win32Native.STATUS_SUCCESS ||
67 policyReadStatus == Win32Native.STATUS_OBJECT_NAME_NOT_FOUND;
69 s_fipsAlgorithmPolicy = !readPolicy || fipsEnabled;
70 s_haveFipsAlgorithmPolicy = true;
73 s_fipsAlgorithmPolicy = Utils.ReadLegacyFipsPolicy();
74 s_haveFipsAlgorithmPolicy = true;
78 #endif // !FEATURE_CORECLR
80 s_fipsAlgorithmPolicy = false;
81 s_haveFipsAlgorithmPolicy = true;
85 return s_fipsAlgorithmPolicy;
88 #endif // FEATURE_CRYPTO
90 private static string Version
92 [System.Security.SecurityCritical] // auto-generated
96 version = ((RuntimeType)typeof(CryptoConfig)).GetRuntimeAssembly().GetVersion().ToString();
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 {
106 if (s_InternalSyncObject == null) {
107 Object o = new Object();
108 Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
110 return s_InternalSyncObject;
114 private static Dictionary<string, string> DefaultOidHT {
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
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
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
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
170 private static Dictionary<string, object> DefaultNameHT {
172 if (defaultNameHT == null) {
173 Dictionary<string, object> ht = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
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
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
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
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
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
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;
237 // Cryptography algorithms in System.Security
238 string DpapiDataProtectorType = "System.Security.Cryptography.DpapiDataProtector, " + AssemblyRef.SystemSecurity;
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
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
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);
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
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
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);
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);
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
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
352 ht.Add("DpapiDataProtector", DpapiDataProtectorType);
353 ht.Add("System.Security.Cryptography.DpapiDataProtector", DpapiDataProtectorType);
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);
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);
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
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);
398 // the decryption transform
399 ht.Add("http://www.w3.org/2002/07/decrypt#XML", "System.Security.Cryptography.Xml.XmlDecryptionTransform, " + AssemblyRef.SystemSecurity);
401 // Xml licence transform.
402 ht.Add("urn:mpeg:mpeg21:2003:01-REL-R-NS:licenseTransform", "System.Security.Cryptography.Xml.XmlLicenseTransform, " + AssemblyRef.SystemSecurity);
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);
413 ht.Add("http://www.w3.org/2001/04/xmlenc# EncryptedKey", "System.Security.Cryptography.Xml.KeyInfoEncryptedKey, " + AssemblyRef.SystemSecurity);
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
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
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);
445 // X509Chain class can be overridden to use a different chain engine.
446 ht.Add("X509Chain", "System.Security.Cryptography.X509Certificates.X509Chain, " + AssemblyRef.System);
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
458 return defaultNameHT;
462 [System.Security.SecurityCritical] // auto-generated
463 [ResourceExposure(ResourceScope.None)]
464 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
465 private static void InitializeConfigInfo()
467 #if FEATURE_CRYPTO && !FEATURE_CORECLR
468 if (machineNameHT == null)
470 lock(InternalSyncObject)
472 if(machineNameHT == null)
474 ConfigNode cryptoConfig = OpenCryptoConfig();
475 if (cryptoConfig != null)
477 foreach (ConfigNode node in cryptoConfig.Children)
479 if (machineNameHT != null && machineOidHT != null)
483 else if (machineNameHT == null &&
484 String.Compare(node.Name, "cryptoNameMapping", StringComparison.Ordinal) == 0)
486 machineNameHT = InitializeNameMappings(node);
488 else if (machineOidHT == null &&
489 String.Compare(node.Name, "oidMap", StringComparison.Ordinal) == 0)
491 machineOidHT = InitializeOidMappings(node);
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>();
509 if (machineNameHT == null)
510 machineNameHT = new Dictionary<string, string>();
511 if (machineOidHT == null)
512 machineOidHT = new Dictionary<string, string>();
514 #endif //FEATURE_CRYPTO
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.
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");
529 throw new ArgumentNullException("names");
530 Contract.EndContractBlock();
532 string[] algorithmNames = new string[names.Length];
533 Array.Copy(names, algorithmNames, algorithmNames.Length);
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"));
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;
551 [System.Security.SecuritySafeCritical] // auto-generated
552 public static object CreateFromName (string name, params object[] args) {
554 throw new ArgumentNullException("name");
555 Contract.EndContractBlock();
557 Type retvalType = null;
560 // First we'll do the machine-wide stuff, initializing if necessary
561 InitializeConfigInfo();
563 // Check to see if we have an applicaiton defined mapping
564 lock (InternalSyncObject) {
565 retvalType = appNameHT.GetValueOrDefault(name);
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)
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)
596 // Maybe they gave us a classname.
597 if (retvalType == null) {
598 retvalType = Type.GetType(name, false, false);
599 if (retvalType != null && !retvalType.IsVisible)
603 // Still null? Then we didn't find it
604 if (retvalType == null)
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;
614 args = new Object[]{};
616 // Locate all constructors.
617 MethodBase[] cons = rtType.GetConstructors(Activator.ConstructorDefault);
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) {
630 if (candidates.Count == 0)
633 cons = candidates.ToArray();
635 // Bind to matching ctor.
637 RuntimeConstructorInfo rci = Type.DefaultBinder.BindToMethod(Activator.ConstructorDefault,
643 out state) as RuntimeConstructorInfo;
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))
650 // Ctor invoke (actually causes the allocation as well).
651 retval = rci.Invoke(Activator.ConstructorDefault, Type.DefaultBinder, args, null);
653 // Reset any parameter re-ordering performed by the binder.
655 Type.DefaultBinder.ReorderArgumentArray(ref args, state);
660 public static object CreateFromName (string name) {
661 return CreateFromName(name, null);
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.
670 public static void AddOID(string oid, params string[] names) {
672 throw new ArgumentNullException("oid");
674 throw new ArgumentNullException("names");
675 Contract.EndContractBlock();
677 string[] oidNames = new string[names.Length];
678 Array.Copy(names, oidNames, oidNames.Length);
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"));
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;
696 public static string MapNameToOID (string name) {
697 return MapNameToOID(name, OidGroup.AllGroups);
700 [SecuritySafeCritical]
701 internal static string MapNameToOID(string name, OidGroup oidGroup) {
703 throw new ArgumentNullException("name");
704 Contract.EndContractBlock();
706 // First we'll do the machine-wide stuff, initializing if necessary
707 InitializeConfigInfo();
711 // Check to see if we have an application defined mapping
712 lock (InternalSyncObject) {
713 oid = appOidHT.GetValueOrDefault(name);
716 // If we didn't find an application defined mapping, search the machine table
718 oid = machineOidHT.GetValueOrDefault(name);
720 // If we didn't find it in the machine-wide table, look in the default table
722 oid = DefaultOidHT.GetValueOrDefault(name);
724 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
725 // Try the CAPI table association
727 oid = X509Utils.GetOidFromFriendlyName(name, oidGroup);
728 #endif // FEATURE_CRYPTO
733 static public byte[] EncodeOID (string str) {
735 throw new ArgumentNullException("str");
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);
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"));
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;
762 // final return value is 06 <length> || encodedOidNums
763 if (encodedOidNumsIndex > 0x7f) {
764 throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_Config_EncodedOIDError"));
766 retval = new byte[ encodedOidNumsIndex + 2];
767 retval[0] = (byte) 0x06;
768 retval[1] = (byte) encodedOidNumsIndex;
769 Buffer.InternalBlockCopy(encodedOidNums, 0, retval, 2, encodedOidNumsIndex);
773 static private byte[] EncodeSingleOIDNum(uint dwValue) {
776 if ((int)dwValue < 0x80) {
777 retval = new byte[1];
778 retval[0] = (byte) dwValue;
781 else if (dwValue < 0x4000) {
782 retval = new byte[2];
783 retval[0] = (byte) ((dwValue >> 7) | 0x80);
784 retval[1] = (byte) (dwValue & 0x7f);
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);
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);
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);
813 private static Dictionary<string, string> InitializeNameMappings(ConfigNode nameMappingNode)
815 Contract.Assert(nameMappingNode != null, "No name mappings");
816 Contract.Assert(String.Compare(nameMappingNode.Name, "cryptoNameMapping", StringComparison.Ordinal) == 0, "Invalid name mapping root");
818 Dictionary<string, string> nameMappings = new Dictionary<string, string>();
819 Dictionary<string, string> typeAliases = new Dictionary<string, string>();
821 // find the cryptoClases element
822 foreach (ConfigNode node in nameMappingNode.Children)
824 if (String.Compare(node.Name, "cryptoClasses", StringComparison.Ordinal) == 0)
826 foreach(ConfigNode cryptoClass in node.Children)
828 if (String.Compare(cryptoClass.Name, "cryptoClass", StringComparison.Ordinal) == 0)
830 if (cryptoClass.Attributes.Count > 0)
832 DictionaryEntry attribute = (DictionaryEntry)cryptoClass.Attributes[0];
833 typeAliases.Add((string)attribute.Key, (string)attribute.Value);
838 else if(String.Compare(node.Name, "nameEntry", StringComparison.Ordinal) == 0)
840 string friendlyName = null;
841 string className = null;
843 foreach(DictionaryEntry attribute in node.Attributes)
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;
851 if (friendlyName != null && className != null)
853 string typeName = typeAliases.GetValueOrDefault(className);
854 if (typeName != null)
855 nameMappings.Add(friendlyName, typeName);
863 private static Dictionary<string, string> InitializeOidMappings(ConfigNode oidMappingNode)
865 Contract.Assert(oidMappingNode != null, "No OID mappings");
866 Contract.Assert(String.Compare(oidMappingNode.Name, "oidMap", StringComparison.Ordinal) == 0, "Invalid OID mapping root");
868 Dictionary<string, string> oidMap = new Dictionary<string, string>();
869 foreach (ConfigNode node in oidMappingNode.Children)
871 if (String.Compare(node.Name, "oidEntry", StringComparison.Ordinal) == 0)
873 string oidString = null;
874 string friendlyName = null;
876 foreach (DictionaryEntry attribute in node.Attributes)
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;
884 if ((friendlyName != null) && (oidString != null))
885 oidMap.Add(friendlyName, oidString);
892 [System.Security.SecurityCritical] // auto-generated
893 [ResourceExposure(ResourceScope.None)]
894 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
895 private static ConfigNode OpenCryptoConfig()
897 string machineConfigFile = System.Security.Util.Config.MachineDirectory + MachineConfigFilename;
898 new FileIOPermission(FileIOPermissionAccess.Read, machineConfigFile).Assert();
899 if (!File.Exists(machineConfigFile))
901 CodeAccessPermission.RevertAssert();
903 ConfigTreeParser parser = new ConfigTreeParser();
904 ConfigNode rootNode = parser.Parse(machineConfigFile, "configuration", true);
905 if (rootNode == null)
908 // now, find the mscorlib tag with our version
909 ConfigNode mscorlibNode = null;
910 foreach (ConfigNode node in rootNode.Children)
912 bool versionSpecificMscorlib = false;
914 if (String.Compare(node.Name, "mscorlib", StringComparison.Ordinal) == 0)
916 foreach (DictionaryEntry attribute in node.Attributes)
918 if (String.Compare((string)attribute.Key, "version", StringComparison.Ordinal) == 0)
920 versionSpecificMscorlib = true;
922 if (String.Compare((string)attribute.Value, Version, StringComparison.Ordinal) == 0)
930 // if this mscorlib element did not have a version attribute, then use it
931 if (!versionSpecificMscorlib)
935 // use the first matching mscorlib we find
936 if (mscorlibNode != null)
940 if (mscorlibNode == null)
943 // now look for the first crypto settings element
944 foreach (ConfigNode node in mscorlibNode.Children)
946 if (String.Compare(node.Name, "cryptographySettings", StringComparison.Ordinal) == 0)