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