| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 1 | /** | 
|  | 2 | * Licensed to the Apache Software Foundation (ASF) under one | 
|  | 3 | * or more contributor license agreements. See the NOTICE file | 
|  | 4 | * distributed with this work for additional information | 
|  | 5 | * regarding copyright ownership. The ASF licenses this file | 
|  | 6 | * to you under the Apache License, Version 2.0 (the | 
|  | 7 | * "License"); you may not use this file except in compliance | 
|  | 8 | * with the License. You may obtain a copy of the License at | 
|  | 9 | * | 
|  | 10 | *   http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 11 | * | 
|  | 12 | * Unless required by applicable law or agreed to in writing, | 
|  | 13 | * software distributed under the License is distributed on an | 
|  | 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
|  | 15 | * KIND, either express or implied. See the License for the | 
|  | 16 | * specific language governing permissions and limitations | 
|  | 17 | * under the License. | 
|  | 18 | */ | 
|  | 19 |  | 
|  | 20 | using System; | 
|  | 21 | using System.Net.Security; | 
|  | 22 | using System.Net.Sockets; | 
|  | 23 | using System.Security.Authentication; | 
|  | 24 | using System.Security.Cryptography.X509Certificates; | 
|  | 25 |  | 
|  | 26 | namespace Thrift.Transport | 
|  | 27 | { | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 28 | /// <summary> | 
|  | 29 | /// SSL Socket Wrapper class | 
|  | 30 | /// </summary> | 
|  | 31 | public class TTLSSocket : TStreamTransport | 
|  | 32 | { | 
|  | 33 | /// <summary> | 
|  | 34 | /// Internal TCP Client | 
|  | 35 | /// </summary> | 
| Jens Geyer | 178b813 | 2015-09-30 23:16:45 +0200 | [diff] [blame] | 36 | private TcpClient client; | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 37 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 38 | /// <summary> | 
|  | 39 | /// The host | 
|  | 40 | /// </summary> | 
| Jens Geyer | 178b813 | 2015-09-30 23:16:45 +0200 | [diff] [blame] | 41 | private string host; | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 42 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 43 | /// <summary> | 
|  | 44 | /// The port | 
|  | 45 | /// </summary> | 
| Jens Geyer | 178b813 | 2015-09-30 23:16:45 +0200 | [diff] [blame] | 46 | private int port; | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 47 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 48 | /// <summary> | 
|  | 49 | /// The timeout for the connection | 
|  | 50 | /// </summary> | 
| Jens Geyer | 178b813 | 2015-09-30 23:16:45 +0200 | [diff] [blame] | 51 | private int timeout; | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 52 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 53 | /// <summary> | 
|  | 54 | /// Internal SSL Stream for IO | 
|  | 55 | /// </summary> | 
| Jens Geyer | 178b813 | 2015-09-30 23:16:45 +0200 | [diff] [blame] | 56 | private SslStream secureStream; | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 57 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 58 | /// <summary> | 
|  | 59 | /// Defines wheter or not this socket is a server socket<br/> | 
|  | 60 | /// This is used for the TLS-authentication | 
|  | 61 | /// </summary> | 
| Jens Geyer | 178b813 | 2015-09-30 23:16:45 +0200 | [diff] [blame] | 62 | private bool isServer; | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 63 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 64 | /// <summary> | 
|  | 65 | /// The certificate | 
|  | 66 | /// </summary> | 
| Jens Geyer | 178b813 | 2015-09-30 23:16:45 +0200 | [diff] [blame] | 67 | private X509Certificate certificate; | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 68 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 69 | /// <summary> | 
|  | 70 | /// User defined certificate validator. | 
|  | 71 | /// </summary> | 
| Jens Geyer | 178b813 | 2015-09-30 23:16:45 +0200 | [diff] [blame] | 72 | private RemoteCertificateValidationCallback certValidator; | 
| Jens Geyer | 7b11fec | 2014-06-05 22:03:19 +0200 | [diff] [blame] | 73 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 74 | /// <summary> | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 75 | /// The function to determine which certificate to use. | 
|  | 76 | /// </summary> | 
|  | 77 | private LocalCertificateSelectionCallback localCertificateSelectionCallback; | 
|  | 78 |  | 
|  | 79 | /// <summary> | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 80 | /// The SslProtocols value that represents the protocol used for authentication.SSL protocols to be used. | 
|  | 81 | /// </summary> | 
|  | 82 | private readonly SslProtocols sslProtocols; | 
|  | 83 |  | 
|  | 84 | /// <summary> | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 85 | /// Initializes a new instance of the <see cref="TTLSSocket"/> class. | 
|  | 86 | /// </summary> | 
|  | 87 | /// <param name="client">An already created TCP-client</param> | 
|  | 88 | /// <param name="certificate">The certificate.</param> | 
|  | 89 | /// <param name="isServer">if set to <c>true</c> [is server].</param> | 
| Jens Geyer | af57724 | 2015-03-30 23:44:51 +0200 | [diff] [blame] | 90 | /// <param name="certValidator">User defined cert validator.</param> | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 91 | /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param> | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 92 | /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param> | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 93 | public TTLSSocket( | 
|  | 94 | TcpClient client, | 
|  | 95 | X509Certificate certificate, | 
|  | 96 | bool isServer = false, | 
|  | 97 | RemoteCertificateValidationCallback certValidator = null, | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 98 | LocalCertificateSelectionCallback localCertificateSelectionCallback = null, | 
|  | 99 | // TODO: Enable Tls11 and Tls12 (TLS 1.1 and 1.2) by default once we start using .NET 4.5+. | 
|  | 100 | SslProtocols sslProtocols = SslProtocols.Tls) | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 101 | { | 
|  | 102 | this.client = client; | 
|  | 103 | this.certificate = certificate; | 
| Jens Geyer | af57724 | 2015-03-30 23:44:51 +0200 | [diff] [blame] | 104 | this.certValidator = certValidator; | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 105 | this.localCertificateSelectionCallback = localCertificateSelectionCallback; | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 106 | this.sslProtocols = sslProtocols; | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 107 | this.isServer = isServer; | 
| Jens Geyer | 178b813 | 2015-09-30 23:16:45 +0200 | [diff] [blame] | 108 | if (isServer && certificate == null) | 
|  | 109 | { | 
|  | 110 | throw new ArgumentException("TTLSSocket needs certificate to be used for server", "certificate"); | 
|  | 111 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 112 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 113 | if (IsOpen) | 
|  | 114 | { | 
|  | 115 | base.inputStream = client.GetStream(); | 
|  | 116 | base.outputStream = client.GetStream(); | 
|  | 117 | } | 
|  | 118 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 119 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 120 | /// <summary> | 
|  | 121 | /// Initializes a new instance of the <see cref="TTLSSocket"/> class. | 
|  | 122 | /// </summary> | 
|  | 123 | /// <param name="host">The host, where the socket should connect to.</param> | 
|  | 124 | /// <param name="port">The port.</param> | 
|  | 125 | /// <param name="certificatePath">The certificate path.</param> | 
|  | 126 | /// <param name="certValidator">User defined cert validator.</param> | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 127 | /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param> | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 128 | /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param> | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 129 | public TTLSSocket( | 
|  | 130 | string host, | 
|  | 131 | int port, | 
|  | 132 | string certificatePath, | 
|  | 133 | RemoteCertificateValidationCallback certValidator = null, | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 134 | LocalCertificateSelectionCallback localCertificateSelectionCallback = null, | 
|  | 135 | SslProtocols sslProtocols = SslProtocols.Tls) | 
|  | 136 | : this(host, port, 0, X509Certificate.CreateFromCertFile(certificatePath), certValidator, localCertificateSelectionCallback, sslProtocols) | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 137 | { | 
|  | 138 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 139 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 140 | /// <summary> | 
|  | 141 | /// Initializes a new instance of the <see cref="TTLSSocket"/> class. | 
|  | 142 | /// </summary> | 
|  | 143 | /// <param name="host">The host, where the socket should connect to.</param> | 
|  | 144 | /// <param name="port">The port.</param> | 
|  | 145 | /// <param name="certificate">The certificate.</param> | 
|  | 146 | /// <param name="certValidator">User defined cert validator.</param> | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 147 | /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param> | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 148 | /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param> | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 149 | public TTLSSocket( | 
|  | 150 | string host, | 
|  | 151 | int port, | 
| Jens Geyer | 178b813 | 2015-09-30 23:16:45 +0200 | [diff] [blame] | 152 | X509Certificate certificate = null, | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 153 | RemoteCertificateValidationCallback certValidator = null, | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 154 | LocalCertificateSelectionCallback localCertificateSelectionCallback = null, | 
|  | 155 | SslProtocols sslProtocols = SslProtocols.Tls) | 
|  | 156 | : this(host, port, 0, certificate, certValidator, localCertificateSelectionCallback, sslProtocols) | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 157 | { | 
|  | 158 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 159 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 160 | /// <summary> | 
|  | 161 | /// Initializes a new instance of the <see cref="TTLSSocket"/> class. | 
|  | 162 | /// </summary> | 
|  | 163 | /// <param name="host">The host, where the socket should connect to.</param> | 
|  | 164 | /// <param name="port">The port.</param> | 
|  | 165 | /// <param name="timeout">The timeout.</param> | 
|  | 166 | /// <param name="certificate">The certificate.</param> | 
|  | 167 | /// <param name="certValidator">User defined cert validator.</param> | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 168 | /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param> | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 169 | /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param> | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 170 | public TTLSSocket( | 
|  | 171 | string host, | 
|  | 172 | int port, | 
|  | 173 | int timeout, | 
|  | 174 | X509Certificate certificate, | 
|  | 175 | RemoteCertificateValidationCallback certValidator = null, | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 176 | LocalCertificateSelectionCallback localCertificateSelectionCallback = null, | 
|  | 177 | SslProtocols sslProtocols = SslProtocols.Tls) | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 178 | { | 
|  | 179 | this.host = host; | 
|  | 180 | this.port = port; | 
|  | 181 | this.timeout = timeout; | 
|  | 182 | this.certificate = certificate; | 
|  | 183 | this.certValidator = certValidator; | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 184 | this.localCertificateSelectionCallback = localCertificateSelectionCallback; | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 185 | this.sslProtocols = sslProtocols; | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 186 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 187 | InitSocket(); | 
|  | 188 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 189 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 190 | /// <summary> | 
|  | 191 | /// Creates the TcpClient and sets the timeouts | 
|  | 192 | /// </summary> | 
|  | 193 | private void InitSocket() | 
|  | 194 | { | 
| Jens Geyer | feea478 | 2017-01-28 19:53:28 +0100 | [diff] [blame] | 195 | client = TSocketVersionizer.CreateTcpClient(); | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 196 | client.ReceiveTimeout = client.SendTimeout = timeout; | 
|  | 197 | client.Client.NoDelay = true; | 
|  | 198 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 199 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 200 | /// <summary> | 
|  | 201 | /// Sets Send / Recv Timeout for IO | 
|  | 202 | /// </summary> | 
|  | 203 | public int Timeout | 
|  | 204 | { | 
|  | 205 | set | 
|  | 206 | { | 
|  | 207 | this.client.ReceiveTimeout = this.client.SendTimeout = this.timeout = value; | 
|  | 208 | } | 
|  | 209 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 210 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 211 | /// <summary> | 
|  | 212 | /// Gets the TCP client. | 
|  | 213 | /// </summary> | 
|  | 214 | public TcpClient TcpClient | 
|  | 215 | { | 
|  | 216 | get | 
|  | 217 | { | 
|  | 218 | return client; | 
|  | 219 | } | 
|  | 220 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 221 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 222 | /// <summary> | 
|  | 223 | /// Gets the host. | 
|  | 224 | /// </summary> | 
|  | 225 | public string Host | 
|  | 226 | { | 
|  | 227 | get | 
|  | 228 | { | 
|  | 229 | return host; | 
|  | 230 | } | 
|  | 231 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 232 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 233 | /// <summary> | 
|  | 234 | /// Gets the port. | 
|  | 235 | /// </summary> | 
|  | 236 | public int Port | 
|  | 237 | { | 
|  | 238 | get | 
|  | 239 | { | 
|  | 240 | return port; | 
|  | 241 | } | 
|  | 242 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 243 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 244 | /// <summary> | 
|  | 245 | /// Gets a value indicating whether TCP Client is Cpen | 
|  | 246 | /// </summary> | 
|  | 247 | public override bool IsOpen | 
|  | 248 | { | 
|  | 249 | get | 
|  | 250 | { | 
|  | 251 | if (this.client == null) | 
|  | 252 | { | 
|  | 253 | return false; | 
|  | 254 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 255 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 256 | return this.client.Connected; | 
|  | 257 | } | 
|  | 258 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 259 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 260 | /// <summary> | 
|  | 261 | /// Validates the certificates!<br/> | 
|  | 262 | /// </summary> | 
|  | 263 | /// <param name="sender">The sender-object.</param> | 
|  | 264 | /// <param name="certificate">The used certificate.</param> | 
|  | 265 | /// <param name="chain">The certificate chain.</param> | 
| Christian Weiss | 8fb719e | 2018-03-30 21:26:04 +0200 | [diff] [blame^] | 266 | /// <param name="sslValidationErrors">An enum, which lists all the errors from the .NET certificate check.</param> | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 267 | /// <returns></returns> | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 268 | private bool DefaultCertificateValidator(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslValidationErrors) | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 269 | { | 
|  | 270 | return (sslValidationErrors == SslPolicyErrors.None); | 
|  | 271 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 272 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 273 | /// <summary> | 
|  | 274 | /// Connects to the host and starts the routine, which sets up the TLS | 
|  | 275 | /// </summary> | 
|  | 276 | public override void Open() | 
|  | 277 | { | 
|  | 278 | if (IsOpen) | 
|  | 279 | { | 
|  | 280 | throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected"); | 
|  | 281 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 282 |  | 
| Christian Weiss | 8fb719e | 2018-03-30 21:26:04 +0200 | [diff] [blame^] | 283 | if (string.IsNullOrEmpty(host)) | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 284 | { | 
|  | 285 | throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host"); | 
|  | 286 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 287 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 288 | if (port <= 0) | 
|  | 289 | { | 
|  | 290 | throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port"); | 
|  | 291 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 292 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 293 | if (client == null) | 
|  | 294 | { | 
|  | 295 | InitSocket(); | 
|  | 296 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 297 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 298 | client.Connect(host, port); | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 299 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 300 | setupTLS(); | 
|  | 301 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 302 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 303 | /// <summary> | 
|  | 304 | /// Creates a TLS-stream and lays it over the existing socket | 
|  | 305 | /// </summary> | 
|  | 306 | public void setupTLS() | 
|  | 307 | { | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 308 | RemoteCertificateValidationCallback validator = this.certValidator ?? DefaultCertificateValidator; | 
| Adam Connelly | 0c0649d | 2015-12-26 15:55:05 +0000 | [diff] [blame] | 309 |  | 
| Christian Weiss | 8fb719e | 2018-03-30 21:26:04 +0200 | [diff] [blame^] | 310 | if (this.localCertificateSelectionCallback != null) | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 311 | { | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 312 | this.secureStream = new SslStream( | 
|  | 313 | this.client.GetStream(), | 
|  | 314 | false, | 
|  | 315 | validator, | 
|  | 316 | this.localCertificateSelectionCallback | 
|  | 317 | ); | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 318 | } | 
|  | 319 | else | 
|  | 320 | { | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 321 | this.secureStream = new SslStream( | 
|  | 322 | this.client.GetStream(), | 
|  | 323 | false, | 
|  | 324 | validator | 
|  | 325 | ); | 
|  | 326 | } | 
| Adam Connelly | 0c0649d | 2015-12-26 15:55:05 +0000 | [diff] [blame] | 327 |  | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 328 | try | 
|  | 329 | { | 
|  | 330 | if (isServer) | 
|  | 331 | { | 
|  | 332 | // Server authentication | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 333 | this.secureStream.AuthenticateAsServer(this.certificate, this.certValidator != null, sslProtocols, true); | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 334 | } | 
|  | 335 | else | 
|  | 336 | { | 
|  | 337 | // Client authentication | 
| Christian Weiss | 8fb719e | 2018-03-30 21:26:04 +0200 | [diff] [blame^] | 338 | X509CertificateCollection certs = certificate != null ? new X509CertificateCollection { certificate } : new X509CertificateCollection(); | 
| Nobuaki Sukegawa | 474ddbd | 2016-02-17 23:44:27 +0900 | [diff] [blame] | 339 | this.secureStream.AuthenticateAsClient(host, certs, sslProtocols, true); | 
| Jens Geyer | 1dc2653 | 2015-04-05 19:13:29 +0200 | [diff] [blame] | 340 | } | 
|  | 341 | } | 
|  | 342 | catch (Exception) | 
|  | 343 | { | 
|  | 344 | this.Close(); | 
|  | 345 | throw; | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 346 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 347 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 348 | inputStream = this.secureStream; | 
|  | 349 | outputStream = this.secureStream; | 
|  | 350 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 351 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 352 | /// <summary> | 
|  | 353 | /// Closes the SSL Socket | 
|  | 354 | /// </summary> | 
|  | 355 | public override void Close() | 
|  | 356 | { | 
|  | 357 | base.Close(); | 
|  | 358 | if (this.client != null) | 
|  | 359 | { | 
|  | 360 | this.client.Close(); | 
|  | 361 | this.client = null; | 
|  | 362 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 363 |  | 
| Jens Geyer | d5436f5 | 2014-10-03 19:50:38 +0200 | [diff] [blame] | 364 | if (this.secureStream != null) | 
|  | 365 | { | 
|  | 366 | this.secureStream.Close(); | 
|  | 367 | this.secureStream = null; | 
|  | 368 | } | 
|  | 369 | } | 
|  | 370 | } | 
| Jens Geyer | c1d7943 | 2014-04-22 22:52:43 +0200 | [diff] [blame] | 371 | } |