5 // Martin Baulig <martin.baulig@xamarin.com>
7 // Copyright (c) 2015 Xamarin, Inc.
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:
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
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
29 #if MONO_SECURITY_ALIAS
30 extern alias MonoSecurity;
33 #if MONO_SECURITY_ALIAS
34 using MonoSecurity::Mono.Security.Interface;
36 using Mono.Security.Interface;
39 using CipherAlgorithmType = System.Security.Authentication.CipherAlgorithmType;
40 using HashAlgorithmType = System.Security.Authentication.HashAlgorithmType;
41 using ExchangeAlgorithmType = System.Security.Authentication.ExchangeAlgorithmType;
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 using System.Threading.Tasks;
54 using MNS = Mono.Net.Security;
56 namespace System.Net.Security
59 * These two are defined by the referencesource; add them heere to make
60 * it easy to switch between the two implementations.
63 internal delegate bool RemoteCertValidationCallback (
65 X509Certificate certificate,
67 SslPolicyErrors sslPolicyErrors);
69 internal delegate X509Certificate LocalCertSelectionCallback (
71 X509CertificateCollection localCertificates,
72 X509Certificate remoteCertificate,
73 string[] acceptableIssuers);
75 public class SslStream : AuthenticatedStream
78 MonoTlsProvider provider;
81 internal IMonoSslStream Impl {
88 internal MonoTlsProvider Provider {
95 static MonoTlsProvider GetProvider ()
97 return MonoTlsProviderFactory.GetProvider ();
100 public SslStream (Stream innerStream)
101 : this (innerStream, false)
105 public SslStream (Stream innerStream, bool leaveInnerStreamOpen)
106 : base (innerStream, leaveInnerStreamOpen)
108 provider = GetProvider ();
109 impl = provider.CreateSslStreamInternal (this, innerStream, leaveInnerStreamOpen, null);
112 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback)
113 : this (innerStream, leaveInnerStreamOpen, userCertificateValidationCallback, null)
117 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback, LocalCertificateSelectionCallback userCertificateSelectionCallback)
118 : base (innerStream, leaveInnerStreamOpen)
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);
127 [MonoLimitation ("encryptionPolicy is ignored")]
128 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback, LocalCertificateSelectionCallback userCertificateSelectionCallback, EncryptionPolicy encryptionPolicy)
129 : this (innerStream, leaveInnerStreamOpen, userCertificateValidationCallback, userCertificateSelectionCallback)
133 SslStream (Stream innerStream, bool leaveInnerStreamOpen, MonoTlsProvider provider, MonoTlsSettings settings)
134 : base (innerStream, leaveInnerStreamOpen)
136 this.provider = provider;
137 impl = provider.CreateSslStreamInternal (this, innerStream, leaveInnerStreamOpen, settings);
140 internal static IMonoSslStream CreateMonoSslStream (Stream innerStream, bool leaveInnerStreamOpen, MonoTlsProvider provider, MonoTlsSettings settings)
142 var sslStream = new SslStream (innerStream, leaveInnerStreamOpen, provider, settings);
143 return sslStream.Impl;
146 public virtual void AuthenticateAsClient (string targetHost)
148 Impl.AuthenticateAsClient (targetHost);
151 public virtual void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
153 Impl.AuthenticateAsClient (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation);
156 // [HostProtection (ExternalThreading=true)]
157 public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState)
159 return Impl.BeginAuthenticateAsClient (targetHost, asyncCallback, asyncState);
162 // [HostProtection (ExternalThreading=true)]
163 public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
165 return Impl.BeginAuthenticateAsClient (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
168 public virtual void EndAuthenticateAsClient (IAsyncResult asyncResult)
170 Impl.EndAuthenticateAsClient (asyncResult);
173 public virtual void AuthenticateAsServer (X509Certificate serverCertificate)
175 Impl.AuthenticateAsServer (serverCertificate);
178 public virtual void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
180 Impl.AuthenticateAsServer (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation);
183 // [HostProtection (ExternalThreading=true)]
184 public virtual IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState)
186 return Impl.BeginAuthenticateAsServer (serverCertificate, asyncCallback, asyncState);
189 public virtual IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
191 return Impl.BeginAuthenticateAsServer (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
194 public virtual void EndAuthenticateAsServer (IAsyncResult asyncResult)
196 Impl.EndAuthenticateAsServer (asyncResult);
199 public TransportContext TransportContext {
201 throw new NotSupportedException();
205 // [HostProtection (ExternalThreading=true)]
206 public virtual Task AuthenticateAsClientAsync (string targetHost)
208 return Impl.AuthenticateAsClientAsync (targetHost);
211 public virtual Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
213 return Impl.AuthenticateAsClientAsync (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation);
216 public virtual Task AuthenticateAsServerAsync (X509Certificate serverCertificate)
218 return Impl.AuthenticateAsServerAsync (serverCertificate);
221 public virtual Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
223 return Impl.AuthenticateAsServerAsync (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation);
226 public override bool IsAuthenticated {
227 get { return Impl.IsAuthenticated; }
230 public override bool IsMutuallyAuthenticated {
231 get { return Impl.IsMutuallyAuthenticated; }
234 public override bool IsEncrypted {
235 get { return Impl.IsEncrypted; }
238 public override bool IsSigned {
239 get { return Impl.IsSigned; }
242 public override bool IsServer {
243 get { return Impl.IsServer; }
246 public virtual SslProtocols SslProtocol {
247 get { return (SslProtocols)Impl.SslProtocol; }
250 public virtual bool CheckCertRevocationStatus {
251 get { return Impl.CheckCertRevocationStatus; }
254 public virtual X509Certificate LocalCertificate {
255 get { return Impl.LocalCertificate; }
258 public virtual X509Certificate RemoteCertificate {
259 get { return Impl.RemoteCertificate; }
262 public virtual CipherAlgorithmType CipherAlgorithm {
263 get { return (CipherAlgorithmType)Impl.CipherAlgorithm; }
266 public virtual int CipherStrength {
267 get { return Impl.CipherStrength; }
270 public virtual HashAlgorithmType HashAlgorithm {
271 get { return (HashAlgorithmType)Impl.HashAlgorithm; }
274 public virtual int HashStrength {
275 get { return Impl.HashStrength; }
278 public virtual ExchangeAlgorithmType KeyExchangeAlgorithm {
279 get { return (ExchangeAlgorithmType)Impl.KeyExchangeAlgorithm; }
282 public virtual int KeyExchangeStrength {
283 get { return Impl.KeyExchangeStrength; }
286 public override bool CanSeek {
287 get { return false; }
290 public override bool CanRead {
291 get { return Impl.CanRead; }
294 public override bool CanTimeout {
295 get { return Impl.CanTimeout; }
298 public override bool CanWrite {
299 get { return Impl.CanWrite; }
302 public override int ReadTimeout {
303 get { return Impl.ReadTimeout; }
304 set { Impl.ReadTimeout = value; }
307 public override int WriteTimeout {
308 get { return Impl.WriteTimeout; }
309 set { Impl.WriteTimeout = value; }
312 public override long Length {
313 get { return Impl.Length; }
316 public override long Position {
317 get { return Impl.Position; }
319 throw new NotSupportedException (SR.GetString (SR.net_noseek));
323 public override void SetLength (long value)
325 Impl.SetLength (value);
328 public override long Seek (long offset, SeekOrigin origin)
330 throw new NotSupportedException (SR.GetString (SR.net_noseek));
333 public override void Flush ()
338 void CheckDisposed ()
341 throw new ObjectDisposedException ("SslStream");
344 protected override void Dispose (bool disposing)
347 if (impl != null && disposing) {
352 base.Dispose (disposing);
356 public override int Read (byte[] buffer, int offset, int count)
358 return Impl.Read (buffer, offset, count);
361 public void Write (byte[] buffer)
366 public override void Write (byte[] buffer, int offset, int count)
368 Impl.Write (buffer, offset, count);
371 // [HostProtection (ExternalThreading=true)]
372 public override IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
374 return Impl.BeginRead (buffer, offset, count, asyncCallback, asyncState);
377 public override int EndRead (IAsyncResult asyncResult)
379 return Impl.EndRead (asyncResult);
382 // [HostProtection (ExternalThreading=true)]
383 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
385 return Impl.BeginWrite (buffer, offset, count, asyncCallback, asyncState);
388 public override void EndWrite (IAsyncResult asyncResult)
390 Impl.EndWrite (asyncResult);
392 #else // !SECURITY_DEP
393 const string EXCEPTION_MESSAGE = "System.Net.Security.SslStream is not supported on the current platform.";
395 public SslStream (Stream innerStream)
396 : this (innerStream, false)
400 public SslStream (Stream innerStream, bool leaveInnerStreamOpen)
401 : base (innerStream, leaveInnerStreamOpen)
403 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
406 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback)
407 : this (innerStream, leaveInnerStreamOpen)
411 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback, LocalCertificateSelectionCallback userCertificateSelectionCallback)
412 : this (innerStream, leaveInnerStreamOpen)
416 public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback, LocalCertificateSelectionCallback userCertificateSelectionCallback, EncryptionPolicy encryptionPolicy)
417 : this (innerStream, leaveInnerStreamOpen)
421 public virtual void AuthenticateAsClient (string targetHost)
423 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
426 public virtual void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
428 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
431 public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState)
433 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
436 public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
438 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
441 public virtual void EndAuthenticateAsClient (IAsyncResult asyncResult)
443 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
446 public virtual void AuthenticateAsServer (X509Certificate serverCertificate)
448 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
451 public virtual void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
453 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
456 public virtual IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState)
458 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
461 public virtual IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
463 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
466 public virtual void EndAuthenticateAsServer (IAsyncResult asyncResult)
468 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
471 public TransportContext TransportContext {
472 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
475 public virtual Task AuthenticateAsClientAsync (string targetHost)
477 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
480 public virtual Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
482 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
485 public virtual Task AuthenticateAsServerAsync (X509Certificate serverCertificate)
487 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
490 public virtual Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
492 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
495 public override bool IsAuthenticated {
496 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
499 public override bool IsMutuallyAuthenticated {
500 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
503 public override bool IsEncrypted {
504 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
507 public override bool IsSigned {
508 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
511 public override bool IsServer {
512 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
515 public virtual SslProtocols SslProtocol {
516 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
519 public virtual bool CheckCertRevocationStatus {
520 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
523 public virtual X509Certificate LocalCertificate {
524 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
527 public virtual X509Certificate RemoteCertificate {
528 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
531 public virtual CipherAlgorithmType CipherAlgorithm {
532 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
535 public virtual int CipherStrength {
536 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
539 public virtual HashAlgorithmType HashAlgorithm {
540 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
543 public virtual int HashStrength {
544 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
547 public virtual ExchangeAlgorithmType KeyExchangeAlgorithm {
548 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
551 public virtual int KeyExchangeStrength {
552 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
555 public override bool CanSeek {
556 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
559 public override bool CanRead {
560 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
563 public override bool CanTimeout {
564 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
567 public override bool CanWrite {
568 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
571 public override int ReadTimeout {
572 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
573 set { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
576 public override int WriteTimeout {
577 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
578 set { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
581 public override long Length {
582 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
585 public override long Position {
586 get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
587 set { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
590 public override void SetLength (long value)
592 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
595 public override long Seek (long offset, SeekOrigin origin)
597 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
600 public override void Flush ()
602 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
605 protected override void Dispose (bool disposing)
609 public override int Read (byte[] buffer, int offset, int count)
611 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
614 public void Write (byte[] buffer)
616 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
619 public override void Write (byte[] buffer, int offset, int count)
621 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
624 public override IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
626 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
629 public override int EndRead (IAsyncResult asyncResult)
631 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
634 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
636 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
639 public override void EndWrite (IAsyncResult asyncResult)
641 throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);