Fix XMM scanning on Mac x86.
[mono.git] / mcs / class / System / System.Net.Security / SslStream.cs
1 //
2 // SslStream.cs
3 //
4 // Author:
5 //       Martin Baulig <martin.baulig@xamarin.com>
6 //
7 // Copyright (c) 2015 Xamarin, Inc.
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
27 #if SECURITY_DEP
28
29 #if MONO_SECURITY_ALIAS
30 extern alias MonoSecurity;
31 #endif
32
33 #if MONO_SECURITY_ALIAS
34 using MonoSecurity::Mono.Security.Interface;
35 #else
36 using Mono.Security.Interface;
37 #endif
38
39 using CipherAlgorithmType = System.Security.Authentication.CipherAlgorithmType;
40 using HashAlgorithmType = System.Security.Authentication.HashAlgorithmType;
41 using ExchangeAlgorithmType = System.Security.Authentication.ExchangeAlgorithmType;
42
43 using System;
44 using System.IO;
45 using System.Net;
46 using System.Net.Security;
47 using System.Security.Authentication;
48 using System.Security.Cryptography.X509Certificates;
49 using System.Security.Permissions;
50 using System.Security.Principal;
51 using System.Security.Cryptography;
52
53 using System.Threading.Tasks;
54
55 using MNS = Mono.Net.Security;
56
57 namespace System.Net.Security
58 {
59         /*
60          * These two are defined by the referencesource; add them heere to make
61          * it easy to switch between the two implementations.
62          */
63
64         internal delegate bool RemoteCertValidationCallback (
65                 string host,
66                 X509Certificate certificate,
67                 X509Chain chain,
68                 SslPolicyErrors sslPolicyErrors);
69
70         internal delegate X509Certificate LocalCertSelectionCallback (
71                 string targetHost,
72                 X509CertificateCollection localCertificates,
73                 X509Certificate remoteCertificate,
74                 string[] acceptableIssuers);
75
76         public class SslStream : AuthenticatedStream, MNS.IMonoSslStream
77         {
78                 MonoTlsProvider provider;
79                 IMonoSslStream impl;
80
81                 internal IMonoSslStream Impl {
82                         get {
83                                 CheckDisposed ();
84                                 return impl;
85                         }
86                 }
87
88                 internal MonoTlsProvider Provider {
89                         get {
90                                 CheckDisposed ();
91                                 return provider;
92                         }
93                 }
94
95                 static MonoTlsProvider GetProvider ()
96                 {
97 #pragma warning disable 612
98                         return MonoTlsProviderFactory.GetDefaultProvider ();
99 #pragma warning restore 612
100                 }
101
102                 public SslStream (Stream innerStream)
103                         : this (innerStream, false)
104                 {
105                 }
106
107                 public SslStream (Stream innerStream, bool leaveInnerStreamOpen)
108                         : base (innerStream, leaveInnerStreamOpen)
109                 {
110                         provider = GetProvider ();
111                         impl = provider.CreateSslStream (innerStream, leaveInnerStreamOpen);
112                 }
113
114                 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback)
115                         : this (innerStream, leaveInnerStreamOpen, userCertificateValidationCallback, null)
116                 {
117                 }
118
119                 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback, LocalCertificateSelectionCallback userCertificateSelectionCallback)
120                         : base (innerStream, leaveInnerStreamOpen)
121                 {
122                         provider = GetProvider ();
123                         var settings = MonoTlsSettings.CopyDefaultSettings ();
124                         settings.RemoteCertificateValidationCallback = MNS.Private.CallbackHelpers.PublicToMono (userCertificateValidationCallback);
125                         settings.ClientCertificateSelectionCallback = MNS.Private.CallbackHelpers.PublicToMono (userCertificateSelectionCallback);
126                         impl = provider.CreateSslStream (innerStream, leaveInnerStreamOpen, settings);
127                 }
128
129                 [MonoLimitation ("encryptionPolicy is ignored")]
130                 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback, LocalCertificateSelectionCallback userCertificateSelectionCallback, EncryptionPolicy encryptionPolicy)
131                 : this (innerStream, leaveInnerStreamOpen, userCertificateValidationCallback, userCertificateSelectionCallback)
132                 {
133                 }
134
135                 internal SslStream (Stream innerStream, bool leaveInnerStreamOpen, IMonoSslStream impl)
136                         : base (innerStream, leaveInnerStreamOpen)
137                 {
138                         this.impl = impl;
139                 }
140
141                 public virtual void AuthenticateAsClient (string targetHost)
142                 {
143                         Impl.AuthenticateAsClient (targetHost);
144                 }
145
146                 public virtual void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
147                 {
148                         Impl.AuthenticateAsClient (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation);
149                 }
150
151                 // [HostProtection (ExternalThreading=true)]
152                 public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState)
153                 {
154                         return Impl.BeginAuthenticateAsClient (targetHost, asyncCallback, asyncState);
155                 }
156
157                 // [HostProtection (ExternalThreading=true)]
158                 public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
159                 {
160                         return Impl.BeginAuthenticateAsClient (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
161                 }
162
163                 public virtual void EndAuthenticateAsClient (IAsyncResult asyncResult)
164                 {
165                         Impl.EndAuthenticateAsClient (asyncResult);
166                 }
167
168                 public virtual void AuthenticateAsServer (X509Certificate serverCertificate)
169                 {
170                         Impl.AuthenticateAsServer (serverCertificate);
171                 }
172
173                 public virtual void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
174                 {
175                         Impl.AuthenticateAsServer (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation);
176                 }
177
178                 // [HostProtection (ExternalThreading=true)]
179                 public virtual IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState)
180                 {
181                         return Impl.BeginAuthenticateAsServer (serverCertificate, asyncCallback, asyncState);
182                 }
183
184                 public virtual IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
185                 {
186                         return Impl.BeginAuthenticateAsServer (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
187                 }
188
189                 public virtual void EndAuthenticateAsServer (IAsyncResult asyncResult)
190                 {
191                         Impl.EndAuthenticateAsServer (asyncResult);
192                 }
193
194                 public TransportContext TransportContext {
195                         get {
196                                 throw new NotSupportedException();
197                         }
198                 }
199
200                 // [HostProtection (ExternalThreading=true)]
201                 public virtual Task AuthenticateAsClientAsync (string targetHost)
202                 {
203                         return Impl.AuthenticateAsClientAsync (targetHost);
204                 }
205
206                 public virtual Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
207                 {
208                         return Impl.AuthenticateAsClientAsync (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation);
209                 }
210
211                 public virtual Task AuthenticateAsServerAsync (X509Certificate serverCertificate)
212                 {
213                         return Impl.AuthenticateAsServerAsync (serverCertificate);
214                 }
215
216                 public virtual Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
217                 {
218                         return Impl.AuthenticateAsServerAsync (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation);
219                 }
220
221                 public override bool IsAuthenticated {
222                         get { return Impl.IsAuthenticated; }
223                 }
224
225                 public override bool IsMutuallyAuthenticated {
226                         get { return Impl.IsMutuallyAuthenticated; }
227                 }
228
229                 public override bool IsEncrypted {
230                         get { return Impl.IsEncrypted; }
231                 }
232
233                 public override bool IsSigned {
234                         get { return Impl.IsSigned; }
235                 }
236
237                 public override bool IsServer {
238                         get { return Impl.IsServer; }
239                 }
240
241                 public virtual SslProtocols SslProtocol {
242                         get { return (SslProtocols)Impl.SslProtocol; }
243                 }
244
245                 public virtual bool CheckCertRevocationStatus {
246                         get { return Impl.CheckCertRevocationStatus; }
247                 }
248
249                 X509Certificate MNS.IMonoSslStream.InternalLocalCertificate {
250                         get { return Impl.InternalLocalCertificate; }
251                 }
252
253                 public virtual X509Certificate LocalCertificate {
254                         get { return Impl.LocalCertificate; }
255                 }
256
257                 public virtual X509Certificate RemoteCertificate {
258                         get { return Impl.RemoteCertificate; }
259                 }
260
261                 public virtual CipherAlgorithmType CipherAlgorithm {
262                         get { return (CipherAlgorithmType)Impl.CipherAlgorithm; }
263                 }
264
265                 public virtual int CipherStrength {
266                         get { return Impl.CipherStrength; }
267                 }
268
269                 public virtual HashAlgorithmType HashAlgorithm {
270                         get { return (HashAlgorithmType)Impl.HashAlgorithm; }
271                 }
272
273                 public virtual int HashStrength {
274                         get { return Impl.HashStrength; }
275                 }
276
277                 public virtual ExchangeAlgorithmType KeyExchangeAlgorithm {
278                         get { return (ExchangeAlgorithmType)Impl.KeyExchangeAlgorithm; }
279                 }
280
281                 public virtual int KeyExchangeStrength {
282                         get { return Impl.KeyExchangeStrength; }
283                 }
284
285                 public override bool CanSeek {
286                         get { return false; }
287                 }
288
289                 public override bool CanRead {
290                         get { return Impl.CanRead; }
291                 }
292
293                 public override bool CanTimeout {
294                         get { return Impl.CanTimeout; }
295                 }
296
297                 public override bool CanWrite {
298                         get { return Impl.CanWrite; }
299                 }
300
301                 public override int ReadTimeout {
302                         get { return Impl.ReadTimeout; }
303                         set { Impl.ReadTimeout = value; }
304                 }
305
306                 public override int WriteTimeout {
307                         get { return Impl.WriteTimeout; }
308                         set { Impl.WriteTimeout = value; }
309                 }
310
311                 public override long Length {
312                         get { return Impl.Length; }
313                 }
314
315                 public override long Position {
316                         get { return Impl.Position; }
317                         set {
318                                 throw new NotSupportedException (SR.GetString (SR.net_noseek));
319                         }
320                 }
321
322                 public override void SetLength (long value)
323                 {
324                         Impl.SetLength (value);
325                 }
326
327                 public override long Seek (long offset, SeekOrigin origin)
328                 {
329                         throw new NotSupportedException (SR.GetString (SR.net_noseek));
330                 }
331
332                 public override void Flush ()
333                 {
334                         Impl.Flush ();
335                 }
336
337                 void CheckDisposed ()
338                 {
339                         if (impl == null)
340                                 throw new ObjectDisposedException ("SslStream");
341                 }
342
343                 protected override void Dispose (bool disposing)
344                 {
345                         try {
346                                 if (impl != null && disposing) {
347                                         impl.Dispose ();
348                                         impl = null;
349                                 }
350                         } finally {
351                                 base.Dispose (disposing);
352                         }
353                 }
354
355                 public override int Read (byte[] buffer, int offset, int count)
356                 {
357                         return Impl.Read (buffer, offset, count);
358                 }
359
360                 public void Write (byte[] buffer)
361                 {
362                         Impl.Write (buffer);
363                 }
364
365                 public override void Write (byte[] buffer, int offset, int count)
366                 {
367                         Impl.Write (buffer, offset, count);
368                 }
369
370                 // [HostProtection (ExternalThreading=true)]
371                 public override IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
372                 {
373                         return Impl.BeginRead (buffer, offset, count, asyncCallback, asyncState);
374                 }
375
376                 public override int EndRead (IAsyncResult asyncResult)
377                 {
378                         return Impl.EndRead (asyncResult);
379                 }
380
381                 // [HostProtection (ExternalThreading=true)]
382                 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
383                 {
384                         return Impl.BeginWrite (buffer, offset, count, asyncCallback, asyncState);
385                 }
386
387                 public override void EndWrite (IAsyncResult asyncResult)
388                 {
389                         Impl.EndWrite (asyncResult);
390                 }
391
392                 AuthenticatedStream MNS.IMonoSslStream.AuthenticatedStream {
393                         get { return this; }
394                 }
395
396                 MonoTlsProvider MNS.IMonoSslStream.Provider {
397                         get { return provider; }
398                 }
399
400                 MonoTlsConnectionInfo MNS.IMonoSslStream.GetConnectionInfo ()
401                 {
402                         return Impl.GetConnectionInfo ();
403                 }
404         }
405 }
406 #else // !SECURITY_DEP
407 namespace System.Net.Security
408 {
409         public class SslStream
410         {
411         }
412 }
413 #endif