New tests.
[mono.git] / mcs / class / corlib / System.Security.Cryptography / CryptoConfig_2_1.cs
1 //
2 // CryptoConfig.cs: Handles cryptographic implementations and OIDs mappings.
3 //
4 // Author:
5 //      Sebastien Pouliot (sebastien@ximian.com)
6 //      Tim Coleman (tim@timcoleman.com)
7 //
8 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
9 // Copyright (C) Tim Coleman, 2004
10 // Copyright (C) 2004-2007, 2009 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 namespace System.Security.Cryptography {
33
34         public partial class CryptoConfig {
35
36                 public static byte[] EncodeOID (string str)
37                 {
38                         if (str == null)
39                                 throw new ArgumentNullException ("str");
40                         char[] delim = { '.' };
41                         string[] parts = str.Split (delim);
42                         // according to X.208 n is always at least 2
43                         if (parts.Length < 2) {
44                                 throw new CryptographicUnexpectedOperationException (
45                                         Locale.GetText ("OID must have at least two parts"));
46                         }
47
48                         // we're sure that the encoded OID is shorter than its string representation
49                         byte[] oid = new byte [str.Length];
50                         // now encoding value
51                         try {
52                                 byte part0 = Convert.ToByte (parts [0]);
53                                 // OID[0] > 2 is invalid but "supported" in MS BCL
54                                 // uncomment next line to trap this error
55                                 // if (part0 > 2) throw new CryptographicUnexpectedOperationException ();
56                                 byte part1 = Convert.ToByte (parts [1]);
57                                 // OID[1] >= 40 is illegal for OID[0] < 2 because of the % 40
58                                 // however the syntax is "supported" in MS BCL
59                                 // uncomment next 2 lines to trap this error
60                                 //if ((part0 < 2) && (part1 >= 40))
61                                 //      throw new CryptographicUnexpectedOperationException ();
62                                 oid[2] = Convert.ToByte (part0 * 40 + part1);
63                         }
64                         catch {
65                                 throw new CryptographicUnexpectedOperationException (
66                                         Locale.GetText ("Invalid OID"));
67                         }
68                         int j = 3;
69                         for (int i = 2; i < parts.Length; i++) {
70                                 long x = Convert.ToInt64 (parts [i]);
71                                 if (x > 0x7F) {
72                                         byte[] num = EncodeLongNumber (x);
73                                         Buffer.BlockCopy (num, 0, oid, j, num.Length);
74                                         j += num.Length;
75                                 }
76                                 else
77                                         oid[j++] = Convert.ToByte (x);
78                         }
79
80                         int k = 2;
81                         // copy the exact number of byte required
82                         byte[] oid2 = new byte [j];
83                         oid2[0] = 0x06; // always - this tag means OID
84                         // Length (of value)
85                         if (j > 0x7F) {
86                                 // for compatibility with MS BCL
87                                 throw new CryptographicUnexpectedOperationException (
88                                         Locale.GetText ("OID > 127 bytes"));
89                                 // comment exception and uncomment next 3 lines to remove restriction
90                                 //byte[] num = EncodeLongNumber (j);
91                                 //Buffer.BlockCopy (num, 0, oid, j, num.Length);
92                                 //k = num.Length + 1;
93                         }
94                         else
95                                 oid2 [1] = Convert.ToByte (j - 2); 
96
97                         Buffer.BlockCopy (oid, k, oid2, k, j - k);
98                         return oid2;
99                 }
100
101                 // encode (7bits array) number greater than 127
102                 private static byte[] EncodeLongNumber (long x)
103                 {
104                         // for MS BCL compatibility
105                         // comment next two lines to remove restriction
106                         if ((x > Int32.MaxValue) || (x < Int32.MinValue))
107                                 throw new OverflowException (Locale.GetText ("Part of OID doesn't fit in Int32"));
108
109                         long y = x;
110                         // number of bytes required to encode this number
111                         int n = 1;
112                         while (y > 0x7F) {
113                                 y = y >> 7;
114                                 n++;
115                         }
116                         byte[] num = new byte [n];
117                         // encode all bytes 
118                         for (int i = 0; i < n; i++) {
119                                 y = x >> (7 * i);
120                                 y = y & 0x7F;
121                                 if (i != 0)
122                                         y += 0x80;
123                                 num[n-i-1] = Convert.ToByte (y);
124                         }
125                         return num;
126                 }
127 #if MOONLIGHT
128                 // we need SHA1 support to verify the codecs binary integrity
129                 public static string MapNameToOID (string name)
130                 {
131                         if ((name != null) && name.Contains ("SHA1"))
132                                 return "1.3.14.3.2.26";
133                         return String.Empty;
134                 }
135
136                 // non-configurable (versus machine.config) mappings for Moonlight (to avoid loading custom code)
137                 public static object CreateFromName (string name)
138                 {
139                         switch (name) {
140                         case "System.Security.Cryptography.HashAlgorithm":
141                         case "System.Security.Cryptography.SHA1":
142                         case "SHA1":
143                                 return new SHA1Managed ();
144                         case "SHA256":
145                                 return new SHA256Managed ();
146                         case "System.Security.Cryptography.MD5":
147                         case "MD5":
148                                 return new MD5CryptoServiceProvider ();
149                         case "System.Security.Cryptography.RandomNumberGenerator":
150                                 return new RNGCryptoServiceProvider ();
151                         case "System.Security.Cryptography.RSA":
152                                 return new Mono.Security.Cryptography.RSAManaged ();
153                         default:
154                                 throw new NotImplementedException (name);
155                         }
156                 }
157 #endif
158         }
159 }
160