2004-12-06 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / corlib / Test / System.Security.Cryptography / CryptoConfigTest.cs
1 //
2 // CryptoConfigTest.cs - NUnit Test Cases for CryptoConfig
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using NUnit.Framework;
31 using System;
32 using System.Security.Cryptography;
33
34 namespace MonoTests.System.Security.Cryptography {
35
36 [TestFixture]
37 public class CryptoConfigTest : Assertion {
38
39         public void AssertEquals (string msg, byte[] array1, byte[] array2)
40         {
41                 AllTests.AssertEquals (msg, array1, array2);
42         }
43
44         void CreateFromName (string name, string objectname)
45         {
46                 object o = CryptoConfig.CreateFromName (name);
47                 if (objectname == null)
48                         AssertNull (name, o);
49                 else
50                         AssertEquals (name, o.ToString(), objectname);
51         }
52
53         [Test]
54         [ExpectedException (typeof (ArgumentNullException))]
55         public void CreateFromNameNull () 
56         {
57                 object o = CryptoConfig.CreateFromName (null);
58         }
59
60         // validate that CryptoConfig create the exact same implementation between mono and MS
61         [Test]
62         public void CreateFromName () 
63         {
64                 CreateFromName ("SHA", "System.Security.Cryptography.SHA1CryptoServiceProvider");
65                 // FIXME: We need to support the machine.config file to get exact same results
66                 // with the MS .NET Framework
67                 CreateFromName ("SHA1", "System.Security.Cryptography.SHA1CryptoServiceProvider");
68                 CreateFromName( "System.Security.Cryptography.SHA1", "System.Security.Cryptography.SHA1CryptoServiceProvider");
69                 // after installing the WSDK - changes to the machine.config file (not documented)
70 //              CreateFromName ("SHA1", "System.Security.Cryptography.SHA1Managed");
71 //              CreateFromName ("System.Security.Cryptography.SHA1", "System.Security.Cryptography.SHA1Managed");
72                 CreateFromName ("System.Security.Cryptography.HashAlgorithm", "System.Security.Cryptography.SHA1CryptoServiceProvider");
73                 CreateFromName ("System.Security.Cryptography.SHA1CryptoServiceProvider", "System.Security.Cryptography.SHA1CryptoServiceProvider");
74                 CreateFromName ("MD5", "System.Security.Cryptography.MD5CryptoServiceProvider");  
75                 CreateFromName ("System.Security.Cryptography.MD5", "System.Security.Cryptography.MD5CryptoServiceProvider");  
76                 CreateFromName ("System.Security.Cryptography.MD5CryptoServiceProvider", "System.Security.Cryptography.MD5CryptoServiceProvider");
77                 CreateFromName ("SHA256", "System.Security.Cryptography.SHA256Managed");  
78                 CreateFromName ("SHA-256", "System.Security.Cryptography.SHA256Managed");  
79                 CreateFromName ("System.Security.Cryptography.SHA256", "System.Security.Cryptography.SHA256Managed");  
80                 CreateFromName ("SHA384", "System.Security.Cryptography.SHA384Managed");  
81                 CreateFromName ("SHA-384", "System.Security.Cryptography.SHA384Managed");  
82                 CreateFromName ("System.Security.Cryptography.SHA384", "System.Security.Cryptography.SHA384Managed");  
83                 CreateFromName ("SHA512", "System.Security.Cryptography.SHA512Managed");  
84                 CreateFromName ("SHA-512", "System.Security.Cryptography.SHA512Managed");  
85                 CreateFromName ("System.Security.Cryptography.SHA512", "System.Security.Cryptography.SHA512Managed");  
86                 CreateFromName ("RSA", "System.Security.Cryptography.RSACryptoServiceProvider");  
87                 CreateFromName ("System.Security.Cryptography.RSA", "System.Security.Cryptography.RSACryptoServiceProvider");  
88                 CreateFromName ("System.Security.Cryptography.AsymmetricAlgorithm", "System.Security.Cryptography.RSACryptoServiceProvider");  
89                 CreateFromName ("DSA", "System.Security.Cryptography.DSACryptoServiceProvider");  
90                 CreateFromName ("System.Security.Cryptography.DSA", "System.Security.Cryptography.DSACryptoServiceProvider");  
91                 CreateFromName ("DES", "System.Security.Cryptography.DESCryptoServiceProvider");  
92                 CreateFromName ("System.Security.Cryptography.DES", "System.Security.Cryptography.DESCryptoServiceProvider");  
93                 CreateFromName ("3DES", "System.Security.Cryptography.TripleDESCryptoServiceProvider");  
94                 CreateFromName ("TripleDES", "System.Security.Cryptography.TripleDESCryptoServiceProvider");  
95                 CreateFromName ("Triple DES", "System.Security.Cryptography.TripleDESCryptoServiceProvider");  
96                 CreateFromName ("System.Security.Cryptography.TripleDES", "System.Security.Cryptography.TripleDESCryptoServiceProvider");  
97                 // LAMESPEC SymmetricAlgorithm documented as TripleDESCryptoServiceProvider
98                 CreateFromName ("System.Security.Cryptography.SymmetricAlgorithm", "System.Security.Cryptography.RijndaelManaged");  
99                 CreateFromName ("RC2", "System.Security.Cryptography.RC2CryptoServiceProvider");  
100                 CreateFromName ("System.Security.Cryptography.RC2", "System.Security.Cryptography.RC2CryptoServiceProvider");  
101                 CreateFromName ("Rijndael", "System.Security.Cryptography.RijndaelManaged");  
102                 CreateFromName ("System.Security.Cryptography.Rijndael", "System.Security.Cryptography.RijndaelManaged");
103                 // LAMESPEC Undocumented Names in CryptoConfig
104                 CreateFromName ("RandomNumberGenerator", "System.Security.Cryptography.RNGCryptoServiceProvider");
105                 CreateFromName ("System.Security.Cryptography.RandomNumberGenerator", "System.Security.Cryptography.RNGCryptoServiceProvider");
106                 CreateFromName ("System.Security.Cryptography.KeyedHashAlgorithm", "System.Security.Cryptography.HMACSHA1");
107                 CreateFromName ("HMACSHA1", "System.Security.Cryptography.HMACSHA1");
108                 CreateFromName ("System.Security.Cryptography.HMACSHA1", "System.Security.Cryptography.HMACSHA1");
109                 CreateFromName ("MACTripleDES", "System.Security.Cryptography.MACTripleDES");
110                 CreateFromName ("System.Security.Cryptography.MACTripleDES", "System.Security.Cryptography.MACTripleDES");
111                 // note: CryptoConfig can create any object !
112                 CreateFromName ("System.Security.Cryptography.CryptoConfig", "System.Security.Cryptography.CryptoConfig");
113                 CreateFromName ("System.IO.MemoryStream", "System.IO.MemoryStream");
114                 // non existing algo should return null (without exception)
115                 AssertNull ("NonExistingAlgorithm", CryptoConfig.CreateFromName("NonExistingAlgorithm"));
116         }
117
118         // additional names (URL) used for XMLDSIG (System.Security.Cryptography.Xml)
119         // URL taken from http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/
120         [Test]
121         public void CreateFromURL () 
122         {
123                 // URL used in SignatureMethod element
124                 CreateFromName ("http://www.w3.org/2000/09/xmldsig#dsa-sha1", "System.Security.Cryptography.DSASignatureDescription");
125                 CreateFromName ("http://www.w3.org/2000/09/xmldsig#rsa-sha1", "System.Security.Cryptography.RSAPKCS1SHA1SignatureDescription");
126                 CreateFromName ("http://www.w3.org/2000/09/xmldsig#hmac-sha1", null);
127                 // URL used in DigestMethod element 
128                 CreateFromName ("http://www.w3.org/2000/09/xmldsig#sha1", "System.Security.Cryptography.SHA1CryptoServiceProvider");
129                 // URL used in Canonicalization or Transform elements 
130                 CreateFromName ("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", "System.Security.Cryptography.Xml.XmlDsigC14NTransform");
131                 CreateFromName ("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments", "System.Security.Cryptography.Xml.XmlDsigC14NWithCommentsTransform");
132                 // URL used in Transform element 
133                 CreateFromName ("http://www.w3.org/2000/09/xmldsig#base64", "System.Security.Cryptography.Xml.XmlDsigBase64Transform");
134                 // after installing the WSDK - changes to the machine.config file (not documented)
135 //              CreateFromName ("http://www.w3.org/TR/1999/REC-xpath-19991116", "Microsoft.WSDK.Security.XmlDsigXPathTransform");
136                 CreateFromName ("http://www.w3.org/TR/1999/REC-xpath-19991116", "System.Security.Cryptography.Xml.XmlDsigXPathTransform");
137                 CreateFromName ("http://www.w3.org/TR/1999/REC-xslt-19991116", "System.Security.Cryptography.Xml.XmlDsigXsltTransform");
138                 CreateFromName ("http://www.w3.org/2000/09/xmldsig#enveloped-signature", "System.Security.Cryptography.Xml.XmlDsigEnvelopedSignatureTransform");
139                 // URL used in Reference element 
140                 CreateFromName ("http://www.w3.org/2000/09/xmldsig#Object", null);
141                 CreateFromName ("http://www.w3.org/2000/09/xmldsig#Manifest", null);
142                 CreateFromName ("http://www.w3.org/2000/09/xmldsig#SignatureProperties", null);
143                 // LAMESPEC: only documentated in ".NET Framework Security" book
144                 CreateFromName ("http://www.w3.org/2000/09/xmldsig# X509Data", "System.Security.Cryptography.Xml.KeyInfoX509Data");
145                 CreateFromName ("http://www.w3.org/2000/09/xmldsig# KeyName", "System.Security.Cryptography.Xml.KeyInfoName");
146                 CreateFromName ("http://www.w3.org/2000/09/xmldsig# KeyValue/DSAKeyValue", "System.Security.Cryptography.Xml.DSAKeyValue");
147                 CreateFromName ("http://www.w3.org/2000/09/xmldsig# KeyValue/RSAKeyValue", "System.Security.Cryptography.Xml.RSAKeyValue");
148                 CreateFromName ("http://www.w3.org/2000/09/xmldsig# RetrievalMethod", "System.Security.Cryptography.Xml.KeyInfoRetrievalMethod");
149         }
150
151         // Tests created using "A Layer Man Guide to ASN.1" from RSA, page 19-20
152         // Need to find an OID ? goto http://www.alvestrand.no/~hta/objectid/top.html
153         static byte[] oidETSI = { 0x06, 0x03, 0x04, 0x00, 0x00 };
154         static byte[] oidSHA1 = { 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A };
155         static byte[] oidASN1CharacterModule = { 0x06, 0x04, 0x51, 0x00, 0x00, 0x00 };
156         static byte[] oidmd5withRSAEncryption = { 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04 };
157
158         [Test]
159         [ExpectedException (typeof (NullReferenceException))]
160         // LAMESPEC NullReferenceException is thrown (not ArgumentNullException) if parameter is NULL
161         public void EncodeOIDNull () 
162         {
163                 byte[] o = CryptoConfig.EncodeOID (null);
164         }
165
166         [Test]
167         public void EncodeOID () 
168         {
169                 // OID starts with 0, 1 or 2
170                 AssertEquals ("OID starting with 0.", oidETSI, CryptoConfig.EncodeOID ("0.4.0.0"));
171                 AssertEquals ("OID starting with 1.", oidSHA1, CryptoConfig.EncodeOID ("1.3.14.3.2.26"));
172                 AssertEquals ("OID starting with 2.", oidASN1CharacterModule, CryptoConfig.EncodeOID ("2.1.0.0.0"));
173                 // OID numbers can span multiple bytes
174                 AssertEquals ("OID with numbers spanning multiple bytes", oidmd5withRSAEncryption, CryptoConfig.EncodeOID ("1.2.840.113549.1.1.4"));
175         }
176
177         [Test]
178         [ExpectedException (typeof (CryptographicUnexpectedOperationException))]
179         // LAMESPEC: OID greater that 0x7F (127) bytes aren't supported by the MS Framework
180         public void EncodeOID_BiggerThan127bytes () 
181         {
182                 // "ms"-invalid OID - greater than 127 bytes (length encoding)
183                 // OID longer than 127 bytes (so length must be encoded on multiple bytes)
184                 string baseOID = "1.3.6.1.4.1.11071.0.";
185                 string lastPart = "1111111111"; // must fit in int32
186                 for (int i = 1; i < 30; i++) {
187                         baseOID += lastPart + ".";
188                 }
189                 baseOID += "0";
190                 byte[] tooLongOID = CryptoConfig.EncodeOID (baseOID);
191         }
192                 
193         [Test]
194         [ExpectedException (typeof (OverflowException))]
195         // LAMESPEC: OID with numbers > Int32 aren't supported by the MS BCL
196         public void EncodeOID_BiggerThanInt32 () 
197         {
198                 // "ms"-invalid OID - where a number of the OID > Int32
199                 byte[] tooLongOID = CryptoConfig.EncodeOID ("1.1.4294967295");
200         }
201
202         [Test]
203         public void EncodeOID_InvalidStart () 
204         {
205                 // invalid OID - must start with 0, 1 or 2
206                 // however it works with MS BCL
207                 byte[] oid3 = CryptoConfig.EncodeOID ("3.0");
208                 byte[] res3 = { 0x06, 0x01, 0x78 };
209                 AssertEquals ("OID: 3.0", res3, oid3);
210         }
211
212         [Test]
213         [ExpectedException (typeof (CryptographicUnexpectedOperationException))]
214         public void EncodeOID_TooShort () 
215         {
216                 // invalid OID - must have at least 2 parts (according to X.208)
217                 byte[] tooShortOID = CryptoConfig.EncodeOID ("0");
218         }
219
220         [Test]
221         public void EncodeOID_InvalidSecondPart () 
222         {
223                 // invalid OID - second value < 40 for 0. and 1. (modulo 40)
224                 // however it works with MS BCL
225                 byte[] tooBigSecondPartOID = CryptoConfig.EncodeOID ("0.40");
226                 byte[] tooBigSecondPartRes = { 0x06, 0x01, 0x28 };
227                 AssertEquals ("OID: 0.40", tooBigSecondPartRes, tooBigSecondPartOID);
228         }
229
230         [Test]
231         [ExpectedException (typeof (ArgumentNullException))]
232         public void MapNameToOIDNull () 
233         {
234                 CryptoConfig.MapNameToOID (null);
235         }
236
237         private void MapNameToOID (string name, string oid)
238         {
239                 AssertEquals ("oid(" + name + ")", oid, CryptoConfig.MapNameToOID (name));
240         }
241
242         // LAMESPEC: doesn't support all names defined in CryptoConfig 
243         // non supported names (in MSFW) are commented or null-ed
244         // LAMESPEC: undocumented but full class name is supported
245         [Test]
246         public void MapNameToOID() 
247         {
248 //              MapNameToOID ("SHA", "1.3.14.3.2.26");
249                 MapNameToOID ("SHA1", "1.3.14.3.2.26");
250                 MapNameToOID ("System.Security.Cryptography.SHA1", "1.3.14.3.2.26");
251 //              MapNameToOID ("System.Security.Cryptography.HashAlgorithm", "1.3.14.3.2.26");
252                 MapNameToOID ("System.Security.Cryptography.SHA1CryptoServiceProvider", "1.3.14.3.2.26");
253                 MapNameToOID ("System.Security.Cryptography.SHA1Managed", "1.3.14.3.2.26");
254                 MapNameToOID ("MD5", "1.2.840.113549.2.5");
255                 MapNameToOID ("System.Security.Cryptography.MD5", "1.2.840.113549.2.5");
256                 MapNameToOID ("System.Security.Cryptography.MD5CryptoServiceProvider", "1.2.840.113549.2.5");
257 #if NET_2_0
258                 MapNameToOID ("SHA256", "2.16.840.1.101.3.4.2.1");
259                 MapNameToOID ("System.Security.Cryptography.SHA256", "2.16.840.1.101.3.4.2.1");
260                 MapNameToOID ("System.Security.Cryptography.SHA256Managed", "2.16.840.1.101.3.4.2.1");
261                 MapNameToOID ("SHA384", "2.16.840.1.101.3.4.2.2");
262                 MapNameToOID ("System.Security.Cryptography.SHA384", "2.16.840.1.101.3.4.2.2");
263                 MapNameToOID ("System.Security.Cryptography.SHA384Managed", "2.16.840.1.101.3.4.2.2");
264                 MapNameToOID ("SHA512", "2.16.840.1.101.3.4.2.3");
265                 MapNameToOID ("System.Security.Cryptography.SHA512", "2.16.840.1.101.3.4.2.3");
266                 MapNameToOID ("System.Security.Cryptography.SHA512Managed", "2.16.840.1.101.3.4.2.3");
267 #else
268                 MapNameToOID ("SHA256", "2.16.840.1.101.3.4.1");
269 //              MapNameToOID ("SHA-256", "2.16.840.1.101.3.4.1");
270                 MapNameToOID ("System.Security.Cryptography.SHA256", "2.16.840.1.101.3.4.1");
271                 MapNameToOID ("System.Security.Cryptography.SHA256Managed", "2.16.840.1.101.3.4.1");
272                 MapNameToOID ("SHA384", "2.16.840.1.101.3.4.2");
273 //              MapNameToOID ("SHA-384", "2.16.840.1.101.3.4.2");
274                 MapNameToOID ("System.Security.Cryptography.SHA384", "2.16.840.1.101.3.4.2");
275                 MapNameToOID ("System.Security.Cryptography.SHA384Managed", "2.16.840.1.101.3.4.2");
276                 MapNameToOID ("SHA512", "2.16.840.1.101.3.4.3");
277 //              MapNameToOID ("SHA-512", "2.16.840.1.101.3.4.3");
278                 MapNameToOID ("System.Security.Cryptography.SHA512", "2.16.840.1.101.3.4.3");
279                 MapNameToOID ("System.Security.Cryptography.SHA512Managed", "2.16.840.1.101.3.4.3");
280 #endif
281                 // LAMESPEC: only documentated in ".NET Framework Security" book
282                 MapNameToOID ("TripleDESKeyWrap", "1.2.840.113549.1.9.16.3.6");
283 #if NET_2_0
284                 // new OID defined in Fx 2.0
285                 MapNameToOID ("RSA", "1.2.840.113549.1.1.1");
286                 MapNameToOID ("DSA", "1.2.840.10040.4.1");
287                 MapNameToOID ("DES", "1.3.14.3.2.7");
288                 MapNameToOID ("3DES", "1.2.840.113549.3.7");
289                 MapNameToOID ("TripleDES", "1.2.840.113549.3.7");
290                 MapNameToOID ("RC2", "1.2.840.113549.3.2");
291 #else
292                 // no OID defined before Fx 2.0
293                 MapNameToOID ("RSA", null);
294                 MapNameToOID ("DSA", null);
295                 MapNameToOID ("DES", null);
296                 MapNameToOID ("3DES", null);
297                 MapNameToOID ("TripleDES", null);
298                 MapNameToOID ("RC2", null);
299 #endif
300                 // no OID defined ?
301                 MapNameToOID ("System.Security.Cryptography.RSA", null);
302                 MapNameToOID ("System.Security.Cryptography.AsymmetricAlgorithm", null);
303                 MapNameToOID ("System.Security.Cryptography.DSA", null);
304                 MapNameToOID ("System.Security.Cryptography.DES", null);
305                 MapNameToOID ("Triple DES", null);
306                 MapNameToOID ("System.Security.Cryptography.TripleDES", null);
307                 MapNameToOID ("System.Security.Cryptography.RC2", null);
308                 MapNameToOID ("Rijndael", null);
309                 MapNameToOID ("System.Security.Cryptography.Rijndael", null);
310                 MapNameToOID ("System.Security.Cryptography.SymmetricAlgorithm", null);
311                 // LAMESPEC Undocumented Names in CryptoConfig
312                 MapNameToOID ("RandomNumberGenerator", null);
313                 MapNameToOID ("System.Security.Cryptography.RandomNumberGenerator", null);
314                 MapNameToOID ("System.Security.Cryptography.KeyedHashAlgorithm", null);
315                 MapNameToOID ("HMACSHA1", null);
316                 MapNameToOID ("System.Security.Cryptography.HMACSHA1", null);
317                 MapNameToOID ("MACTripleDES", null);
318                 MapNameToOID ("System.Security.Cryptography.MACTripleDES", null);
319                 // non existing algo should return null (without exception)
320                 MapNameToOID ("NonExistingAlgorithm", null);
321         }
322
323         [Test]
324         public void CCToString () 
325         {
326                 // under normal circumstance there are no need to create a CryptoConfig object
327                 // because all interesting stuff are in static methods
328                 CryptoConfig cc = new CryptoConfig ();
329                 AssertEquals ("System.Security.Cryptography.CryptoConfig", cc.ToString ());
330         }
331 }
332
333 }