|
| 1 | +' NclSslServerSync |
| 2 | + |
| 3 | +' <snippet0> |
| 4 | +Imports System.Collections |
| 5 | +Imports System.Net |
| 6 | +Imports System.Net.Sockets |
| 7 | +Imports System.Net.Security |
| 8 | +Imports System.Security.Authentication |
| 9 | +Imports System.Text |
| 10 | +Imports System.Security.Cryptography.X509Certificates |
| 11 | +Imports System.IO |
| 12 | + |
| 13 | +Namespace Examples.System.Net |
| 14 | + Public NotInheritable Class SslTcpServer |
| 15 | + Shared serverCertificate As X509Certificate = Nothing |
| 16 | + |
| 17 | + ' The certificate parameter specifies the name of the file |
| 18 | + ' containing the machine certificate. |
| 19 | + Public Shared Sub RunServer(certificate As String) |
| 20 | + serverCertificate = X509Certificate.CreateFromCertFile(certificate) |
| 21 | + ' Create a TCP/IP (IPv4) socket And listen for incoming connections. |
| 22 | + Dim listener = New TcpListener(IPAddress.Any, 8080) |
| 23 | + listener.Start() |
| 24 | + |
| 25 | + While True |
| 26 | + Console.WriteLine("Waiting for a client to connect...") |
| 27 | + ' Application blocks while waiting for an incoming connection. |
| 28 | + ' Type CNTL-C to terminate the server. |
| 29 | + Dim client As TcpClient = listener.AcceptTcpClient() |
| 30 | + ProcessClient(client) |
| 31 | + End While |
| 32 | + End Sub |
| 33 | + '<snippet1 |
| 34 | + Private Shared Sub ProcessClient(client As TcpClient) |
| 35 | + ' A client has connected. Create the |
| 36 | + ' SslStream using the client's network stream. |
| 37 | + Dim sslStream = New SslStream(client.GetStream(), False) |
| 38 | + |
| 39 | + Try |
| 40 | + |
| 41 | + sslStream.AuthenticateAsServer(serverCertificate, clientCertificateRequired:=False, checkCertificateRevocation:=True) |
| 42 | + ' Display the properties And settings for the authenticated stream. |
| 43 | + DisplaySecurityLevel(sslStream) |
| 44 | + DisplaySecurityServices(sslStream) |
| 45 | + DisplayCertificateInformation(sslStream) |
| 46 | + DisplayStreamProperties(sslStream) |
| 47 | + |
| 48 | + ' Set timeouts for the read and write to 5 seconds. |
| 49 | + sslStream.ReadTimeout = 5000 |
| 50 | + sslStream.WriteTimeout = 5000 |
| 51 | + |
| 52 | + ' Read a message from the client. |
| 53 | + Console.WriteLine("Waiting for client message...") |
| 54 | + Dim messageData As String = ReadMessage(sslStream) |
| 55 | + Console.WriteLine("Received: {0}", messageData) |
| 56 | + |
| 57 | + ' Write a message to the client. |
| 58 | + Dim message As Byte() = Encoding.UTF8.GetBytes("Hello from the server.<EOF>") |
| 59 | + Console.WriteLine("Sending hello message.") |
| 60 | + sslStream.Write(message) |
| 61 | + Catch e As AuthenticationException |
| 62 | + Console.WriteLine("Exception: {0}", e.Message) |
| 63 | + |
| 64 | + If e.InnerException IsNot Nothing Then |
| 65 | + Console.WriteLine("Inner exception: {0}", e.InnerException.Message) |
| 66 | + End If |
| 67 | + |
| 68 | + Console.WriteLine("Authentication failed - closing the connection.") |
| 69 | + sslStream.Close() |
| 70 | + client.Close() |
| 71 | + Return |
| 72 | + Finally |
| 73 | + ' The client stream will be closed with the sslStream |
| 74 | + ' because we specified this behavior when creating |
| 75 | + ' the sslStream. |
| 76 | + sslStream.Close() |
| 77 | + client.Close() |
| 78 | + End Try |
| 79 | + End Sub |
| 80 | + |
| 81 | + '</snippet1> |
| 82 | + '<snippet2> |
| 83 | + Private Shared Function ReadMessage(sslStream As SslStream) As String |
| 84 | + |
| 85 | + ' Read the message sent by the client. |
| 86 | + ' The client signals the end of the message using the |
| 87 | + ' "<EOF>" marker. |
| 88 | + Dim buffer As Byte() = New Byte(2048) {} |
| 89 | + Dim messageData As StringBuilder = New StringBuilder() |
| 90 | + Dim bytes As Integer = -1 |
| 91 | + |
| 92 | + Do |
| 93 | + ' Read the client's test message. |
| 94 | + bytes = sslStream.Read(buffer, 0, buffer.Length) |
| 95 | + |
| 96 | + ' Use decoder class to convert from bytes to UTF8 |
| 97 | + ' in case a character spans two buffers. |
| 98 | + Dim decoder As Decoder = Encoding.UTF8.GetDecoder() |
| 99 | + Dim chars As Char() = New Char(decoder.GetCharCount(buffer, 0, bytes) - 1) {} |
| 100 | + decoder.GetChars(buffer, 0, bytes, chars, 0) |
| 101 | + messageData.Append(chars) |
| 102 | + |
| 103 | + ' Check for EOF or an empty message. |
| 104 | + If messageData.ToString().IndexOf("<EOF>") <> -1 Then |
| 105 | + Exit Do |
| 106 | + End If |
| 107 | + Loop While bytes <> 0 |
| 108 | + |
| 109 | + Return messageData.ToString() |
| 110 | + End Function |
| 111 | + |
| 112 | + ' </snippet2> |
| 113 | + ' <snippet3> |
| 114 | + Private Shared Sub DisplaySecurityLevel(stream As SslStream) |
| 115 | + Console.WriteLine("Cipher: {0} strength {1}", stream.CipherAlgorithm, stream.CipherStrength) |
| 116 | + Console.WriteLine("Hash: {0} strength {1}", stream.HashAlgorithm, stream.HashStrength) |
| 117 | + Console.WriteLine("Key exchange: {0} strength {1}", stream.KeyExchangeAlgorithm, stream.KeyExchangeStrength) |
| 118 | + Console.WriteLine("Protocol: {0}", stream.SslProtocol) |
| 119 | + End Sub |
| 120 | + '</snippet3> |
| 121 | + '<snippet4> |
| 122 | + |
| 123 | + Private Shared Sub DisplaySecurityServices(stream As SslStream) |
| 124 | + Console.WriteLine("Is authenticated: {0} as server? {1}", stream.IsAuthenticated, stream.IsServer) |
| 125 | + Console.WriteLine("IsSigned: {0}", stream.IsSigned) |
| 126 | + Console.WriteLine("Is Encrypted: {0}", stream.IsEncrypted) |
| 127 | + End Sub |
| 128 | + ' </snippet4> |
| 129 | + ' <snippet5> |
| 130 | + Private Shared Sub DisplayStreamProperties(stream As SslStream) |
| 131 | + Console.WriteLine("Can read: {0}, write {1}", stream.CanRead, stream.CanWrite) |
| 132 | + Console.WriteLine("Can timeout: {0}", stream.CanTimeout) |
| 133 | + End Sub |
| 134 | + |
| 135 | + ' </snippet5> |
| 136 | + ' <snippet6> |
| 137 | + Private Shared Sub DisplayCertificateInformation(stream As SslStream) |
| 138 | + Console.WriteLine("Certificate revocation list checked: {0}", stream.CheckCertRevocationStatus) |
| 139 | + Dim localCertificate As X509Certificate = stream.LocalCertificate |
| 140 | + |
| 141 | + If stream.LocalCertificate IsNot Nothing Then |
| 142 | + Console.WriteLine("Local cert was issued to {0} and is valid from {1} until {2}.", localCertificate.Subject, localCertificate.GetEffectiveDateString(), localCertificate.GetExpirationDateString()) |
| 143 | + Else |
| 144 | + Console.WriteLine("Local certificate is null.") |
| 145 | + End If |
| 146 | + |
| 147 | + ' Display the properties of the client's certificate. |
| 148 | + Dim remoteCertificate As X509Certificate = stream.RemoteCertificate |
| 149 | + |
| 150 | + If stream.RemoteCertificate IsNot Nothing Then |
| 151 | + Console.WriteLine("Remote cert was issued to {0} and is valid from {1} until {2}.", remoteCertificate.Subject, remoteCertificate.GetEffectiveDateString(), remoteCertificate.GetExpirationDateString()) |
| 152 | + Else |
| 153 | + Console.WriteLine("Remote certificate is null.") |
| 154 | + End If |
| 155 | + End Sub |
| 156 | + |
| 157 | + ' </snippet6> |
| 158 | + Private Shared Sub DisplayUsage() |
| 159 | + Console.WriteLine("To start the server specify:") |
| 160 | + Console.WriteLine("serverSync certificateFile.cer") |
| 161 | + Environment.[Exit](1) |
| 162 | + End Sub |
| 163 | + |
| 164 | + Public Shared Function Main(ByVal args As String()) As Integer |
| 165 | + Dim certificate As String |
| 166 | + |
| 167 | + If args Is Nothing OrElse args.Length < 1 Then |
| 168 | + DisplayUsage() |
| 169 | + End If |
| 170 | + |
| 171 | + certificate = args(0) |
| 172 | + RunServer(certificate) |
| 173 | + Return 0 |
| 174 | + End Function |
| 175 | + End Class |
| 176 | +End Namespace |
| 177 | +'</snippet0> |
0 commit comments