2 // CryptoConfig.cs: Handles cryptographic implementations and OIDs mappings.
5 // Sebastien Pouliot (sebastien@ximian.com)
6 // Tim Coleman (tim@timcoleman.com)
8 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
9 // Copyright (C) Tim Coleman, 2004
10 // Copyright (C) 2004-2007,2011 Novell, Inc (http://www.novell.com)
11 // Copyright (C) 2011 Xamarin Inc. http://www.xamarin.com
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System.Collections;
36 using System.Collections.Generic;
37 using System.Globalization;
39 using System.Reflection;
40 using System.Runtime.CompilerServices;
41 using System.Runtime.InteropServices;
42 using System.Security.Permissions;
47 namespace System.Security.Cryptography {
50 public partial class CryptoConfig {
52 static private object lockObject;
53 static private Dictionary<string,Type> algorithms;
54 static private Dictionary<string,string> unresolved_algorithms;
55 static private Dictionary<string,string> oids;
57 private const string defaultNamespace = "System.Security.Cryptography.";
58 static Type defaultSHA1 = typeof (SHA1CryptoServiceProvider);
59 static Type defaultMD5 = typeof (MD5CryptoServiceProvider);
60 static Type defaultSHA256 = typeof (SHA256Managed);
61 static Type defaultSHA384 = typeof (SHA384Managed);
62 static Type defaultSHA512 = typeof (SHA512Managed);
63 static Type defaultRSA = typeof (RSACryptoServiceProvider);
64 static Type defaultDSA = typeof (DSACryptoServiceProvider);
65 static Type defaultDES = typeof (DESCryptoServiceProvider);
66 static Type default3DES = typeof (TripleDESCryptoServiceProvider);
67 static Type defaultRC2 = typeof (RC2CryptoServiceProvider);
68 static Type defaultAES = typeof (RijndaelManaged);
69 // LAMESPEC: undocumented names in CryptoConfig
70 static Type defaultRNG = typeof (RNGCryptoServiceProvider);
71 static Type defaultHMAC = typeof (HMACSHA1);
72 static Type defaultMAC3DES = typeof (MACTripleDES);
73 // LAMESPEC: undocumented classes (also undocumented in CryptoConfig ;-)
74 static Type defaultDSASigDesc = typeof (DSASignatureDescription);
75 static Type defaultRSASigDesc = typeof (RSAPKCS1SHA1SignatureDescription);
76 static Type defaultRIPEMD160 = typeof (RIPEMD160Managed);
77 static Type defaultHMACMD5 = typeof (HMACMD5);
78 static Type defaultHMACRIPEMD160 = typeof (HMACRIPEMD160);
79 static Type defaultHMACSHA256 = typeof (HMACSHA256);
80 static Type defaultHMACSHA384 = typeof (HMACSHA384);
81 static Type defaultHMACSHA512 = typeof (HMACSHA512);
83 // LAMESPEC: undocumented names in CryptoConfig
84 private const string defaultC14N = defaultNamespace + "Xml.XmlDsigC14NTransform, " + Consts.AssemblySystem_Security;
85 private const string defaultC14NWithComments = defaultNamespace + "Xml.XmlDsigC14NWithCommentsTransform, " + Consts.AssemblySystem_Security;
86 private const string defaultBase64 = defaultNamespace + "Xml.XmlDsigBase64Transform, " + Consts.AssemblySystem_Security;
87 private const string defaultXPath = defaultNamespace + "Xml.XmlDsigXPathTransform, " + Consts.AssemblySystem_Security;
88 private const string defaultXslt = defaultNamespace + "Xml.XmlDsigXsltTransform, " + Consts.AssemblySystem_Security;
89 private const string defaultEnveloped = defaultNamespace + "Xml.XmlDsigEnvelopedSignatureTransform, " + Consts.AssemblySystem_Security;
90 private const string defaultXmlDecryption = defaultNamespace + "Xml.XmlDecryptionTransform, " + Consts.AssemblySystem_Security;
91 private const string defaultExcC14N = defaultNamespace + "Xml.XmlDsigExcC14NTransform, " + Consts.AssemblySystem_Security;
92 private const string defaultExcC14NWithComments = defaultNamespace + "Xml.XmlDsigExcC14NWithCommentsTransform, " + Consts.AssemblySystem_Security;
94 // LAMESPEC: only documentated in ".NET Framework Security" book
95 private const string defaultX509Data = defaultNamespace + "Xml.KeyInfoX509Data, " + Consts.AssemblySystem_Security;
96 private const string defaultKeyName = defaultNamespace + "Xml.KeyInfoName, " + Consts.AssemblySystem_Security;
97 private const string defaultKeyValueDSA = defaultNamespace + "Xml.DSAKeyValue, " + Consts.AssemblySystem_Security;
98 private const string defaultKeyValueRSA = defaultNamespace + "Xml.RSAKeyValue, " + Consts.AssemblySystem_Security;
99 private const string defaultRetrievalMethod = defaultNamespace + "Xml.KeyInfoRetrievalMethod, " + Consts.AssemblySystem_Security;
101 private const string managedSHA1 = defaultNamespace + "SHA1Managed";
103 // Oddly OID seems only available for hash algorithms
104 private const string oidSHA1 = "1.3.14.3.2.26";
105 private const string oidMD5 = "1.2.840.113549.2.5";
107 private const string oidSHA256 = "2.16.840.1.101.3.4.2.1";
108 private const string oidSHA384 = "2.16.840.1.101.3.4.2.2";
109 private const string oidSHA512 = "2.16.840.1.101.3.4.2.3";
110 private const string oidRIPEMD160 = "1.3.36.3.2.1";
112 // private const string oidRSA = "1.2.840.113549.1.1.1";
113 // private const string oidDSA = "1.2.840.10040.4.1";
114 private const string oidDES = "1.3.14.3.2.7";
115 private const string oid3DES = "1.2.840.113549.3.7";
116 private const string oidRC2 = "1.2.840.113549.3.2";
117 // LAMESPEC: only documentated in ".NET Framework Security" book
118 private const string oid3DESKeyWrap = "1.2.840.113549.1.9.16.3.6";
120 private const string nameSHA1 = "System.Security.Cryptography.SHA1CryptoServiceProvider";
121 private const string nameSHA1a = "SHA";
122 private const string nameSHA1b = "SHA1";
123 private const string nameSHA1c = "System.Security.Cryptography.SHA1";
124 private const string nameSHA1d = "System.Security.Cryptography.HashAlgorithm";
125 private const string nameMD5 = "System.Security.Cryptography.MD5CryptoServiceProvider";
126 private const string nameMD5a = "MD5";
127 private const string nameMD5b = "System.Security.Cryptography.MD5";
128 private const string nameSHA256 = "System.Security.Cryptography.SHA256Managed";
129 private const string nameSHA256a = "SHA256";
130 private const string nameSHA256b = "SHA-256";
131 private const string nameSHA256c = "System.Security.Cryptography.SHA256";
132 private const string nameSHA384 = "System.Security.Cryptography.SHA384Managed";
133 private const string nameSHA384a = "SHA384";
134 private const string nameSHA384b = "SHA-384";
135 private const string nameSHA384c = "System.Security.Cryptography.SHA384";
136 private const string nameSHA512 = "System.Security.Cryptography.SHA512Managed";
137 private const string nameSHA512a = "SHA512";
138 private const string nameSHA512b = "SHA-512";
139 private const string nameSHA512c = "System.Security.Cryptography.SHA512";
140 private const string nameRSAa = "RSA";
141 private const string nameRSAb = "System.Security.Cryptography.RSA";
142 private const string nameRSAc = "System.Security.Cryptography.AsymmetricAlgorithm";
143 private const string nameDSAa = "DSA";
144 private const string nameDSAb = "System.Security.Cryptography.DSA";
145 private const string nameDESa = "DES";
146 private const string nameDESb = "System.Security.Cryptography.DES";
147 private const string name3DESa = "3DES";
148 private const string name3DESb = "TripleDES";
149 private const string name3DESc = "Triple DES";
150 private const string name3DESd = "System.Security.Cryptography.TripleDES";
151 private const string nameRC2a = "RC2";
152 private const string nameRC2b = "System.Security.Cryptography.RC2";
153 private const string nameAESa = "Rijndael";
154 private const string nameAESb = "System.Security.Cryptography.Rijndael";
155 private const string nameAESc = "System.Security.Cryptography.SymmetricAlgorithm";
156 // LAMESPEC: undocumented names in CryptoConfig
157 private const string nameRNGa = "RandomNumberGenerator";
158 private const string nameRNGb = "System.Security.Cryptography.RandomNumberGenerator";
159 private const string nameKeyHasha = "System.Security.Cryptography.KeyedHashAlgorithm";
160 private const string nameHMACSHA1a = "HMACSHA1";
161 private const string nameHMACSHA1b = "System.Security.Cryptography.HMACSHA1";
162 private const string nameMAC3DESa = "MACTripleDES";
163 private const string nameMAC3DESb = "System.Security.Cryptography.MACTripleDES";
164 // LAMESPEC: only documentated in ".NET Framework Security" book
165 private const string name3DESKeyWrap = "TripleDESKeyWrap";
166 private const string nameRIPEMD160 = "System.Security.Cryptography.RIPEMD160Managed";
167 private const string nameRIPEMD160a = "RIPEMD160";
168 private const string nameRIPEMD160b = "RIPEMD-160";
169 private const string nameRIPEMD160c = "System.Security.Cryptography.RIPEMD160";
170 // private const string nameHMACa = "HMAC";
171 private const string nameHMACb = "System.Security.Cryptography.HMAC";
172 private const string nameHMACMD5a = "HMACMD5";
173 private const string nameHMACMD5b = "System.Security.Cryptography.HMACMD5";
174 private const string nameHMACRIPEMD160a = "HMACRIPEMD160";
175 private const string nameHMACRIPEMD160b = "System.Security.Cryptography.HMACRIPEMD160";
176 private const string nameHMACSHA256a = "HMACSHA256";
177 private const string nameHMACSHA256b = "System.Security.Cryptography.HMACSHA256";
178 private const string nameHMACSHA384a = "HMACSHA384";
179 private const string nameHMACSHA384b = "System.Security.Cryptography.HMACSHA384";
180 private const string nameHMACSHA512a = "HMACSHA512";
181 private const string nameHMACSHA512b = "System.Security.Cryptography.HMACSHA512";
183 private const string urlXmlDsig = "http://www.w3.org/2000/09/xmldsig#";
184 // LAMESPEC: undocumented URLs in CryptoConfig
185 private const string urlDSASHA1 = urlXmlDsig + "dsa-sha1"; // no space
186 private const string urlRSASHA1 = urlXmlDsig + "rsa-sha1"; // no space
187 private const string urlSHA1 = urlXmlDsig + "sha1"; // no space
188 private const string urlC14N = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
189 private const string urlC14NWithComments = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments";
190 private const string urlBase64 = "http://www.w3.org/2000/09/xmldsig#base64";
191 private const string urlXPath = "http://www.w3.org/TR/1999/REC-xpath-19991116";
192 private const string urlXslt = "http://www.w3.org/TR/1999/REC-xslt-19991116";
193 private const string urlEnveloped = urlXmlDsig + "enveloped-signature"; // no space
194 private const string urlXmlDecryption = "http://www.w3.org/2002/07/decrypt#XML";
195 private const string urlExcC14NWithComments = "http://www.w3.org/2001/10/xml-exc-c14n#WithComments";
196 private const string urlExcC14N = "http://www.w3.org/2001/10/xml-exc-c14n#";
197 private const string urlSHA256 = "http://www.w3.org/2001/04/xmlenc#sha256";
198 private const string urlSHA512 = "http://www.w3.org/2001/04/xmlenc#sha512";
199 private const string urlHMACSHA256 = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256";
200 private const string urlHMACSHA384 = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha384";
201 private const string urlHMACSHA512 = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha512";
202 private const string urlHMACRIPEMD160 = "http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160";
204 // LAMESPEC: only documentated in ".NET Framework Security" book
205 private const string urlX509Data = urlXmlDsig + " X509Data"; // space is required
206 private const string urlKeyName = urlXmlDsig + " KeyName"; // space is required
207 private const string urlKeyValueDSA = urlXmlDsig + " KeyValue/DSAKeyValue"; // space is required
208 private const string urlKeyValueRSA = urlXmlDsig + " KeyValue/RSAKeyValue"; // space is required
209 private const string urlRetrievalMethod = urlXmlDsig + " RetrievalMethod"; // space is required
211 // new (2.0) X509 certificate extensions
212 private const string oidX509SubjectKeyIdentifier = "2.5.29.14";
213 private const string oidX509KeyUsage = "2.5.29.15";
214 private const string oidX509BasicConstraints = "2.5.29.19";
215 private const string oidX509EnhancedKeyUsage = "2.5.29.37";
217 private const string nameX509SubjectKeyIdentifier = defaultNamespace + "X509Certificates.X509SubjectKeyIdentifierExtension, " + Consts.AssemblySystem;
218 private const string nameX509KeyUsage = defaultNamespace + "X509Certificates.X509KeyUsageExtension, " + Consts.AssemblySystem;
219 private const string nameX509BasicConstraints = defaultNamespace + "X509Certificates.X509BasicConstraintsExtension, " + Consts.AssemblySystem;
220 private const string nameX509EnhancedKeyUsage = defaultNamespace + "X509Certificates.X509EnhancedKeyUsageExtension, " + Consts.AssemblySystem;
222 // new (2.0) X509 Chain
223 private const string nameX509Chain = "X509Chain";
224 private const string defaultX509Chain = defaultNamespace + "X509Certificates.X509Chain, " + Consts.AssemblySystem;
227 const string system_core_assembly = ", System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
228 const string nameAES_1 = "AES";
229 const string nameAES_2 = "System.Security.Cryptography.AesCryptoServiceProvider";
230 const string defaultAES_1 = "System.Security.Cryptography.AesCryptoServiceProvider" + system_core_assembly;
232 const string nameAESManaged_1 = "AesManaged";
233 const string nameAESManaged_2 = "System.Security.Cryptography.AesManaged";
234 const string defaultAESManaged = "System.Security.Cryptography.AesManaged" + system_core_assembly;
236 // ECDiffieHellman - not implemented in System.Core at the moment
237 const string nameECDiffieHellman_1 = "ECDH";
238 const string nameECDiffieHellman_2 = "ECDiffieHellman";
239 const string nameECDiffieHellman_3 = "ECDiffieHellmanCng";
240 const string nameECDiffieHellman_4 = "System.Security.Cryptography.ECDiffieHellmanCng";
241 const string defaultECDiffieHellman = "System.Security.Cryptography.ECDiffieHellmanCng" + system_core_assembly;
243 // ECDsa - not implemented in System.Core at the moment
244 const string nameECDsa_1 = "ECDsa";
245 const string nameECDsa_2 = "ECDsaCng";
246 const string nameECDsa_3 = "System.Security.Cryptography.ECDsaCng";
247 const string defaultECDsa = "System.Security.Cryptography.ECDsaCng" + system_core_assembly;
250 const string nameSHA1Cng = "System.Security.Cryptography.SHA1Cng";
251 const string defaultSHA1Cng = "System.Security.Cryptography.SHA1Cng" + system_core_assembly;
254 const string nameSHA256Cng = "System.Security.Cryptography.SHA256Cng";
255 const string defaultSHA256Cng = "System.Security.Cryptography.SHA256Cng" + system_core_assembly;
258 const string nameSHA256Provider = "System.Security.Cryptography.SHA256CryptoServiceProvider";
259 const string defaultSHA256Provider = "System.Security.Cryptography.SHA256CryptoServiceProvider" + system_core_assembly;
262 const string nameSHA384Cng = "System.Security.Cryptography.SHA384Cng";
263 const string defaultSHA384Cng = "System.Security.Cryptography.SHA384Cng" + system_core_assembly;
266 const string nameSHA384Provider = "System.Security.Cryptography.SHA384CryptoServiceProvider";
267 const string defaultSHA384Provider = "System.Security.Cryptography.SHA384CryptoServiceProvider" + system_core_assembly;
270 const string nameSHA512Cng = "System.Security.Cryptography.SHA512Cng";
271 const string defaultSHA512Cng = "System.Security.Cryptography.SHA512Cng" + system_core_assembly;
274 const string nameSHA512Provider = "System.Security.Cryptography.SHA512CryptoServiceProvider";
275 const string defaultSHA512Provider = "System.Security.Cryptography.SHA512CryptoServiceProvider" + system_core_assembly;
277 static CryptoConfig ()
280 // http://msdn.microsoft.com/library/en-us/dnaskdr/html/askgui06032003.asp?frame=true
281 lockObject = new object ();
284 private static void Initialize ()
286 Dictionary<string,Type> algorithms = new Dictionary<string, Type> (StringComparer.OrdinalIgnoreCase);
287 // see list @ http://msdn.microsoft.com/library/en-us/cpref/html/
288 // frlrfSystemSecurityCryptographyCryptoConfigClassTopic.asp
289 algorithms.Add (nameSHA1a, defaultSHA1);
290 algorithms.Add (nameSHA1b, defaultSHA1);
291 algorithms.Add (nameSHA1c, defaultSHA1);
292 algorithms.Add (nameSHA1d, defaultSHA1);
294 algorithms.Add (nameMD5a, defaultMD5);
295 algorithms.Add (nameMD5b, defaultMD5);
297 algorithms.Add (nameSHA256a, defaultSHA256);
298 algorithms.Add (nameSHA256b, defaultSHA256);
299 algorithms.Add (nameSHA256c, defaultSHA256);
301 algorithms.Add (nameSHA384a, defaultSHA384);
302 algorithms.Add (nameSHA384b, defaultSHA384);
303 algorithms.Add (nameSHA384c, defaultSHA384);
305 algorithms.Add (nameSHA512a, defaultSHA512);
306 algorithms.Add (nameSHA512b, defaultSHA512);
307 algorithms.Add (nameSHA512c, defaultSHA512);
309 algorithms.Add (nameRSAa, defaultRSA);
310 algorithms.Add (nameRSAb, defaultRSA);
311 algorithms.Add (nameRSAc, defaultRSA);
313 algorithms.Add (nameDSAa, defaultDSA);
314 algorithms.Add (nameDSAb, defaultDSA);
316 algorithms.Add (nameDESa, defaultDES);
317 algorithms.Add (nameDESb, defaultDES);
319 algorithms.Add (name3DESa, default3DES);
320 algorithms.Add (name3DESb, default3DES);
321 algorithms.Add (name3DESc, default3DES);
322 algorithms.Add (name3DESd, default3DES);
324 algorithms.Add (nameRC2a, defaultRC2);
325 algorithms.Add (nameRC2b, defaultRC2);
327 algorithms.Add (nameAESa, defaultAES);
328 algorithms.Add (nameAESb, defaultAES);
329 // LAMESPEC SymmetricAlgorithm documented as TripleDESCryptoServiceProvider
330 algorithms.Add (nameAESc, defaultAES);
332 // LAMESPEC These names aren't documented but (hint) the classes also have
333 // static Create methods. So logically they should (and are) here.
334 algorithms.Add (nameRNGa, defaultRNG);
335 algorithms.Add (nameRNGb, defaultRNG);
336 algorithms.Add (nameKeyHasha, defaultHMAC);
337 algorithms.Add (nameHMACSHA1a, defaultHMAC);
338 algorithms.Add (nameHMACSHA1b, defaultHMAC);
339 algorithms.Add (nameMAC3DESa, defaultMAC3DES);
340 algorithms.Add (nameMAC3DESb, defaultMAC3DES);
341 algorithms.Add (nameRIPEMD160a, defaultRIPEMD160);
342 algorithms.Add (nameRIPEMD160b, defaultRIPEMD160);
343 algorithms.Add (nameRIPEMD160c, defaultRIPEMD160);
344 algorithms.Add (nameHMACb, defaultHMAC);
345 algorithms.Add (nameHMACMD5a, defaultHMACMD5);
346 algorithms.Add (nameHMACMD5b, defaultHMACMD5);
347 algorithms.Add (nameHMACRIPEMD160a, defaultHMACRIPEMD160);
348 algorithms.Add (nameHMACRIPEMD160b, defaultHMACRIPEMD160);
349 algorithms.Add (nameHMACSHA256a, defaultHMACSHA256);
350 algorithms.Add (nameHMACSHA256b, defaultHMACSHA256);
351 algorithms.Add (nameHMACSHA384a, defaultHMACSHA384);
352 algorithms.Add (nameHMACSHA384b, defaultHMACSHA384);
353 algorithms.Add (nameHMACSHA512a, defaultHMACSHA512);
354 algorithms.Add (nameHMACSHA512b, defaultHMACSHA512);
356 // we do not want to load the types (and assemblies) unless we really need them
357 // so we keep those names as strings
358 Dictionary<string,string> unresolved_algorithms = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
360 // LAMESPEC These URLs aren't documented but (hint) installing the WSDK
361 // add some of the XMLDSIG urls into machine.config (and they make a LOT
362 // of sense for implementing XMLDSIG in System.Security.Cryptography.Xml)
363 algorithms.Add (urlDSASHA1, defaultDSASigDesc);
364 algorithms.Add (urlRSASHA1, defaultRSASigDesc);
365 algorithms.Add (urlSHA1, defaultSHA1);
366 unresolved_algorithms.Add (urlC14N, defaultC14N);
367 unresolved_algorithms.Add (urlC14NWithComments, defaultC14NWithComments);
368 unresolved_algorithms.Add (urlBase64, defaultBase64);
369 unresolved_algorithms.Add (urlXPath, defaultXPath);
370 unresolved_algorithms.Add (urlXslt, defaultXslt);
371 unresolved_algorithms.Add (urlEnveloped, defaultEnveloped);
372 unresolved_algorithms.Add (urlExcC14N, defaultExcC14N);
373 unresolved_algorithms.Add (urlExcC14NWithComments, defaultExcC14NWithComments);
374 unresolved_algorithms.Add (urlXmlDecryption, defaultXmlDecryption);
375 algorithms.Add (urlSHA256, defaultSHA256);
376 // xmlenc does not include a definition for SHA384
377 algorithms.Add (urlSHA512, defaultSHA512);
378 algorithms.Add (urlHMACSHA256, defaultHMACSHA256);
379 algorithms.Add (urlHMACSHA384, defaultHMACSHA384);
380 algorithms.Add (urlHMACSHA512, defaultHMACSHA512);
381 algorithms.Add (urlHMACRIPEMD160, defaultHMACRIPEMD160);
382 // LAMESPEC: only documentated in ".NET Framework Security" book
383 unresolved_algorithms.Add (urlX509Data, defaultX509Data);
384 unresolved_algorithms.Add (urlKeyName, defaultKeyName);
385 unresolved_algorithms.Add (urlKeyValueDSA, defaultKeyValueDSA);
386 unresolved_algorithms.Add (urlKeyValueRSA, defaultKeyValueRSA);
387 unresolved_algorithms.Add (urlRetrievalMethod, defaultRetrievalMethod);
389 // note: X.509 extensions aren't part of OID but names
390 unresolved_algorithms.Add (oidX509SubjectKeyIdentifier, nameX509SubjectKeyIdentifier);
391 unresolved_algorithms.Add (oidX509KeyUsage, nameX509KeyUsage);
392 unresolved_algorithms.Add (oidX509BasicConstraints, nameX509BasicConstraints);
393 unresolved_algorithms.Add (oidX509EnhancedKeyUsage, nameX509EnhancedKeyUsage);
394 // note: the default X.509Chain can also be created this way
395 unresolved_algorithms.Add (nameX509Chain, defaultX509Chain);
397 unresolved_algorithms.Add (nameAES_1, defaultAES_1);
398 unresolved_algorithms.Add (nameAES_2, defaultAES_1);
399 unresolved_algorithms.Add (nameAESManaged_1, defaultAESManaged);
400 unresolved_algorithms.Add (nameAESManaged_2, defaultAESManaged);
402 unresolved_algorithms.Add (nameECDiffieHellman_1, defaultECDiffieHellman);
403 unresolved_algorithms.Add (nameECDiffieHellman_2, defaultECDiffieHellman);
404 unresolved_algorithms.Add (nameECDiffieHellman_3, defaultECDiffieHellman);
405 unresolved_algorithms.Add (nameECDiffieHellman_4, defaultECDiffieHellman);
407 unresolved_algorithms.Add (nameECDsa_1, defaultECDsa);
408 unresolved_algorithms.Add (nameECDsa_2, defaultECDsa);
409 unresolved_algorithms.Add (nameECDsa_3, defaultECDsa);
411 unresolved_algorithms.Add (nameSHA1Cng, defaultSHA1Cng);
412 unresolved_algorithms.Add (nameSHA256Cng, defaultSHA256Cng);
413 unresolved_algorithms.Add (nameSHA256Provider, defaultSHA256Provider);
414 unresolved_algorithms.Add (nameSHA384Cng, defaultSHA384Cng);
415 unresolved_algorithms.Add (nameSHA384Provider, defaultSHA384Provider);
416 unresolved_algorithms.Add (nameSHA512Cng, defaultSHA512Cng);
417 unresolved_algorithms.Add (nameSHA512Provider, defaultSHA512Provider);
419 Dictionary<string,string> oid = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
421 // comments here are to match with MS implementation (but not with doc)
422 // LAMESPEC: only HashAlgorithm seems to have their OID included
423 oid.Add (nameSHA1, oidSHA1);
424 oid.Add (managedSHA1, oidSHA1);
425 oid.Add (nameSHA1b, oidSHA1);
426 oid.Add (nameSHA1c, oidSHA1);
428 oid.Add (nameMD5, oidMD5);
429 oid.Add (nameMD5a, oidMD5);
430 oid.Add (nameMD5b, oidMD5);
432 oid.Add (nameSHA256, oidSHA256);
433 oid.Add (nameSHA256a, oidSHA256);
434 oid.Add (nameSHA256c, oidSHA256);
436 oid.Add (nameSHA384, oidSHA384);
437 oid.Add (nameSHA384a, oidSHA384);
438 oid.Add (nameSHA384c, oidSHA384);
440 oid.Add (nameSHA512, oidSHA512);
441 oid.Add (nameSHA512a, oidSHA512);
442 oid.Add (nameSHA512c, oidSHA512);
444 oid.Add (nameRIPEMD160, oidRIPEMD160);
445 oid.Add (nameRIPEMD160a, oidRIPEMD160);
446 oid.Add (nameRIPEMD160c, oidRIPEMD160);
448 // surprise! documented in ".NET Framework Security" book
449 oid.Add (name3DESKeyWrap, oid3DESKeyWrap);
451 oid.Add (nameDESa, oidDES);
452 oid.Add (name3DESb, oid3DES);
453 oid.Add (nameRC2a, oidRC2);
455 // Add/modify the config as specified by machine.config
456 string config = Environment.GetMachineConfigPath ();
457 LoadConfig (config, algorithms, oid);
460 CryptoConfig.algorithms = algorithms;
461 CryptoConfig.unresolved_algorithms = unresolved_algorithms;
462 CryptoConfig.oids = oid;
465 [FileIOPermission (SecurityAction.Assert, Unrestricted = true)]
466 private static void LoadConfig (string filename, IDictionary<string,Type> algorithms, IDictionary<string,string> oid)
468 if (!File.Exists (filename))
472 using (TextReader reader = new StreamReader (filename)) {
473 CryptoHandler handler = new CryptoHandler (algorithms, oid);
474 SmallXmlParser parser = new SmallXmlParser ();
475 parser.Parse (reader, handler);
482 public static object CreateFromName (string name)
484 return CreateFromName (name, null);
487 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
488 public static object CreateFromName (string name, params object[] args)
491 throw new ArgumentNullException ("name");
494 if (algorithms == null) {
500 Type algoClass = null;
501 if (!algorithms.TryGetValue (name, out algoClass)) {
503 if (!unresolved_algorithms.TryGetValue (name, out algo))
505 algoClass = Type.GetType (algo);
507 if (algoClass == null)
509 // call the constructor for the type
510 return Activator.CreateInstance (algoClass, args);
513 // method doesn't throw any exception
518 public static string MapNameToOID (string name)
521 throw new ArgumentNullException ("name");
529 string result = null;
530 oids.TryGetValue (name, out result);
535 [MonoLimitation ("nothing is FIPS certified so it never make sense to restrict to this (empty) subset")]
536 public static bool AllowOnlyFipsAlgorithms {
537 get { return false; }
540 public static void AddAlgorithm (Type algorithm, params string[] names)
542 if (algorithm == null)
543 throw new ArgumentNullException ("algorithm");
545 throw new ArgumentNullException ("names");
547 foreach (string name in names) {
548 if (String.IsNullOrWhiteSpace (name))
549 throw new ArithmeticException ("names");
550 algorithms [name] = algorithm;
554 public static void AddOID (string oid, params string[] names)
557 throw new ArgumentNullException ("oid");
559 throw new ArgumentNullException ("names");
561 foreach (string name in names) {
562 if (String.IsNullOrWhiteSpace (name))
563 throw new ArithmeticException ("names");
569 class CryptoHandler: SmallXmlParser.IContentHandler {
571 IDictionary<string,Type> algorithms;
572 IDictionary<string,string> oid;
573 Dictionary<string,string> names;
574 Dictionary<string,string> classnames;
577 public CryptoHandler (IDictionary<string,Type> algorithms, IDictionary<string,string> oid)
579 this.algorithms = algorithms;
581 // temporary tables to reconstruct algorithms
582 names = new Dictionary<string,string> ();
583 classnames = new Dictionary<string,string> ();
586 public void OnStartParsing (SmallXmlParser parser)
591 public void OnEndParsing (SmallXmlParser parser)
593 foreach (var kpv in names) {
595 algorithms [kpv.Key] = Type.GetType (classnames [kpv.Value]);
600 // matching is done, data no more required
605 private string Get (SmallXmlParser.IAttrList attrs, string name)
607 for (int i = 0; i < attrs.Names.Length; i++) {
608 if (attrs.Names[i] == name)
609 return attrs.Values[i];
614 public void OnStartElement (string name, SmallXmlParser.IAttrList attrs)
618 if (name == "configuration")
622 if (name == "mscorlib")
626 if (name == "cryptographySettings")
630 if (name == "oidMap")
632 else if (name == "cryptoNameMapping")
636 if (name == "oidEntry") {
637 oid [Get (attrs, "name")] = Get (attrs, "OID");
638 } else if (name == "nameEntry") {
639 names [Get (attrs, "name")] = Get (attrs, "class");
640 } else if (name == "cryptoClasses") {
645 if (name == "cryptoClass")
646 classnames [attrs.Names[0]] = attrs.Values[0];
651 public void OnEndElement (string name)
653 // parser will make sure the XML structure is respected
656 if (name == "configuration")
660 if (name == "mscorlib")
664 if (name == "cryptographySettings")
668 if ((name == "oidMap") || (name == "cryptoNameMapping"))
672 if (name == "cryptoClasses")
678 public void OnProcessingInstruction (string name, string text)
683 public void OnChars (string text)
688 public void OnIgnorableWhitespace (string text)