[sgen] Untag the vtable during concurrent mark
[mono.git] / mcs / class / System / ReferenceSources / SSPISafeHandles.cs
1 //
2 // SafeHandles.cs
3 //
4 // Author:
5 //       Martin Baulig <martin.baulig@xamarin.com>
6 //
7 // Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // THE SOFTWARE.
26 #if MONO_FEATURE_NEW_TLS && SECURITY_DEP
27 #if MONO_SECURITY_ALIAS
28 extern alias MonoSecurity;
29 using IMonoTlsContext = MonoSecurity::Mono.Security.Interface.IMonoTlsContext;
30 #else
31 using IMonoTlsContext = Mono.Security.Interface.IMonoTlsContext;
32 #endif
33
34 using System.Runtime.InteropServices;
35 using System.Security.Cryptography.X509Certificates;
36
37 namespace System.Net.Security
38 {
39         class DummySafeHandle : SafeHandle
40         {
41                 protected DummySafeHandle ()
42                         : base ((IntPtr)(-1), true)
43                 {
44                 }
45
46                 protected override bool ReleaseHandle ()
47                 {
48                         return true;
49                 }
50
51                 public override bool IsInvalid {
52                         get { return handle == (IntPtr)(-1); }
53                 }
54         }
55
56         class SafeFreeCertContext : DummySafeHandle
57         {
58         }
59
60         class SafeFreeCredentials : DummySafeHandle
61         {
62                 SecureCredential credential;
63
64                 public X509Certificate2 Certificate {
65                         get {
66                                 if (IsInvalid)
67                                         throw new ObjectDisposedException ("Certificate");
68                                 return credential.certificate;
69                         }
70                 }
71
72                 public SafeFreeCredentials (SecureCredential credential)
73                 {
74                         this.credential = credential;
75                         bool success = true;
76                         DangerousAddRef (ref success);
77                 }
78
79                 public override bool IsInvalid {
80                         get {
81                                 return credential.certificate == null;
82                         }
83                 }
84
85                 protected override bool ReleaseHandle ()
86                 {
87                         credential.Clear ();
88                         return base.ReleaseHandle ();
89                 }
90         }
91
92         class SafeDeleteContext : DummySafeHandle
93         {
94                 IMonoTlsContext context;
95
96                 public IMonoTlsContext Context {
97                         get {
98                                 if (IsInvalid)
99                                         throw new ObjectDisposedException ("TlsContext");
100                                 return context;
101                         }
102                 }
103
104                 public SafeDeleteContext (IMonoTlsContext context)
105                 {
106                         this.context = context;
107                 }
108
109                 public override bool IsInvalid {
110                         get {
111                                 return context == null || !context.IsValid;
112                         }
113                 }
114
115                 protected override bool ReleaseHandle ()
116                 {
117                         context.Dispose ();
118                         context = null;
119                         return base.ReleaseHandle ();
120                 }
121         }
122
123         struct SecureCredential
124         {
125                 public const int CurrentVersion = 0x4;
126
127                 [Flags]
128                 public enum Flags
129                 {
130                         Zero = 0,
131                         NoSystemMapper = 0x02,
132                         NoNameCheck = 0x04,
133                         ValidateManual = 0x08,
134                         NoDefaultCred = 0x10,
135                         ValidateAuto = 0x20,
136                         SendAuxRecord = 0x00200000,
137                         UseStrongCrypto = 0x00400000
138                 }
139
140                 int version;
141                 internal X509Certificate2 certificate;
142                 SchProtocols protocols;
143                 EncryptionPolicy policy;
144
145                 public SecureCredential (int version, X509Certificate2 certificate, SecureCredential.Flags flags, SchProtocols protocols, EncryptionPolicy policy)
146                 {
147                         this.version = version;
148                         this.certificate = certificate;
149                         this.protocols = protocols;
150                         this.policy = policy;
151                 }
152
153                 public void Clear ()
154                 {
155                         certificate = null;
156                 }
157         }
158
159         internal class SafeCredentialReference : DummySafeHandle
160         {
161                 //
162                 // Static cache will return the target handle if found the reference in the table.
163                 //
164                 internal SafeFreeCredentials _Target;
165
166                 //
167                 //
168                 internal static SafeCredentialReference CreateReference (SafeFreeCredentials target)
169                 {
170                         SafeCredentialReference result = new SafeCredentialReference (target);
171                         if (result.IsInvalid)
172                                 return null;
173
174                         return result;
175                 }
176
177                 private SafeCredentialReference (SafeFreeCredentials target)
178                         : base ()
179                 {
180                         // Bumps up the refcount on Target to signify that target handle is statically cached so
181                         // its dispose should be postponed
182                         bool b = false;
183                         try {
184                                 target.DangerousAddRef (ref b);
185                         } catch {
186                                 if (b) {
187                                         target.DangerousRelease ();
188                                         b = false;
189                                 }
190                         } finally {
191                                 if (b) {
192                                         _Target = target;
193                                         SetHandle (new IntPtr (0));   // make this handle valid
194                                 }
195                         }
196                 }
197
198                 override protected bool ReleaseHandle ()
199                 {
200                         SafeFreeCredentials target = _Target;
201                         if (target != null)
202                                 target.DangerousRelease ();
203                         _Target = null;
204                         return true;
205                 }
206         }
207
208 }
209 #endif