Copied remotely
[mono.git] / mcs / class / System.Web / System.Web.Configuration / MachineKeyConfigHandler.cs
1 //
2 // System.Web.Configuration.MachineKeyConfigHandler
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2002 Ximian, Inc (http://www.ximian.com)
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System;
32 using System.Collections;
33 using System.Configuration;
34 using System.Security.Cryptography;
35 using System.Xml;
36
37 namespace System.Web.Configuration
38 {
39         class MachineKeyConfigHandler : IConfigurationSectionHandler
40         {
41                 static byte [] autogenerated;
42                 static MachineKeyConfigHandler ()
43                 {
44                         autogenerated = new byte [64];
45                         RNGCryptoServiceProvider cp = new RNGCryptoServiceProvider ();
46                         cp.GetBytes (autogenerated);
47                 }
48
49                 static byte ToHexValue (char c, bool high)
50                 {
51                         byte v;
52                         if (c >= '0' && c <= '9')
53                                 v = (byte) (c - '0');
54                         else if (c >= 'a' && c <= 'f')
55                                 v = (byte) (c - 'a' + 10);
56                         else if (c >= 'A' && c <= 'F')
57                                 v = (byte) (c - 'A' + 10);
58                         else
59                                 throw new ArgumentException ("Invalid hex character");
60
61                         if (high)
62                                 v <<= 4;
63
64                         return v;
65                 }
66                 
67                 internal static byte [] GetBytes (string key, int len)
68                 {
69                         byte [] result = new byte [len / 2];
70                         for (int i = 0; i < len; i += 2)
71                                 result [i / 2] = (byte) (ToHexValue (key [i], true) + ToHexValue (key [i + 1], false));
72
73                         return result;
74                 }
75
76                 static byte [] MakeKey (string key)
77                 {
78                         if (key == null || key == "AutoGenerated")
79                                 return autogenerated;
80
81                         int len = key.Length;
82                         if (len < 40 || len > 128 || (len % 2) == 1)
83                                 throw new ArgumentException ("Invalid key length");
84
85                         return GetBytes (key, len);
86                 }
87                 
88                 public object Create (object parent, object context, XmlNode section)
89                 {
90                         if (section.HasChildNodes)
91                                 ThrowException ("Child nodes not allowed here", section.FirstChild);
92
93                         MachineKeyConfig config = new MachineKeyConfig (parent);
94
95                         string validationKey = AttValue ("validationKey", section);
96                         try {
97                                 config.ValidationKey = MakeKey (validationKey);
98                         } catch (ArgumentException e) {
99                                 ThrowException (e.Message, section);
100                         }
101
102                         string decryptionKey = AttValue ("decryptionKey", section);
103                         try {
104                                 config.DecryptionKey = MakeKey (decryptionKey);
105                         } catch (ArgumentException e) {
106                                 ThrowException (e.Message, section);
107                         }
108
109                         string validation = AttValue ("validation", section);
110                         if (validation != "SHA1" && validation != "MD5" && validation != "3DES")
111                                 ThrowException ("Invalid 'validation' value", section);
112
113                         config.ValidationType = validation;
114
115                         if (section.Attributes != null && section.Attributes.Count != 0)
116                                 ThrowException ("Unrecognized attribute", section);
117
118                         MachineKeyConfig.MachineKey = config;
119                         return config;
120                 }
121
122                 // A few methods to save some typing
123                 static string AttValue (string name, XmlNode node)
124                 {
125                         return HandlersUtil.ExtractAttributeValue (name, node, true);
126                 }
127
128                 static void ThrowException (string message, XmlNode node)
129                 {
130                         HandlersUtil.ThrowException (message, node);
131                 }
132                 //
133
134         }
135 }
136