1 // 2 // System.Net.Security.SslStream.cs 3 // 4 // Authors: 5 // Tim Coleman (tim@timcoleman.com) 6 // Atsushi Enomoto (atsushi@ximian.com) 7 // Marek Safar (marek.safar@gmail.com) 8 // 9 // Copyright (C) Tim Coleman, 2004 10 // (c) 2004,2007 Novell, Inc. (http://www.novell.com) 11 // Copyright 2011 Xamarin Inc. 12 // 13 14 // 15 // Permission is hereby granted, free of charge, to any person obtaining 16 // a copy of this software and associated documentation files (the 17 // "Software"), to deal in the Software without restriction, including 18 // without limitation the rights to use, copy, modify, merge, publish, 19 // distribute, sublicense, and/or sell copies of the Software, and to 20 // permit persons to whom the Software is furnished to do so, subject to 21 // the following conditions: 22 // 23 // The above copyright notice and this permission notice shall be 24 // included in all copies or substantial portions of the Software. 25 // 26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 33 // 34 35 #if SECURITY_DEP 36 37 #if MONO_SECURITY_ALIAS 38 extern alias MonoSecurity; 39 #endif 40 41 #if MONO_SECURITY_ALIAS 42 using MonoCipherAlgorithmType = MonoSecurity::Mono.Security.Protocol.Tls.CipherAlgorithmType; 43 using MonoHashAlgorithmType = MonoSecurity::Mono.Security.Protocol.Tls.HashAlgorithmType; 44 using MonoExchangeAlgorithmType = MonoSecurity::Mono.Security.Protocol.Tls.ExchangeAlgorithmType; 45 using MonoSecurityProtocolType = MonoSecurity::Mono.Security.Protocol.Tls.SecurityProtocolType; 46 using MonoSecurity::Mono.Security.Protocol.Tls; 47 using MonoSecurity::Mono.Security.Interface; 48 #else 49 using MonoCipherAlgorithmType = Mono.Security.Protocol.Tls.CipherAlgorithmType; 50 using MonoHashAlgorithmType = Mono.Security.Protocol.Tls.HashAlgorithmType; 51 using MonoExchangeAlgorithmType = Mono.Security.Protocol.Tls.ExchangeAlgorithmType; 52 using MonoSecurityProtocolType = Mono.Security.Protocol.Tls.SecurityProtocolType; 53 using Mono.Security.Protocol.Tls; 54 using Mono.Security.Interface; 55 #endif 56 57 using CipherAlgorithmType = System.Security.Authentication.CipherAlgorithmType; 58 using HashAlgorithmType = System.Security.Authentication.HashAlgorithmType; 59 using ExchangeAlgorithmType = System.Security.Authentication.ExchangeAlgorithmType; 60 61 using System; 62 using System.IO; 63 using System.Net; 64 using System.Net.Security; 65 using System.Security.Authentication; 66 using System.Security.Cryptography.X509Certificates; 67 using System.Security.Principal; 68 using System.Security.Cryptography; 69 70 using System.Threading.Tasks; 71 72 namespace Mono.Net.Security.Private 73 { 74 /* 75 * Strictly private - do not use outside the Mono.Net.Security directory. 76 */ 77 [MonoTODO ("Non-X509Certificate2 certificate is not supported")] 78 internal class LegacySslStream : AuthenticatedStream, IMonoSslStream 79 { 80 #region Fields 81 82 SslStreamBase ssl_stream; 83 ICertificateValidator certificateValidator; 84 85 #endregion // Fields 86 87 #region Constructors 88 LegacySslStream(Stream innerStream, bool leaveInnerStreamOpen, SslStream owner, MonoTlsProvider provider, MonoTlsSettings settings)89 public LegacySslStream (Stream innerStream, bool leaveInnerStreamOpen, SslStream owner, MonoTlsProvider provider, MonoTlsSettings settings) 90 : base (innerStream, leaveInnerStreamOpen) 91 { 92 SslStream = owner; 93 Provider = provider; 94 certificateValidator = ChainValidationHelper.GetInternalValidator (provider, settings); 95 } 96 #endregion // Constructors 97 98 #region Properties 99 100 public override bool CanRead { 101 get { return InnerStream.CanRead; } 102 } 103 104 public override bool CanSeek { 105 get { return InnerStream.CanSeek; } 106 } 107 108 public override bool CanTimeout { 109 get { return InnerStream.CanTimeout; } 110 } 111 112 public override bool CanWrite { 113 get { return InnerStream.CanWrite; } 114 } 115 116 public override long Length { 117 get { return InnerStream.Length; } 118 } 119 120 public override long Position { 121 get { return InnerStream.Position; } 122 set { 123 throw new NotSupportedException ("This stream does not support seek operations"); 124 } 125 } 126 127 // AuthenticatedStream overrides 128 129 public override bool IsAuthenticated { 130 get { return ssl_stream != null; } 131 } 132 133 public override bool IsEncrypted { 134 get { return IsAuthenticated; } 135 } 136 137 public override bool IsMutuallyAuthenticated { 138 get { return IsAuthenticated && (IsServer ? RemoteCertificate != null : LocalCertificate != null); } 139 } 140 141 public override bool IsServer { 142 get { return ssl_stream is SslServerStream; } 143 } 144 145 public override bool IsSigned { 146 get { return IsAuthenticated; } 147 } 148 149 public override int ReadTimeout { 150 get { return InnerStream.ReadTimeout; } 151 set { InnerStream.ReadTimeout = value; } 152 } 153 154 public override int WriteTimeout { 155 get { return InnerStream.WriteTimeout; } 156 set { InnerStream.WriteTimeout = value; } 157 } 158 159 // SslStream 160 161 public virtual bool CheckCertRevocationStatus { 162 get { 163 if (!IsAuthenticated) 164 return false; 165 166 return ssl_stream.CheckCertRevocationStatus; 167 } 168 } 169 170 public virtual CipherAlgorithmType CipherAlgorithm { 171 get { 172 CheckConnectionAuthenticated (); 173 174 switch (ssl_stream.CipherAlgorithm) { 175 case MonoCipherAlgorithmType.Des: 176 return CipherAlgorithmType.Des; 177 case MonoCipherAlgorithmType.None: 178 return CipherAlgorithmType.None; 179 case MonoCipherAlgorithmType.Rc2: 180 return CipherAlgorithmType.Rc2; 181 case MonoCipherAlgorithmType.Rc4: 182 return CipherAlgorithmType.Rc4; 183 case MonoCipherAlgorithmType.SkipJack: 184 break; 185 case MonoCipherAlgorithmType.TripleDes: 186 return CipherAlgorithmType.TripleDes; 187 case MonoCipherAlgorithmType.Rijndael: 188 switch (ssl_stream.CipherStrength) { 189 case 128: 190 return CipherAlgorithmType.Aes128; 191 case 192: 192 return CipherAlgorithmType.Aes192; 193 case 256: 194 return CipherAlgorithmType.Aes256; 195 } 196 break; 197 } 198 199 throw new InvalidOperationException ("Not supported cipher algorithm is in use. It is likely a bug in SslStream."); 200 } 201 } 202 203 public virtual int CipherStrength { 204 get { 205 CheckConnectionAuthenticated (); 206 207 return ssl_stream.CipherStrength; 208 } 209 } 210 211 public virtual HashAlgorithmType HashAlgorithm { 212 get { 213 CheckConnectionAuthenticated (); 214 215 switch (ssl_stream.HashAlgorithm) { 216 case MonoHashAlgorithmType.Md5: 217 return HashAlgorithmType.Md5; 218 case MonoHashAlgorithmType.None: 219 return HashAlgorithmType.None; 220 case MonoHashAlgorithmType.Sha1: 221 return HashAlgorithmType.Sha1; 222 } 223 224 throw new InvalidOperationException ("Not supported hash algorithm is in use. It is likely a bug in SslStream."); 225 } 226 } 227 228 public virtual int HashStrength { 229 get { 230 CheckConnectionAuthenticated (); 231 232 return ssl_stream.HashStrength; 233 } 234 } 235 236 public virtual ExchangeAlgorithmType KeyExchangeAlgorithm { 237 get { 238 CheckConnectionAuthenticated (); 239 240 switch (ssl_stream.KeyExchangeAlgorithm) { 241 case MonoExchangeAlgorithmType.DiffieHellman: 242 return ExchangeAlgorithmType.DiffieHellman; 243 case MonoExchangeAlgorithmType.Fortezza: 244 break; 245 case MonoExchangeAlgorithmType.None: 246 return ExchangeAlgorithmType.None; 247 case MonoExchangeAlgorithmType.RsaKeyX: 248 return ExchangeAlgorithmType.RsaKeyX; 249 case MonoExchangeAlgorithmType.RsaSign: 250 return ExchangeAlgorithmType.RsaSign; 251 } 252 253 throw new InvalidOperationException ("Not supported exchange algorithm is in use. It is likely a bug in SslStream."); 254 } 255 } 256 257 public virtual int KeyExchangeStrength { 258 get { 259 CheckConnectionAuthenticated (); 260 261 return ssl_stream.KeyExchangeStrength; 262 } 263 } 264 265 X509Certificate IMonoSslStream.InternalLocalCertificate { 266 get { 267 return IsServer ? ssl_stream.ServerCertificate : ((SslClientStream) ssl_stream).SelectedClientCertificate; 268 } 269 } 270 271 public virtual X509Certificate LocalCertificate { 272 get { 273 CheckConnectionAuthenticated (); 274 275 return IsServer ? ssl_stream.ServerCertificate : ((SslClientStream) ssl_stream).SelectedClientCertificate; 276 } 277 } 278 279 public virtual X509Certificate RemoteCertificate { 280 get { 281 CheckConnectionAuthenticated (); 282 return !IsServer ? ssl_stream.ServerCertificate : ((SslServerStream) ssl_stream).ClientCertificate; 283 } 284 } 285 286 public virtual SslProtocols SslProtocol { 287 get { 288 CheckConnectionAuthenticated (); 289 290 switch (ssl_stream.SecurityProtocol) { 291 case MonoSecurityProtocolType.Default: 292 return SslProtocols.Default; 293 case MonoSecurityProtocolType.Ssl2: 294 return SslProtocols.Ssl2; 295 case MonoSecurityProtocolType.Ssl3: 296 return SslProtocols.Ssl3; 297 case MonoSecurityProtocolType.Tls: 298 return SslProtocols.Tls; 299 } 300 301 throw new InvalidOperationException ("Not supported SSL/TLS protocol is in use. It is likely a bug in SslStream."); 302 } 303 } 304 305 #endregion // Properties 306 307 #region Methods 308 309 /* 310 AsymmetricAlgorithm GetPrivateKey (X509Certificate cert, string targetHost) 311 { 312 // FIXME: what can I do for non-X509Certificate2 ? 313 X509Certificate2 cert2 = cert as X509Certificate2; 314 return cert2 != null ? cert2.PrivateKey : null; 315 } 316 */ OnCertificateSelection(X509CertificateCollection clientCerts, X509Certificate serverCert, string targetHost, X509CertificateCollection serverRequestedCerts)317 X509Certificate OnCertificateSelection (X509CertificateCollection clientCerts, X509Certificate serverCert, string targetHost, X509CertificateCollection serverRequestedCerts) 318 { 319 #pragma warning disable 618 320 string [] acceptableIssuers = new string [serverRequestedCerts != null ? serverRequestedCerts.Count : 0]; 321 for (int i = 0; i < acceptableIssuers.Length; i++) 322 acceptableIssuers [i] = serverRequestedCerts [i].GetIssuerName (); 323 X509Certificate clientCertificate; 324 certificateValidator.SelectClientCertificate (targetHost, clientCerts, serverCert, acceptableIssuers, out clientCertificate); 325 return clientCertificate; 326 #pragma warning restore 618 327 } 328 BeginAuthenticateAsClient(string targetHost, AsyncCallback asyncCallback, object asyncState)329 public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState) 330 { 331 return BeginAuthenticateAsClient (targetHost, new X509CertificateCollection (), SslProtocols.Tls, false, asyncCallback, asyncState); 332 } 333 BeginAuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)334 public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState) 335 { 336 if (IsAuthenticated) 337 throw new InvalidOperationException ("This SslStream is already authenticated"); 338 339 SslClientStream s = new SslClientStream (InnerStream, targetHost, !LeaveInnerStreamOpen, GetMonoSslProtocol (enabledSslProtocols), clientCertificates); 340 s.CheckCertRevocationStatus = checkCertificateRevocation; 341 342 // Due to the Mono.Security internal, it cannot reuse 343 // the delegated argument, as Mono.Security creates 344 // another instance of X509Certificate which lacks 345 // private key but is filled the private key via this 346 // delegate. 347 s.PrivateKeyCertSelectionDelegate = delegate (X509Certificate cert, string host) { 348 string hash = cert.GetCertHashString (); 349 // ... so, we cannot use the delegate argument. 350 foreach (X509Certificate cc in clientCertificates) { 351 if (cc.GetCertHashString () != hash) 352 continue; 353 X509Certificate2 cert2 = cc as X509Certificate2; 354 cert2 = cert2 ?? new X509Certificate2 (cc); 355 return cert2.PrivateKey; 356 } 357 return null; 358 }; 359 360 // Even if validation_callback is null this allows us to verify requests where the user 361 // does not provide a verification callback but attempts to authenticate with the website 362 // as a client (see https://bugzilla.xamarin.com/show_bug.cgi?id=18962 for an example) 363 s.ServerCertValidation2 += (mcerts) => { 364 X509CertificateCollection certs = null; 365 if (mcerts != null) { 366 certs = new X509CertificateCollection (); 367 for (int i = 0; i < mcerts.Count; i++) 368 certs.Add (new X509Certificate2 (mcerts [i].RawData)); 369 } 370 return ((ChainValidationHelper)certificateValidator).ValidateCertificate (targetHost, false, certs); 371 }; 372 s.ClientCertSelectionDelegate = OnCertificateSelection; 373 374 ssl_stream = s; 375 376 return BeginWrite (new byte [0], 0, 0, asyncCallback, asyncState); 377 } 378 BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)379 public override IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) 380 { 381 CheckConnectionAuthenticated (); 382 383 return ssl_stream.BeginRead (buffer, offset, count, asyncCallback, asyncState); 384 } 385 BeginAuthenticateAsServer(X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState)386 public virtual IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState) 387 { 388 return BeginAuthenticateAsServer (serverCertificate, false, SslProtocols.Tls, false, asyncCallback, asyncState); 389 } 390 BeginAuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)391 public virtual IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState) 392 { 393 if (IsAuthenticated) 394 throw new InvalidOperationException ("This SslStream is already authenticated"); 395 396 SslServerStream s = new SslServerStream (InnerStream, serverCertificate, false, clientCertificateRequired, !LeaveInnerStreamOpen, GetMonoSslProtocol (enabledSslProtocols)); 397 s.CheckCertRevocationStatus = checkCertificateRevocation; 398 // Due to the Mono.Security internal, it cannot reuse 399 // the delegated argument, as Mono.Security creates 400 // another instance of X509Certificate which lacks 401 // private key but is filled the private key via this 402 // delegate. 403 s.PrivateKeyCertSelectionDelegate = delegate (X509Certificate cert, string targetHost) { 404 // ... so, we cannot use the delegate argument. 405 X509Certificate2 cert2 = serverCertificate as X509Certificate2 ?? new X509Certificate2 (serverCertificate); 406 return cert2 != null ? cert2.PrivateKey : null; 407 }; 408 409 s.ClientCertValidationDelegate = delegate (X509Certificate cert, int[] certErrors) { 410 var errors = certErrors.Length > 0 ? MonoSslPolicyErrors.RemoteCertificateChainErrors : MonoSslPolicyErrors.None; 411 return ((ChainValidationHelper)certificateValidator).ValidateClientCertificate (cert, errors); 412 }; 413 414 ssl_stream = s; 415 416 return BeginWrite (new byte[0], 0, 0, asyncCallback, asyncState); 417 } 418 GetMonoSslProtocol(SslProtocols ms)419 MonoSecurityProtocolType GetMonoSslProtocol (SslProtocols ms) 420 { 421 switch (ms) { 422 case SslProtocols.Ssl2: 423 return MonoSecurityProtocolType.Ssl2; 424 case SslProtocols.Ssl3: 425 return MonoSecurityProtocolType.Ssl3; 426 case SslProtocols.Tls: 427 return MonoSecurityProtocolType.Tls; 428 default: 429 return MonoSecurityProtocolType.Default; 430 } 431 } 432 BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)433 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) 434 { 435 CheckConnectionAuthenticated (); 436 437 return ssl_stream.BeginWrite (buffer, offset, count, asyncCallback, asyncState); 438 } 439 AuthenticateAsClient(string targetHost)440 public virtual void AuthenticateAsClient (string targetHost) 441 { 442 AuthenticateAsClient (targetHost, new X509CertificateCollection (), SslProtocols.Tls, false); 443 } 444 AuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)445 public virtual void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation) 446 { 447 EndAuthenticateAsClient (BeginAuthenticateAsClient ( 448 targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation, null, null)); 449 } 450 AuthenticateAsServer(X509Certificate serverCertificate)451 public virtual void AuthenticateAsServer (X509Certificate serverCertificate) 452 { 453 AuthenticateAsServer (serverCertificate, false, SslProtocols.Tls, false); 454 } 455 AuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)456 public virtual void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation) 457 { 458 EndAuthenticateAsServer (BeginAuthenticateAsServer ( 459 serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation, null, null)); 460 } 461 Dispose(bool disposing)462 protected override void Dispose (bool disposing) 463 { 464 if (disposing) { 465 if (ssl_stream != null) 466 ssl_stream.Dispose (); 467 ssl_stream = null; 468 } 469 base.Dispose (disposing); 470 } 471 EndAuthenticateAsClient(IAsyncResult asyncResult)472 public virtual void EndAuthenticateAsClient (IAsyncResult asyncResult) 473 { 474 CheckConnectionAuthenticated (); 475 476 if (CanRead) 477 ssl_stream.EndRead (asyncResult); 478 else 479 ssl_stream.EndWrite (asyncResult); 480 } 481 EndAuthenticateAsServer(IAsyncResult asyncResult)482 public virtual void EndAuthenticateAsServer (IAsyncResult asyncResult) 483 { 484 CheckConnectionAuthenticated (); 485 486 if (CanRead) 487 ssl_stream.EndRead (asyncResult); 488 else 489 ssl_stream.EndWrite (asyncResult); 490 } 491 EndRead(IAsyncResult asyncResult)492 public override int EndRead (IAsyncResult asyncResult) 493 { 494 CheckConnectionAuthenticated (); 495 496 return ssl_stream.EndRead (asyncResult); 497 } 498 EndWrite(IAsyncResult asyncResult)499 public override void EndWrite (IAsyncResult asyncResult) 500 { 501 CheckConnectionAuthenticated (); 502 503 ssl_stream.EndWrite (asyncResult); 504 } 505 Flush()506 public override void Flush () 507 { 508 CheckConnectionAuthenticated (); 509 510 InnerStream.Flush (); 511 } 512 Read(byte[] buffer, int offset, int count)513 public override int Read (byte[] buffer, int offset, int count) 514 { 515 return EndRead (BeginRead (buffer, offset, count, null, null)); 516 } 517 Seek(long offset, SeekOrigin origin)518 public override long Seek (long offset, SeekOrigin origin) 519 { 520 throw new NotSupportedException ("This stream does not support seek operations"); 521 } 522 SetLength(long value)523 public override void SetLength (long value) 524 { 525 InnerStream.SetLength (value); 526 } 527 Write(byte[] buffer, int offset, int count)528 public override void Write (byte[] buffer, int offset, int count) 529 { 530 EndWrite (BeginWrite (buffer, offset, count, null, null)); 531 } 532 Write(byte[] buffer)533 public void Write (byte[] buffer) 534 { 535 Write (buffer, 0, buffer.Length); 536 } 537 CheckConnectionAuthenticated()538 void CheckConnectionAuthenticated () 539 { 540 if (!IsAuthenticated) 541 throw new InvalidOperationException ("This operation is invalid until it is successfully authenticated"); 542 } 543 AuthenticateAsClientAsync(string targetHost)544 public virtual Task AuthenticateAsClientAsync (string targetHost) 545 { 546 return Task.Factory.FromAsync (BeginAuthenticateAsClient, EndAuthenticateAsClient, targetHost, null); 547 } 548 AuthenticateAsClientAsync(string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)549 public virtual Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation) 550 { 551 var t = Tuple.Create (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation, this); 552 553 return Task.Factory.FromAsync ((callback, state) => { 554 var d = (Tuple<string, X509CertificateCollection, SslProtocols, bool, LegacySslStream>) state; 555 return d.Item5.BeginAuthenticateAsClient (d.Item1, d.Item2, d.Item3, d.Item4, callback, null); 556 }, EndAuthenticateAsClient, t); 557 } 558 AuthenticateAsServerAsync(X509Certificate serverCertificate)559 public virtual Task AuthenticateAsServerAsync (X509Certificate serverCertificate) 560 { 561 return Task.Factory.FromAsync (BeginAuthenticateAsServer, EndAuthenticateAsServer, serverCertificate, null); 562 } 563 AuthenticateAsServerAsync(X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)564 public virtual Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation) 565 { 566 var t = Tuple.Create (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation, this); 567 568 return Task.Factory.FromAsync ((callback, state) => { 569 var d = (Tuple<X509Certificate, bool, SslProtocols, bool, LegacySslStream>) state; 570 return d.Item5.BeginAuthenticateAsServer (d.Item1, d.Item2, d.Item3, d.Item4, callback, null); 571 }, EndAuthenticateAsServer, t); 572 } 573 574 #endregion // Methods 575 576 #region IMonoSslStream 577 IMonoSslStream.ShutdownAsync()578 Task IMonoSslStream.ShutdownAsync () 579 { 580 return Task.CompletedTask; 581 } 582 583 AuthenticatedStream IMonoSslStream.AuthenticatedStream { 584 get { return this; } 585 } 586 587 TransportContext IMonoSslStream.TransportContext { 588 get { throw new NotSupportedException (); } 589 } 590 591 public SslStream SslStream { 592 get; 593 } 594 595 public MonoTlsProvider Provider { 596 get; 597 } 598 GetConnectionInfo()599 public MonoTlsConnectionInfo GetConnectionInfo () 600 { 601 return null; 602 } 603 604 #endregion 605 } 606 } 607 608 #endif 609