2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / Test / System.Security.Cryptography / RSATest.cs
1 //
2 // RSATest.cs - NUnit Test Cases for RSA
3 //
4 // Author:
5 //      Sebastien Pouliot (spouliot@motus.com)
6 //
7 // (C) 2002 Motus Technologies Inc. (http://www.motus.com)
8 //
9
10 using NUnit.Framework;
11 using System;
12 using System.Security.Cryptography;
13
14 namespace MonoTests.System.Security.Cryptography {
15
16 public class NonAbstractRSAForUnitTests : RSA {
17         protected RSAParameters rsaParams;
18
19         // not tested here - but we must implemented all abstract properties
20         public override string KeyExchangeAlgorithm {
21                 get { return null; }
22         }
23
24         // not tested here - but we must implemented all abstract properties
25         public override string SignatureAlgorithm {
26                 get { return null; }
27         }
28
29         // not tested here - but we must implemented all abstract methods
30         public override byte[] DecryptValue (byte[] rgb) 
31         {
32                 return null;
33         }
34
35         // not tested here - but we must implemented all abstract methods
36         public override byte[] EncryptValue (byte[] rgb) {
37                 return null;
38         }
39
40         // basic implementation for tests
41         public override RSAParameters ExportParameters (bool includePrivateParameters) 
42         {
43                 if (includePrivateParameters)
44                         return rsaParams;
45                 else {
46                         RSAParameters rsaPublicParams = rsaParams;
47                         rsaPublicParams.D = null;
48                         rsaPublicParams.DP = null;
49                         rsaPublicParams.DQ = null;
50                         rsaPublicParams.P = null;
51                         rsaPublicParams.Q = null;
52                         rsaPublicParams.InverseQ = null;
53                         return rsaPublicParams;
54                 }
55         }
56
57         // basic implementation for tests
58         public override void ImportParameters (RSAParameters parameters) 
59         {
60                 rsaParams = new RSAParameters ();
61                 if (parameters.D != null)
62                         rsaParams.D = (byte[]) parameters.D.Clone ();
63                 if (parameters.DP != null)
64                         rsaParams.DP = (byte[]) parameters.DP.Clone ();
65                 if (parameters.DQ != null)
66                         rsaParams.DQ = (byte[]) parameters.DQ.Clone ();
67                 if (parameters.P != null)
68                         rsaParams.P = (byte[]) parameters.P.Clone ();
69                 if (parameters.Q != null)
70                         rsaParams.Q = (byte[]) parameters.Q.Clone ();
71                 if (parameters.InverseQ != null)
72                         rsaParams.InverseQ = (byte[]) parameters.InverseQ.Clone ();
73                 // public key
74                 rsaParams.Exponent = (byte[]) parameters.Exponent.Clone ();
75                 rsaParams.Modulus = (byte[]) parameters.Modulus.Clone ();
76         }
77
78         // not tested here - but we must implemented all abstract methods
79         protected override void Dispose (bool disposing) {}
80 }
81
82 [TestFixture]
83 public class RSATest : Assertion {
84         protected RSA rsa;
85
86         static byte[] rsaModulus =  { 0xbb, 0xf8, 0x2f, 0x09, 0x06, 0x82, 0xce, 0x9c, 0x23, 0x38, 0xac, 0x2b, 0x9d, 0xa8, 0x71, 0xf7, 
87                                             0x36, 0x8d, 0x07, 0xee, 0xd4, 0x10, 0x43, 0xa4, 0x40, 0xd6, 0xb6, 0xf0, 0x74, 0x54, 0xf5, 0x1f,
88                                             0xb8, 0xdf, 0xba, 0xaf, 0x03, 0x5c, 0x02, 0xab, 0x61, 0xea, 0x48, 0xce, 0xeb, 0x6f, 0xcd, 0x48,
89                                             0x76, 0xed, 0x52, 0x0d, 0x60, 0xe1, 0xec, 0x46, 0x19, 0x71, 0x9d, 0x8a, 0x5b, 0x8b, 0x80, 0x7f,
90                                             0xaf, 0xb8, 0xe0, 0xa3, 0xdf, 0xc7, 0x37, 0x72, 0x3e, 0xe6, 0xb4, 0xb7, 0xd9, 0x3a, 0x25, 0x84,
91                                             0xee, 0x6a, 0x64, 0x9d, 0x06, 0x09, 0x53, 0x74, 0x88, 0x34, 0xb2, 0x45, 0x45, 0x98, 0x39, 0x4e,
92                                             0xe0, 0xaa, 0xb1, 0x2d, 0x7b, 0x61, 0xa5, 0x1f, 0x52, 0x7a, 0x9a, 0x41, 0xf6, 0xc1, 0x68, 0x7f,
93                                             0xe2, 0x53, 0x72, 0x98, 0xca, 0x2a, 0x8f, 0x59, 0x46, 0xf8, 0xe5, 0xfd, 0x09, 0x1d, 0xbd, 0xcb };
94         static byte[] rsaExponent = { 0x11 };
95         static byte[] rsaP =  { 0xee, 0xcf, 0xae, 0x81, 0xb1, 0xb9, 0xb3, 0xc9, 0x08, 0x81, 0x0b, 0x10, 0xa1, 0xb5, 0x60, 0x01, 
96                                       0x99, 0xeb, 0x9f, 0x44, 0xae, 0xf4, 0xfd, 0xa4, 0x93, 0xb8, 0x1a, 0x9e, 0x3d, 0x84, 0xf6, 0x32,
97                                       0x12, 0x4e, 0xf0, 0x23, 0x6e, 0x5d, 0x1e, 0x3b, 0x7e, 0x28, 0xfa, 0xe7, 0xaa, 0x04, 0x0a, 0x2d,
98                                       0x5b, 0x25, 0x21, 0x76, 0x45, 0x9d, 0x1f, 0x39, 0x75, 0x41, 0xba, 0x2a, 0x58, 0xfb, 0x65, 0x99 };
99         static byte[] rsaQ =  { 0xc9, 0x7f, 0xb1, 0xf0, 0x27, 0xf4, 0x53, 0xf6, 0x34, 0x12, 0x33, 0xea, 0xaa, 0xd1, 0xd9, 0x35,
100                                       0x3f, 0x6c, 0x42, 0xd0, 0x88, 0x66, 0xb1, 0xd0, 0x5a, 0x0f, 0x20, 0x35, 0x02, 0x8b, 0x9d, 0x86, 
101                                       0x98, 0x40, 0xb4, 0x16, 0x66, 0xb4, 0x2e, 0x92, 0xea, 0x0d, 0xa3, 0xb4, 0x32, 0x04, 0xb5, 0xcf,
102                                       0xce, 0x33, 0x52, 0x52, 0x4d, 0x04, 0x16, 0xa5, 0xa4, 0x41, 0xe7, 0x00, 0xaf, 0x46, 0x15, 0x03 };
103         static byte[] rsaDP = { 0x54, 0x49, 0x4c, 0xa6, 0x3e, 0xba, 0x03, 0x37, 0xe4, 0xe2, 0x40, 0x23, 0xfc, 0xd6, 0x9a, 0x5a, 
104                                       0xeb, 0x07, 0xdd, 0xdc, 0x01, 0x83, 0xa4, 0xd0, 0xac, 0x9b, 0x54, 0xb0, 0x51, 0xf2, 0xb1, 0x3e, 
105                                       0xd9, 0x49, 0x09, 0x75, 0xea, 0xb7, 0x74, 0x14, 0xff, 0x59, 0xc1, 0xf7, 0x69, 0x2e, 0x9a, 0x2e, 
106                                       0x20, 0x2b, 0x38, 0xfc, 0x91, 0x0a, 0x47, 0x41, 0x74, 0xad, 0xc9, 0x3c, 0x1f, 0x67, 0xc9, 0x81 };
107         static byte[] rsaDQ = { 0x47, 0x1e, 0x02, 0x90, 0xff, 0x0a, 0xf0, 0x75, 0x03, 0x51, 0xb7, 0xf8, 0x78, 0x86, 0x4c, 0xa9, 
108                                       0x61, 0xad, 0xbd, 0x3a, 0x8a, 0x7e, 0x99, 0x1c, 0x5c, 0x05, 0x56, 0xa9, 0x4c, 0x31, 0x46, 0xa7, 
109                                       0xf9, 0x80, 0x3f, 0x8f, 0x6f, 0x8a, 0xe3, 0x42, 0xe9, 0x31, 0xfd, 0x8a, 0xe4, 0x7a, 0x22, 0x0d, 
110                                       0x1b, 0x99, 0xa4, 0x95, 0x84, 0x98, 0x07, 0xfe, 0x39, 0xf9, 0x24, 0x5a, 0x98, 0x36, 0xda, 0x3d };
111         static byte[] rsaInverseQ = { 0xb0, 0x6c, 0x4f, 0xda, 0xbb, 0x63, 0x01, 0x19, 0x8d, 0x26, 0x5b, 0xdb, 0xae, 0x94, 0x23, 0xb3, 
112                                             0x80, 0xf2, 0x71, 0xf7, 0x34, 0x53, 0x88, 0x50, 0x93, 0x07, 0x7f, 0xcd, 0x39, 0xe2, 0x11, 0x9f, 
113                                             0xc9, 0x86, 0x32, 0x15, 0x4f, 0x58, 0x83, 0xb1, 0x67, 0xa9, 0x67, 0xbf, 0x40, 0x2b, 0x4e, 0x9e, 
114                                             0x2e, 0x0f, 0x96, 0x56, 0xe6, 0x98, 0xea, 0x36, 0x66, 0xed, 0xfb, 0x25, 0x79, 0x80, 0x39, 0xf7 };
115         static byte[] rsaD = { 0xa5, 0xda, 0xfc, 0x53, 0x41, 0xfa, 0xf2, 0x89, 0xc4, 0xb9, 0x88, 0xdb, 0x30, 0xc1, 0xcd, 0xf8,
116                                      0x3f, 0x31, 0x25, 0x1e, 0x06, 0x68, 0xb4, 0x27, 0x84, 0x81, 0x38, 0x01, 0x57, 0x96, 0x41, 0xb2, 
117                                      0x94, 0x10, 0xb3, 0xc7, 0x99, 0x8d, 0x6b, 0xc4, 0x65, 0x74, 0x5e, 0x5c, 0x39, 0x26, 0x69, 0xd6, 
118                                      0x87, 0x0d, 0xa2, 0xc0, 0x82, 0xa9, 0x39, 0xe3, 0x7f, 0xdc, 0xb8, 0x2e, 0xc9, 0x3e, 0xda, 0xc9, 
119                                      0x7f, 0xf3, 0xad, 0x59, 0x50, 0xac, 0xcf, 0xbc, 0x11, 0x1c, 0x76, 0xf1, 0xa9, 0x52, 0x94, 0x44, 
120                                      0xe5, 0x6a, 0xaf, 0x68, 0xc5, 0x6c, 0x09, 0x2c, 0xd3, 0x8d, 0xc3, 0xbe, 0xf5, 0xd2, 0x0a, 0x93,
121                                      0x99, 0x26, 0xed, 0x4f, 0x74, 0xa1, 0x3e, 0xdd, 0xfb, 0xe1, 0xa1, 0xce, 0xcc, 0x48, 0x94, 0xaf, 
122                                      0x94, 0x28, 0xc2, 0xb7, 0xb8, 0x88, 0x3f, 0xe4, 0x46, 0x3a, 0x4b, 0xc8, 0x5b, 0x1c, 0xb3, 0xc1 };
123
124         static string xmlPrivate = "<RSAKeyValue><Modulus>u/gvCQaCzpwjOKwrnahx9zaNB+7UEEOkQNa28HRU9R+437qvA1wCq2HqSM7rb81Idu1SDWDh7EYZcZ2KW4uAf6+44KPfxzdyPua0t9k6JYTuamSdBglTdIg0skVFmDlO4KqxLXthpR9SeppB9sFof+JTcpjKKo9ZRvjl/Qkdvcs=</Modulus><Exponent>EQ==</Exponent><P>7s+ugbG5s8kIgQsQobVgAZnrn0Su9P2kk7ganj2E9jISTvAjbl0eO34o+ueqBAotWyUhdkWdHzl1QboqWPtlmQ==</P><Q>yX+x8Cf0U/Y0EjPqqtHZNT9sQtCIZrHQWg8gNQKLnYaYQLQWZrQukuoNo7QyBLXPzjNSUk0EFqWkQecAr0YVAw==</Q><DP>VElMpj66Azfk4kAj/NaaWusH3dwBg6TQrJtUsFHysT7ZSQl16rd0FP9ZwfdpLpouICs4/JEKR0F0rck8H2fJgQ==</DP><DQ>Rx4CkP8K8HUDUbf4eIZMqWGtvTqKfpkcXAVWqUwxRqf5gD+Pb4rjQukx/YrkeiING5mklYSYB/45+SRamDbaPQ==</DQ><InverseQ>sGxP2rtjARmNJlvbrpQjs4Dycfc0U4hQkwd/zTniEZ/JhjIVT1iDsWepZ79AK06eLg+WVuaY6jZm7fsleYA59w==</InverseQ><D>pdr8U0H68onEuYjbMMHN+D8xJR4GaLQnhIE4AVeWQbKUELPHmY1rxGV0Xlw5JmnWhw2iwIKpOeN/3LguyT7ayX/zrVlQrM+8ERx28alSlETlaq9oxWwJLNONw7710gqTmSbtT3ShPt374aHOzEiUr5Qowre4iD/kRjpLyFscs8E=</D></RSAKeyValue>";
125
126         static string xmlPublic = "<RSAKeyValue><Modulus>u/gvCQaCzpwjOKwrnahx9zaNB+7UEEOkQNa28HRU9R+437qvA1wCq2HqSM7rb81Idu1SDWDh7EYZcZ2KW4uAf6+44KPfxzdyPua0t9k6JYTuamSdBglTdIg0skVFmDlO4KqxLXthpR9SeppB9sFof+JTcpjKKo9ZRvjl/Qkdvcs=</Modulus><Exponent>EQ==</Exponent></RSAKeyValue>";
127
128         [SetUp]
129         public void SetUp () 
130         {
131                 rsa = new NonAbstractRSAForUnitTests ();
132         }
133
134         public void AssertEquals (string msg, byte[] array1, byte[] array2) 
135         {
136                 AllTests.AssertEquals (msg, array1, array2);
137         }
138
139         // may also help for RSA descendants
140         public void AssertEquals (string message, RSAParameters expectedKey, RSAParameters actualKey, bool checkPrivateKey) 
141         {
142                 if (checkPrivateKey) {
143                         AssertEquals( message + " D", expectedKey.D, actualKey.D );
144                         AssertEquals( message + " DP", expectedKey.DP, actualKey.DP );
145                         AssertEquals( message + " DQ", expectedKey.DQ, actualKey.DQ );
146                         AssertEquals( message + " P", expectedKey.P, actualKey.P );
147                         AssertEquals( message + " Q", expectedKey.Q, actualKey.Q );
148                         AssertEquals( message + " InverseQ", expectedKey.InverseQ, actualKey.InverseQ );
149                 }
150                 AssertEquals( message + " Modulus", expectedKey.Modulus, actualKey.Modulus );
151                 AssertEquals( message + " Exponent", expectedKey.Exponent, actualKey.Exponent );
152         }
153
154         public RSAParameters GetKey (bool includePrivateKey) 
155         {
156                 RSAParameters p = new RSAParameters();
157                 if (includePrivateKey) {
158                         p.D = rsaD;
159                         p.DP = rsaDP;
160                         p.DQ = rsaDQ;
161                         p.P = rsaP;
162                         p.Q = rsaQ;
163                         p.InverseQ = rsaInverseQ;
164                 }
165                 else {
166                         p.D = null;
167                         p.DP = null;
168                         p.DQ = null;
169                         p.P = null;
170                         p.Q = null;
171                         p.InverseQ = null;
172                 }
173                 p.Modulus = rsaModulus;
174                 p.Exponent = rsaExponent;
175                 return p;
176         }
177
178         // importing RSA keypair and exporting a RSA keypair 
179         [Test]
180         public void RSAImportPrivateExportPrivate () 
181         {
182                 RSAParameters input = GetKey (true);
183                 rsa.ImportParameters (input);
184                 string xmlRSA = rsa.ToXmlString (true);
185                 rsa.FromXmlString (xmlRSA);
186                 AssertEquals ("RSA Import Private Export Private (xml)", xmlPrivate, xmlRSA);
187                 RSAParameters output = rsa.ExportParameters (true);
188                 AssertEquals ("RSA Import Private Export Private (binary)", input, output, true);
189         }
190
191         // importing RSA keypair and exporting a RSA public key 
192         [Test]
193         public void RSAImportPrivateExportPublic () 
194         {
195                 RSAParameters input = GetKey (true);
196                 rsa.ImportParameters (input);
197                 string xmlRSA = rsa.ToXmlString (false);
198                 rsa.FromXmlString (xmlRSA);
199                 AssertEquals ("RSA Import Private Export Public (xml)", xmlPublic, xmlRSA);
200                 RSAParameters output = rsa.ExportParameters (false);
201                 AssertEquals ("RSA Import Private Export Public (binary)", input, output, false);
202         }
203
204         // importing RSA public key and exporting a RSA keypair (including private key!)
205         [Test]
206         [ExpectedException (typeof (ArgumentNullException))]
207         public void RSAImportPublicExportPrivate () 
208         {
209                 RSAParameters input = GetKey (false);
210                 rsa.ImportParameters (input);
211                 string xmlRSA = rsa.ToXmlString (true);
212                 //rsa.FromXmlString (xmlRSA);
213                 //RSAParameters output = rsa.ExportParameters (true);
214                 //AssertEquals ("RSA Import Public Export Private", input, output, true);
215         }
216
217         // importing RSA public key and exporting a RSA public key 
218         [Test]
219         public void RSAImportPublicExportPublic () 
220         {
221                 RSAParameters input = GetKey (false);
222                 rsa.ImportParameters (input);
223                 string xmlRSA = rsa.ToXmlString (false);
224                 rsa.FromXmlString (xmlRSA);
225                 AssertEquals ("RSA Import Public Export Public (xml)", xmlPublic, xmlRSA);
226                 RSAParameters output = rsa.ExportParameters (false);
227                 AssertEquals ("RSA Import Public Export Public (binary)", input, output, true);
228         }
229
230         [Test]
231         [ExpectedException (typeof (ArgumentNullException))]
232         public void FromXmlStringNull () 
233         {
234                 rsa.FromXmlString (null);
235         }
236
237         [Test]
238         public void FromXmlStringBadCase () 
239         {
240                 string xml = "<rsakEYvALUE><Modulus>u/gvCQaCzpwjOKwrnahx9zaNB+7UEEOkQNa28HRU9R+437qvA1wCq2HqSM7rb81Idu1SDWDh7EYZcZ2KW4uAf6+44KPfxzdyPua0t9k6JYTuamSdBglTdIg0skVFmDlO4KqxLXthpR9SeppB9sFof+JTcpjKKo9ZRvjl/Qkdvcs=</Modulus><Exponent>EQ==</Exponent></rsakEYvALUE>";
241                 rsa.FromXmlString (xml);
242                 AssertEquals ("BadCase", xmlPublic, rsa.ToXmlString (false));
243         }
244
245         [Test]
246         public void FromXmlStringBadTop () 
247         {
248                 string xml = "<MonoKeyValue><Modulus>u/gvCQaCzpwjOKwrnahx9zaNB+7UEEOkQNa28HRU9R+437qvA1wCq2HqSM7rb81Idu1SDWDh7EYZcZ2KW4uAf6+44KPfxzdyPua0t9k6JYTuamSdBglTdIg0skVFmDlO4KqxLXthpR9SeppB9sFof+JTcpjKKo9ZRvjl/Qkdvcs=</Modulus><Exponent>EQ==</Exponent></MonoKeyValue>";
249                 rsa.FromXmlString (xml);
250                 AssertEquals ("BadTop", xmlPublic, rsa.ToXmlString (false));
251         }
252
253         [Test]
254         [ExpectedException (typeof (CryptographicException))]
255         public void FromXmlStringBadItemCase ()
256         {
257                 string xml = "<RSAKeyValue><mODULUS>u/gvCQaCzpwjOKwrnahx9zaNB+7UEEOkQNa28HRU9R+437qvA1wCq2HqSM7rb81Idu1SDWDh7EYZcZ2KW4uAf6+44KPfxzdyPua0t9k6JYTuamSdBglTdIg0skVFmDlO4KqxLXthpR9SeppB9sFof+JTcpjKKo9ZRvjl/Qkdvcs=</mODULUS><eXPONENT>EQ==</eXPONENT></RSAKeyValue>";
258                 rsa.FromXmlString (xml);
259                 AssertEquals ("BadItemCase", xmlPublic, rsa.ToXmlString (false));
260         }
261 }
262
263 }