Merge pull request #3248 from esdrubal/web_request_abort
[mono.git] / mcs / class / System.Security / System.Security.Cryptography / ProtectedData.cs
1 //\r
2 // ProtectedData.cs: Protect (encrypt) data without (user involved) key management\r
3 //\r
4 // Author:\r
5 //      Sebastien Pouliot  <sebastien@ximian.com>\r
6 //\r
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)\r
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)\r
9 //\r
10 // Permission is hereby granted, free of charge, to any person obtaining\r
11 // a copy of this software and associated documentation files (the\r
12 // "Software"), to deal in the Software without restriction, including\r
13 // without limitation the rights to use, copy, modify, merge, publish,\r
14 // distribute, sublicense, and/or sell copies of the Software, and to\r
15 // permit persons to whom the Software is furnished to do so, subject to\r
16 // the following conditions:\r
17 // \r
18 // The above copyright notice and this permission notice shall be\r
19 // included in all copies or substantial portions of the Software.\r
20 // \r
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
28 //\r
29 \r
30 \r
31 using System.Runtime.InteropServices;\r
32 using System.Security.Permissions;\r
33 \r
34 using Mono.Security.Cryptography;\r
35 \r
36 namespace System.Security.Cryptography {\r
37 \r
38         // References:\r
39         // a.   Windows Data Protection\r
40         //      http://msdn.microsoft.com/library/en-us/dnsecure/html/windataprotection-dpapi.asp?frame=true\r
41 \r
42         public sealed class ProtectedData {\r
43 \r
44                 private ProtectedData ()\r
45                 {\r
46                 }\r
47 \r
48 // FIXME        [DataProtectionPermission (SecurityAction.Demand, ProtectData = true)]\r
49                 public static byte[] Protect (byte[] userData, byte[] optionalEntropy, DataProtectionScope scope) \r
50                 {\r
51                         if (userData == null)\r
52                                 throw new ArgumentNullException ("userData");\r
53 \r
54                         // on Windows this is supported only under 2000 and later OS\r
55                         Check (scope);\r
56 \r
57                         switch (impl) {\r
58 #if !MOBILE\r
59                         case DataProtectionImplementation.ManagedProtection:\r
60                                 try {\r
61                                         return ManagedProtection.Protect (userData, optionalEntropy, scope);\r
62                                 }\r
63                                 catch (Exception e) {\r
64                                         string msg = Locale.GetText ("Data protection failed.");\r
65                                         throw new CryptographicException (msg, e);\r
66                                 }\r
67                         case DataProtectionImplementation.Win32CryptoProtect:\r
68                                 try {\r
69                                         return NativeDapiProtection.Protect (userData, optionalEntropy, scope);\r
70                                 }\r
71                                 catch (Exception e) {\r
72                                         string msg = Locale.GetText ("Data protection failed.");\r
73                                         throw new CryptographicException (msg, e);\r
74                                 }\r
75 #endif\r
76                         default:\r
77                                 throw new PlatformNotSupportedException ();\r
78                         }\r
79                 }\r
80 \r
81 // FIXME        [DataProtectionPermission (SecurityAction.Demand, UnprotectData = true)]\r
82                 public static byte[] Unprotect (byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope) \r
83                 {\r
84                         if (encryptedData == null)\r
85                                 throw new ArgumentNullException ("encryptedData");\r
86 \r
87                         // on Windows this is supported only under 2000 and later OS\r
88                         Check (scope);\r
89 \r
90                         switch (impl) {\r
91 #if !MOBILE\r
92                         case DataProtectionImplementation.ManagedProtection:\r
93                                 try {\r
94                                         return ManagedProtection.Unprotect (encryptedData, optionalEntropy, scope);\r
95                                 }\r
96                                 catch (Exception e) {\r
97                                         string msg = Locale.GetText ("Data unprotection failed.");\r
98                                         throw new CryptographicException (msg, e);\r
99                                 }\r
100                         case DataProtectionImplementation.Win32CryptoProtect:\r
101                                 try {\r
102                                         return NativeDapiProtection.Unprotect (encryptedData, optionalEntropy, scope);\r
103                                 }\r
104                                 catch (Exception e) {\r
105                                         string msg = Locale.GetText ("Data unprotection failed.");\r
106                                         throw new CryptographicException (msg, e);\r
107                                 }\r
108 #endif\r
109                         default:\r
110                                 throw new PlatformNotSupportedException ();\r
111                         }\r
112                 }\r
113 \r
114                 // private stuff\r
115 \r
116                 enum DataProtectionImplementation {\r
117                         Unknown,\r
118                         Win32CryptoProtect,\r
119                         ManagedProtection,\r
120                         Unsupported = Int32.MinValue\r
121                 }\r
122 \r
123                 private static DataProtectionImplementation impl;\r
124 \r
125                 private static void Detect ()\r
126                 {\r
127                         OperatingSystem os = Environment.OSVersion;\r
128                         switch (os.Platform) {\r
129                         case PlatformID.Win32NT:\r
130                                 Version v = os.Version;\r
131                                 if (v.Major < 5) {\r
132                                         impl = DataProtectionImplementation.Unsupported;\r
133                                 } else {\r
134                                         // Windows 2000 (5.0) and later\r
135                                         impl = DataProtectionImplementation.Win32CryptoProtect;\r
136                                 }\r
137                                 break;\r
138                         case PlatformID.Unix:\r
139                                 impl = DataProtectionImplementation.ManagedProtection;\r
140                                 break;\r
141                         default:\r
142                                 impl = DataProtectionImplementation.Unsupported;\r
143                                 break;\r
144                         }\r
145                 }\r
146 \r
147                 private static void Check (DataProtectionScope scope)\r
148                 {\r
149                         if ((scope < DataProtectionScope.CurrentUser) || (scope > DataProtectionScope.LocalMachine)) {\r
150                                 string msg = Locale.GetText ("Invalid enum value '{0}' for '{1}'.", \r
151                                         scope, "DataProtectionScope");\r
152                                 throw new ArgumentException (msg, "scope");\r
153                         }\r
154 \r
155                         switch (impl) {\r
156                         case DataProtectionImplementation.Unknown:\r
157                                 Detect ();\r
158                                 break;\r
159                         case DataProtectionImplementation.Unsupported:\r
160                                 throw new PlatformNotSupportedException ();\r
161                         }\r
162                 }\r
163         }\r
164 }\r
165 \r