Merge pull request #3766 from BrzVlad/feature-default-conc
[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                         return MonoTlsProviderFactory.GetDefaultProvider ();
98                 }
99
100                 public SslStream (Stream innerStream)
101                         : this (innerStream, false)
102                 {
103                 }
104
105                 public SslStream (Stream innerStream, bool leaveInnerStreamOpen)
106                         : base (innerStream, leaveInnerStreamOpen)
107                 {
108                         provider = GetProvider ();
109                         impl = provider.CreateSslStream (innerStream, leaveInnerStreamOpen);
110                 }
111
112                 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback)
113                         : this (innerStream, leaveInnerStreamOpen, userCertificateValidationCallback, null)
114                 {
115                 }
116
117                 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback, LocalCertificateSelectionCallback userCertificateSelectionCallback)
118                         : base (innerStream, leaveInnerStreamOpen)
119                 {
120                         provider = GetProvider ();
121                         var settings = MonoTlsSettings.CopyDefaultSettings ();
122                         settings.RemoteCertificateValidationCallback = MNS.Private.CallbackHelpers.PublicToMono (userCertificateValidationCallback);
123                         settings.ClientCertificateSelectionCallback = MNS.Private.CallbackHelpers.PublicToMono (userCertificateSelectionCallback);
124                         impl = provider.CreateSslStream (innerStream, leaveInnerStreamOpen, settings);
125                 }
126
127                 [MonoLimitation ("encryptionPolicy is ignored")]
128                 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback, LocalCertificateSelectionCallback userCertificateSelectionCallback, EncryptionPolicy encryptionPolicy)
129                 : this (innerStream, leaveInnerStreamOpen, userCertificateValidationCallback, userCertificateSelectionCallback)
130                 {
131                 }
132
133                 internal SslStream (Stream innerStream, bool leaveInnerStreamOpen, IMonoSslStream impl)
134                         : base (innerStream, leaveInnerStreamOpen)
135                 {
136                         this.impl = impl;
137                 }
138
139                 public virtual void AuthenticateAsClient (string targetHost)
140                 {
141                         Impl.AuthenticateAsClient (targetHost);
142                 }
143
144                 public virtual void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
145                 {
146                         Impl.AuthenticateAsClient (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation);
147                 }
148
149                 // [HostProtection (ExternalThreading=true)]
150                 public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState)
151                 {
152                         return Impl.BeginAuthenticateAsClient (targetHost, asyncCallback, asyncState);
153                 }
154
155                 // [HostProtection (ExternalThreading=true)]
156                 public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
157                 {
158                         return Impl.BeginAuthenticateAsClient (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
159                 }
160
161                 public virtual void EndAuthenticateAsClient (IAsyncResult asyncResult)
162                 {
163                         Impl.EndAuthenticateAsClient (asyncResult);
164                 }
165
166                 public virtual void AuthenticateAsServer (X509Certificate serverCertificate)
167                 {
168                         Impl.AuthenticateAsServer (serverCertificate);
169                 }
170
171                 public virtual void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
172                 {
173                         Impl.AuthenticateAsServer (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation);
174                 }
175
176                 // [HostProtection (ExternalThreading=true)]
177                 public virtual IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState)
178                 {
179                         return Impl.BeginAuthenticateAsServer (serverCertificate, asyncCallback, asyncState);
180                 }
181
182                 public virtual IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
183                 {
184                         return Impl.BeginAuthenticateAsServer (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
185                 }
186
187                 public virtual void EndAuthenticateAsServer (IAsyncResult asyncResult)
188                 {
189                         Impl.EndAuthenticateAsServer (asyncResult);
190                 }
191
192                 public TransportContext TransportContext {
193                         get {
194                                 throw new NotSupportedException();
195                         }
196                 }
197
198                 // [HostProtection (ExternalThreading=true)]
199                 public virtual Task AuthenticateAsClientAsync (string targetHost)
200                 {
201                         return Impl.AuthenticateAsClientAsync (targetHost);
202                 }
203
204                 public virtual Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
205                 {
206                         return Impl.AuthenticateAsClientAsync (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation);
207                 }
208
209                 public virtual Task AuthenticateAsServerAsync (X509Certificate serverCertificate)
210                 {
211                         return Impl.AuthenticateAsServerAsync (serverCertificate);
212                 }
213
214                 public virtual Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
215                 {
216                         return Impl.AuthenticateAsServerAsync (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation);
217                 }
218
219                 public override bool IsAuthenticated {
220                         get { return Impl.IsAuthenticated; }
221                 }
222
223                 public override bool IsMutuallyAuthenticated {
224                         get { return Impl.IsMutuallyAuthenticated; }
225                 }
226
227                 public override bool IsEncrypted {
228                         get { return Impl.IsEncrypted; }
229                 }
230
231                 public override bool IsSigned {
232                         get { return Impl.IsSigned; }
233                 }
234
235                 public override bool IsServer {
236                         get { return Impl.IsServer; }
237                 }
238
239                 public virtual SslProtocols SslProtocol {
240                         get { return (SslProtocols)Impl.SslProtocol; }
241                 }
242
243                 public virtual bool CheckCertRevocationStatus {
244                         get { return Impl.CheckCertRevocationStatus; }
245                 }
246
247                 X509Certificate MNS.IMonoSslStream.InternalLocalCertificate {
248                         get { return Impl.InternalLocalCertificate; }
249                 }
250
251                 public virtual X509Certificate LocalCertificate {
252                         get { return Impl.LocalCertificate; }
253                 }
254
255                 public virtual X509Certificate RemoteCertificate {
256                         get { return Impl.RemoteCertificate; }
257                 }
258
259                 public virtual CipherAlgorithmType CipherAlgorithm {
260                         get { return (CipherAlgorithmType)Impl.CipherAlgorithm; }
261                 }
262
263                 public virtual int CipherStrength {
264                         get { return Impl.CipherStrength; }
265                 }
266
267                 public virtual HashAlgorithmType HashAlgorithm {
268                         get { return (HashAlgorithmType)Impl.HashAlgorithm; }
269                 }
270
271                 public virtual int HashStrength {
272                         get { return Impl.HashStrength; }
273                 }
274
275                 public virtual ExchangeAlgorithmType KeyExchangeAlgorithm {
276                         get { return (ExchangeAlgorithmType)Impl.KeyExchangeAlgorithm; }
277                 }
278
279                 public virtual int KeyExchangeStrength {
280                         get { return Impl.KeyExchangeStrength; }
281                 }
282
283                 public override bool CanSeek {
284                         get { return false; }
285                 }
286
287                 public override bool CanRead {
288                         get { return Impl.CanRead; }
289                 }
290
291                 public override bool CanTimeout {
292                         get { return Impl.CanTimeout; }
293                 }
294
295                 public override bool CanWrite {
296                         get { return Impl.CanWrite; }
297                 }
298
299                 public override int ReadTimeout {
300                         get { return Impl.ReadTimeout; }
301                         set { Impl.ReadTimeout = value; }
302                 }
303
304                 public override int WriteTimeout {
305                         get { return Impl.WriteTimeout; }
306                         set { Impl.WriteTimeout = value; }
307                 }
308
309                 public override long Length {
310                         get { return Impl.Length; }
311                 }
312
313                 public override long Position {
314                         get { return Impl.Position; }
315                         set {
316                                 throw new NotSupportedException (SR.GetString (SR.net_noseek));
317                         }
318                 }
319
320                 public override void SetLength (long value)
321                 {
322                         Impl.SetLength (value);
323                 }
324
325                 public override long Seek (long offset, SeekOrigin origin)
326                 {
327                         throw new NotSupportedException (SR.GetString (SR.net_noseek));
328                 }
329
330                 public override void Flush ()
331                 {
332                         Impl.Flush ();
333                 }
334
335                 void CheckDisposed ()
336                 {
337                         if (impl == null)
338                                 throw new ObjectDisposedException ("SslStream");
339                 }
340
341                 protected override void Dispose (bool disposing)
342                 {
343                         try {
344                                 if (impl != null && disposing) {
345                                         impl.Dispose ();
346                                         impl = null;
347                                 }
348                         } finally {
349                                 base.Dispose (disposing);
350                         }
351                 }
352
353                 public override int Read (byte[] buffer, int offset, int count)
354                 {
355                         return Impl.Read (buffer, offset, count);
356                 }
357
358                 public void Write (byte[] buffer)
359                 {
360                         Impl.Write (buffer);
361                 }
362
363                 public override void Write (byte[] buffer, int offset, int count)
364                 {
365                         Impl.Write (buffer, offset, count);
366                 }
367
368                 // [HostProtection (ExternalThreading=true)]
369                 public override IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
370                 {
371                         return Impl.BeginRead (buffer, offset, count, asyncCallback, asyncState);
372                 }
373
374                 public override int EndRead (IAsyncResult asyncResult)
375                 {
376                         return Impl.EndRead (asyncResult);
377                 }
378
379                 // [HostProtection (ExternalThreading=true)]
380                 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
381                 {
382                         return Impl.BeginWrite (buffer, offset, count, asyncCallback, asyncState);
383                 }
384
385                 public override void EndWrite (IAsyncResult asyncResult)
386                 {
387                         Impl.EndWrite (asyncResult);
388                 }
389
390                 AuthenticatedStream MNS.IMonoSslStream.AuthenticatedStream {
391                         get { return this; }
392                 }
393
394                 MonoTlsProvider MNS.IMonoSslStream.Provider {
395                         get { return provider; }
396                 }
397
398                 MonoTlsConnectionInfo MNS.IMonoSslStream.GetConnectionInfo ()
399                 {
400                         return Impl.GetConnectionInfo ();
401                 }
402         }
403 }
404 #else // !SECURITY_DEP
405 namespace System.Net.Security
406 {
407         public class SslStream
408         {
409         }
410 }
411 #endif