hikalkan / scs

TCP Server/Client Communication and RMI Framework
MIT License
225 stars 112 forks source link

SSL Support #37

Open SariSultan opened 5 years ago

hikalkan commented 5 years ago

Thanks a lot @SariSultan I will review it soon :)

hikalkan commented 5 years ago

This is a very huge PR. Can you explain what you've done with a bit detailed?

SariSultan commented 5 years ago

Thank you @hikalkan. Sure.

I added SSL/TLS support for server and clients. I tried to be consistent with the original framework. I made few changes to the original files.

### First, changes to the original files: In ScsEndPoint.cs, I added : 1.A: internal abstract IScsServer CreateSslServer(X509Certificate serverCert, List<X509Certificate2> clientCerts, SslScsAuthMode authMode);

This method allows the user to create and Ssl server. (Parameters will be discussed later)

1.B: internal abstract IScsClient CreateSslClient(X509Certificate2 serverCertificate, SslScsAuthMode authMode, X509Certificate clientCertificate, string sslHostAddress);

This method allows the user to create Ssl client. (Parameters will be discussed later)

  1. Bug fixes to the original framework: 2.A: In ScsTextMessage.cs: I added an explicit operator to cast ScsPingMessage to ScsTextMessage. This resolved an error in the customwireprotocol you provided in the benchmarks.

2.B: In BinarySerializationProtocol.cs: There is an issue with SslStreams. I don't know why it gets a message as two parts. When EndRead method is called for the first time, the steam will read only 1 byte. On the second read, it will read the rest of the message. Hence, I changed the serialization and added the following lines inside ReadSingleMessage method (If you can check this issue it would be great):

    if (_receiveMemoryStream.Length == 1)
            {
                _receiveMemoryStream.Position = 1;
                return false;
            }

Those are the only changes to the original framework files. Now lets see the new files added.

### Second, new files in the framework:

  1. I made a similar namespace to communication.scs and called it communication.SslScs, it contains four main sub namespaces: 1.A: Authentication: This includes an enum to identify the authentication type. I implemented two authentication types. First, server authentication only. In this type, the client verifies the server identity (assuming it has the server public key). [an important enhancement should be made to identify if the certificate should be validated using the system certificate authorities (so the client does not have to have the public key explicitly)].

Second, mutual authentication: in this type the client verifies the server certificate (similar to the previous steps), but the server should also verify the client certificate.

1.B: channel.tcp: this includes two main classes: 1.B.i: TcpSslCommunicationChannel.cs: this is similar to TcpCommunicationChannel.cs but it uses Sslsteams. 1.B.ii: TcpSslConnectionListener.cs: this is similar to TcpConnectionListener.cs but uses Sslsteams.

1.C: Client.Tcp: this includes two main classes: 1.C.i: SslScsTcpClient.cs: this is similar to ScsTcpClient.cs but it creates communication channel using sslstreams. 1.C.ii: SslScsClientFactory.cs: this is similar to ScsClientFactory.cs.

1.D: Server.Tcp: changes here are similar to the changes in (1.C) but for the server.

### Third, new samples: It is important to provide examples on usage. I created similar examples as the ones you provided (copied and pasted), then modified them to SSL (few modifications). I commented the old lines to let the user see the few changes that they should make to convert older application using Scs to use SslScs. I also provide sample certificate for the server. (Only provided Server authentication mode examples). Currently working on mutual authentication.

Raknison123 commented 4 years ago

Is there a chance that this will be merged to a release? I am very interested in that feature.