0

According to TLS 1.3 & OpenSSL 1.1.1 on Linux I can use TLS 1.3 under linux in my "Console App (.NET Core)" project.

My codes

using System;
using System.IO;
using System.Net.Security;
using System.Net.Sockets;
using System.Reflection;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace TestTlsServer {
    class Program {
        static void Main(string[] args) {
            string curdir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            Console.WriteLine($"my assembly dir====>{curdir}");
            SslProtocols protocol = SslProtocols.Tls13;
            int port = 5555;
            RemoteCertificateValidationCallback certificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {
                return (true);
            };
            X509Certificate2 serverCert = new X509Certificate2("server.pfx", "testpass123");
            TcpListener server = TcpListener.Create(port);
            server.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
            server.Server.NoDelay = true;
            server.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
            server.Start();
            Task taskServer = Task.Run(() => {
                Console.WriteLine("Server started");
                while(true) {
                    TcpClient romoteClient = server.AcceptTcpClient();
                    Task.Run(() => {
                        Console.WriteLine($"==============>New Connection from {romoteClient.Client.RemoteEndPoint}");
                        using(romoteClient) {
                            using(SslStream sslStreamRomoteClient = new SslStream(romoteClient.GetStream(), false, certificateValidationCallback)) {
                                try {
                                    sslStreamRomoteClient.AuthenticateAsServer(serverCert, true, protocol, true);
                                    byte[] buf = new byte[1000];
                                    int len = sslStreamRomoteClient.Read(buf, 0, buf.Length);
                                    string receive = Encoding.UTF8.GetString(buf, 0, len);
                                    Console.WriteLine($"server receive:{receive}");
                                    string send = "Hi, this message is from server";
                                    sslStreamRomoteClient.Write(Encoding.UTF8.GetBytes(send));
                                    Console.WriteLine($"server send:{send}");
                                } catch(Exception ex) {
                                    Console.WriteLine("======Server Exception==========================");
                                    Console.WriteLine(ex);
                                }
                            }
                        }
                    });
                }
            });
            taskServer.Wait();
        }
    }
}

I compiled openssl-1.1.1h.tar.gz under centos7 and got libssl.so.1.1 and libcrypto.so.1.1, then i added these two libraries in my project as "content" enter image description here

Publish this project to a single file
enter image description here

Now i run this program under centos (Note: no openssl1.1.1 installed), the following exception came when i tried to connect to this server.

my assembly dir====>/var/tmp/.net/root/TestTlsServer/unsorm3j.o1q
Server started

==============>New Connection from [::ffff:192.168.18.44]:58131
======Server Exception==========================
System.Security.Authentication.AuthenticationException: Authentication failed, s                                                       ee inner exception.
 ---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SS                                                       L_ERROR_SSL.
 ---> Interop+Crypto+OpenSslCryptographicException: error:1408A0C1:SSL routines:                                                       ssl3_get_client_hello:no shared cipher
   --- End of inner exception stack trace ---
   at Interop.OpenSsl.DoSslHandshake(SafeSslHandle context, Byte[] recvBuf, Int3                                                       2 recvOffset, Int32 recvCount, Byte[]& sendBuf, Int32& sendCount)
   at System.Net.Security.SslStreamPal.HandshakeInternal(SafeFreeCredentials cre                                                       dential, SafeDeleteContext& context, ArraySegment`1 inputBuffer, Byte[]& outputB                                                       uffer, SslAuthenticationOptions sslAuthenticationOptions)
   --- End of inner exception stack trace ---
   at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken messa                                                       ge, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
   at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolTok                                                       en message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count,                                                        AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 cou                                                       nt, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readByte                                                       s, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartReceiveBlob(Byte[] buffer, AsyncProtoco                                                       lRequest asyncRequest)
   at System.Net.Security.SslStream.ForceAuthentication(Boolean receiveFirst, By                                                       te[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.ProcessAuthentication(LazyAsyncResult lazyRe                                                       sult, CancellationToken cancellationToken)
   at System.Net.Security.SslStream.AuthenticateAsServer(SslServerAuthentication                                                       Options sslServerAuthenticationOptions)
   at System.Net.Security.SslStream.AuthenticateAsServer(X509Certificate serverC                                                       ertificate, Boolean clientCertificateRequired, SslProtocols enabledSslProtocols,                                                        Boolean checkCertificateRevocation)
   at TestTlsServer.Program.<>c__DisplayClass0_1.<Main>b__2()

I think this is because the program can not load these libraries

/var/tmp/.net/root/TestTlsServer/unsorm3j.o1q/libcrypto.so.1.1
/var/tmp/.net/root/TestTlsServer/unsorm3j.o1q/libssl.so.1.1

Then i add this path into LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/var/tmp/.net/root/TestTlsServer/unsorm3j.o1q:$LD_LIBRARY_PATH

now it works correctly!!

my assembly dir====>/var/tmp/.net/root/TestTlsServer/unsorm3j.o1q
Server started
==============>New Connection from [::ffff:192.168.18.44]:58172
server receive:Hi, this message is from client (C++)
server send:Hi, this message is from server

Because some special reason i should not install openssl1.1.1 and change LD_LIBRARY_PATH on my target Centos PC. that is why i packed libssl.so.1.1 and libcrypto.so.1.1 in my program.

How can the program find the libraries without change "LD_LIBRARY_PATH"?

Or

How can the program change LD_LIBRARY_PATH only for itself?

Please give me some advice! help me!

  • 1
    You need to load the certificate (see https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#cryptographic-key-importexport). Read the link carefully. It sayd you don't need to use X509 but need to import the certificate. https://www.ssls.com/knowledgebase/how-to-install-an-ssl-certificate-on-a-tomcat-server/ – jdweng Dec 18 '20 at 15:22
  • I think now the problem is the program can not load the libraries because of the path is not included in LD_LIBRARY_PATH. Otherwise it works perfectly. –  Dec 18 '20 at 17:52
  • Yes, you need to ensure that `$LD_LIBRARY_PATH` contains the directory with the libraries. Given you are using CentOS 7, you might consider using `openssl11-devel` from EPEL 7 rather building (and maintaining) OpenSSL yourself (it also provides its libraries in the default library path). – rsc Dec 26 '20 at 03:44

0 Answers0