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