2004-05-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[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 using System;
11 using System.Collections;
12 using System.Configuration;
13 using System.Security.Cryptography;
14 using System.Xml;
15
16 namespace System.Web.Configuration
17 {
18         class MachineKeyConfigHandler : IConfigurationSectionHandler
19         {
20                 static byte [] autogenerated;
21                 static MachineKeyConfigHandler ()
22                 {
23                         autogenerated = new byte [64];
24                         RNGCryptoServiceProvider cp = new RNGCryptoServiceProvider ();
25                         cp.GetBytes (autogenerated);
26                 }
27
28                 static byte ToHexValue (char c, bool high)
29                 {
30                         byte v;
31                         if (c >= '0' && c <= '9')
32                                 v = (byte) (c - '0');
33                         else if (c >= 'a' && c <= 'f')
34                                 v = (byte) (c - 'a' + 10);
35                         else if (c >= 'A' && c <= 'F')
36                                 v = (byte) (c - 'A' + 10);
37                         else
38                                 throw new ArgumentException ("Invalid hex character");
39
40                         if (high)
41                                 v <<= 4;
42
43                         return v;
44                 }
45                 
46                 internal static byte [] GetBytes (string key, int len)
47                 {
48                         byte [] result = new byte [len / 2];
49                         for (int i = 0; i < len; i += 2)
50                                 result [i / 2] = (byte) (ToHexValue (key [i], true) + ToHexValue (key [i + 1], false));
51
52                         return result;
53                 }
54
55                 static byte [] MakeKey (string key)
56                 {
57                         if (key == null || key == "AutoGenerated")
58                                 return autogenerated;
59
60                         int len = key.Length;
61                         if (len < 40 || len > 128 || (len % 2) == 1)
62                                 throw new ArgumentException ("Invalid key length");
63
64                         return GetBytes (key, len);
65                 }
66                 
67                 public object Create (object parent, object context, XmlNode section)
68                 {
69                         if (section.HasChildNodes)
70                                 ThrowException ("Child nodes not allowed here", section.FirstChild);
71
72                         MachineKeyConfig config = new MachineKeyConfig (parent);
73
74                         string validationKey = AttValue ("validationKey", section);
75                         try {
76                                 config.ValidationKey = MakeKey (validationKey);
77                         } catch (ArgumentException e) {
78                                 ThrowException (e.Message, section);
79                         }
80
81                         string decryptionKey = AttValue ("decryptionKey", section);
82                         try {
83                                 config.DecryptionKey = MakeKey (decryptionKey);
84                         } catch (ArgumentException e) {
85                                 ThrowException (e.Message, section);
86                         }
87
88                         string validation = AttValue ("validation", section);
89                         if (validation != "SHA1" && validation != "MD5" && validation != "3DES")
90                                 ThrowException ("Invalid 'validation' value", section);
91
92                         config.ValidationType = validation;
93
94                         if (section.Attributes != null && section.Attributes.Count != 0)
95                                 ThrowException ("Unrecognized attribute", section);
96
97                         MachineKeyConfig.MachineKey = config;
98                         return config;
99                 }
100
101                 // A few methods to save some typing
102                 static string AttValue (string name, XmlNode node)
103                 {
104                         return HandlersUtil.ExtractAttributeValue (name, node, true);
105                 }
106
107                 static void ThrowException (string message, XmlNode node)
108                 {
109                         HandlersUtil.ThrowException (message, node);
110                 }
111                 //
112
113         }
114 }
115