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