Added Mono.Tasklets test
[mono.git] / mcs / class / System.Security / System.Security.Cryptography / ProtectedData.cs
1 //
2 // ProtectedData.cs: Protect (encrypt) data without (user involved) key management
3 //
4 // Author:\r
5 //      Sebastien Pouliot  <sebastien@ximian.com>\r
6 //
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)\r
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)\r
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 \r
31 using System.Runtime.InteropServices;\r
32 using System.Security.Permissions;
33
34 using Mono.Security.Cryptography;
35
36 namespace System.Security.Cryptography {
37
38         // References:
39         // a.   Windows Data Protection
40         //      http://msdn.microsoft.com/library/en-us/dnsecure/html/windataprotection-dpapi.asp?frame=true
41
42         public sealed class ProtectedData {
43
44                 private ProtectedData ()
45                 {
46                 }
47
48 // FIXME        [DataProtectionPermission (SecurityAction.Demand, ProtectData = true)]\r
49                 public static byte[] Protect (byte[] userData, byte[] optionalEntropy, DataProtectionScope scope) 
50                 {
51                         if (userData == null)
52                                 throw new ArgumentNullException ("userData");
53
54                         // on Windows this is supported only under 2000 and later OS\r
55                         Check (scope);\r
56 \r
57                         switch (impl) {\r
58                         case DataProtectionImplementation.ManagedProtection:\r
59                                 try {\r
60                                         return ManagedProtection.Protect (userData, optionalEntropy, scope);\r
61                                 }\r
62                                 catch (Exception e) {\r
63                                         string msg = Locale.GetText ("Data protection failed.");\r
64                                         throw new CryptographicException (msg, e);\r
65                                 }\r
66                         case DataProtectionImplementation.Win32CryptoProtect:\r
67                                 try {\r
68                                         return NativeDapiProtection.Protect (userData, optionalEntropy, scope);\r
69                                 }\r
70                                 catch (Exception e) {\r
71                                         string msg = Locale.GetText ("Data protection failed.");\r
72                                         throw new CryptographicException (msg, e);\r
73                                 }\r
74                         default:\r
75                                 throw new PlatformNotSupportedException ();\r
76                         }\r
77                 }\r
78 \r
79 // FIXME        [DataProtectionPermission (SecurityAction.Demand, UnprotectData = true)]\r
80                 public static byte[] Unprotect (byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope) 
81                 {
82                         if (encryptedData == null)
83                                 throw new ArgumentNullException ("encryptedData");
84
85                         // on Windows this is supported only under 2000 and later OS\r
86                         Check (scope);\r
87 \r
88                         switch (impl) {\r
89                         case DataProtectionImplementation.ManagedProtection:\r
90                                 try {\r
91                                         return ManagedProtection.Unprotect (encryptedData, optionalEntropy, scope);\r
92                                 }\r
93                                 catch (Exception e) {\r
94                                         string msg = Locale.GetText ("Data unprotection failed.");\r
95                                         throw new CryptographicException (msg, e);\r
96                                 }\r
97                         case DataProtectionImplementation.Win32CryptoProtect:\r
98                                 try {\r
99                                         return NativeDapiProtection.Unprotect (encryptedData, optionalEntropy, scope);\r
100                                 }\r
101                                 catch (Exception e) {\r
102                                         string msg = Locale.GetText ("Data unprotection failed.");\r
103                                         throw new CryptographicException (msg, e);\r
104                                 }\r
105                         default:\r
106                                 throw new PlatformNotSupportedException ();\r
107                         }\r
108                 }
109
110                 // private stuff\r
111 \r
112                 enum DataProtectionImplementation {\r
113                         Unknown,\r
114                         Win32CryptoProtect,\r
115                         ManagedProtection,\r
116                         Unsupported = Int32.MinValue\r
117                 }\r
118 \r
119                 private static DataProtectionImplementation impl;\r
120 \r
121                 private static void Detect ()\r
122                 {\r
123                         OperatingSystem os = Environment.OSVersion;\r
124                         switch (os.Platform) {\r
125                         case PlatformID.Win32NT:\r
126                                 Version v = os.Version;\r
127                                 if (v.Major < 5) {\r
128                                         impl = DataProtectionImplementation.Unsupported;\r
129                                 } else {\r
130                                         // Windows 2000 (5.0) and later\r
131                                         impl = DataProtectionImplementation.Win32CryptoProtect;\r
132                                 }\r
133                                 break;\r
134                         case PlatformID.Unix:\r
135                                 impl = DataProtectionImplementation.ManagedProtection;\r
136                                 break;\r
137                         default:\r
138                                 impl = DataProtectionImplementation.Unsupported;\r
139                                 break;\r
140                         }\r
141                 }\r
142 \r
143                 private static void Check (DataProtectionScope scope)\r
144                 {\r
145                         if ((scope < DataProtectionScope.CurrentUser) || (scope > DataProtectionScope.LocalMachine)) {\r
146                                 string msg = Locale.GetText ("Invalid enum value '{0}' for '{1}'.", \r
147                                         scope, "DataProtectionScope");\r
148                                 throw new ArgumentException (msg, "scope");\r
149                         }\r
150 \r
151                         switch (impl) {\r
152                         case DataProtectionImplementation.Unknown:\r
153                                 Detect ();\r
154                                 break;\r
155                         case DataProtectionImplementation.Unsupported:\r
156                                 throw new PlatformNotSupportedException ();\r
157                         }\r
158                 }\r
159         }
160 }
161