0 votes
by (120 points)

Hi I am evaluating Rebex TlsSocket to establish secured TLS1.2 MQTT connection with Aws IoT Hub. We have volume field devices and a successful trial should help us connect all the field devices with AWS IoT Hub.

I referred to this article and followed all steps https://forum.rebex.net/9807/how-to-use-tlssocket-directly?show=9807#q9807

Code:

this.tlsSocket = new TlsClientSocket();
tlsSocket.LogWriter = new Rebex.FileLogWriter(@"D:\log.txt",Rebex.LogLevel.Debug);
this.tlsSocket.Connect(new IPEndPoint(this.remoteIpAddress, this.remotePort));
tlsSocket.Parameters.Version = TlsVersion.TLS12;
//var cert = Certificate.LoadPfx("devicecert.pfx", "");
tlsSocket.Parameters.CertificateRequestHandler = CertificateRequestHandler.CreateRequestHandler(clientCert);
tlsSocket.Parameters.CertificateVerifier = CertificateVerifier.Default;
tlsSocket.ValidatingCertificate += new EventHandler<SslCertificateValidationEventArgs>(tlsSocket_ValidatingCertificate);

I am getting following error:

2023-05-23 00:12:00 INFO TlsSocket(54267293)[1] TLS: Performing client certificate authentication.
2023-05-23 00:12:00 DEBUG TlsSocket(54267293)[1] TLS: Error while processing TLS packet: System.Security.Cryptography.CryptographicException: Unable to create SHA256 hash using 楍牣獯景⁴湅慨据摥䌠祲瑰杯慲桰捩倠潲楶敤⁲ㅶ〮� (0x80090008).
   at ghric.xtdkc.wbbry(Byte[] p0, aippr p1)
   at Rebex.Security.Cryptography.AsymmetricKeyAlgorithm.SignHash(Byte[] hash, SignatureHashAlgorithm hashAlgorithm)
   at ghric.autbd.hwlnr(Byte[] p0, Int32 p1, Int32 p2, ivnfx p3)
   at ghric.autbd.fwlia(Byte[] p0, Int32 p1, Int32 p2)
   at ghric.yexzh.fcfxr(Byte[] p0, Int32 p1, Int32 p2)
   at ghric.yexzh.loqiv()
2023-05-23 00:12:01 INFO TlsSocket(54267293)[1] TLS: Fatal Alert:InternalError was sent.
2023-05-23 00:13:07 Opening log file.
2023-05-23 00:13:07 INFO FileLogWriter(1)[1] Info: Assembly: Rebex.Common R5.11 for .NET Compact Framework 3.5

My client Certificate file "devicecert.pfx does not have any password set. I am able to use same certificate on .NET 4.5 Windows to connect.

Applies to: Rebex TLS

1 Answer

0 votes
by (148k points)

PFX support is limited on .NET CF 3.5 on platforms that don't support SHA-2, which seems to be the case here.

As a workaround, load the certificate and the private key from files. To create those two files, load the PFX file on .NET 4.5 on Windows and convert it to a .cer/.pri file pair:

var cert = Certificate.LoadPfx("devicecert.pfx", password); 
cert.Save("devicecert.cer", CertificateFormat.Base64Der);
cert.SavePrivateKey("devicecert.key", password, PrivateKeyFormat.Base64Pkcs8, true);

Then, in .NET CF 3.5 application, load the certificate from those two files instead of the PFX:

var clientCert = Certificate.LoadDerWithKey("devicecert.cer", "devicecert.key", "password");
by (120 points)
Thanks for your revert Lukas,

I tried what you suggested and in the log I see that TLS1.2 Handshake is complete, but shortly after the connection gets dropped. I am using https://github.com/eclipse/paho.mqtt.m2mqtt library and when i try to establish connect from .NET 4.5 everything works fine with .Net SSL

2023-05-23 15:18:15 DEBUG TlsSocket(55530882)[1] TLS: Certificate verification result: Accept
2023-05-23 15:18:15 DEBUG TlsSocket(55530882)[1] TLS: Client certificate authentication was requested.
2023-05-23 15:18:15 DEBUG TlsSocket(55530882)[1] TLS: Suitable client certificate is available ('CN=AWS IoT Certificate').
2023-05-23 15:18:15 DEBUG TlsSocket(55530882)[1] TLS: HandshakeMessage:Certificate was sent.
2023-05-23 15:18:15 DEBUG TlsSocket(55530882)[1] TLS: HandshakeMessage:ClientKeyExchange was sent.
2023-05-23 15:18:15 INFO TlsSocket(55530882)[1] TLS: Performing client certificate authentication.
2023-05-23 15:18:15 DEBUG TlsSocket(55530882)[1] TLS: HandshakeMessage:CertificateVerify was sent.
2023-05-23 15:18:15 DEBUG TlsSocket(55530882)[1] TLS: CipherSpec:ChangeCipherSpec was sent.
2023-05-23 15:18:15 DEBUG TlsSocket(55530882)[1] TLS: HandshakeMessage:Finished was sent.
2023-05-23 15:18:16 DEBUG TlsSocket(55530882)[1] TLS: CipherSpec:ChangeCipherSpec was received.
2023-05-23 15:18:16 DEBUG TlsSocket(55530882)[1] TLS: HandshakeMessage:Finished was received.
2023-05-23 15:18:16 INFO TlsSocket(55530882)[1] TLS: Connection secured using cipher: TLS 1.2, RSA, AES with 128-bit key in GCM mode, AEAD.
2023-05-23 15:18:17 DEBUG TlsSocket(55530882)[3] TLS: Alert:CloseNotify was received.
2023-05-23 15:18:17 DEBUG TlsSocket(55530882)[3] TLS: Alert:CloseNotify was sent.
by (120 points)
Running on Toradex VF60 with WinCE6

Code: (Please note the ca certificated is passed as null)
var clientCert = Certificate.LoadDerWithKey(Path.Combine(root,"devicecert.cer"), Path.Combine(root, "devicecert.key"), "m2mlogger");
Console.WriteLine("Client Cert");
var client = new MqttClient("a14qk1rdcpv6rz-ats.iot.us-east-1.amazonaws.com", 8883, true, null,clientCert,MqttSslProtocols.TLSv1_2);

var clientId = Guid.NewGuid().ToString();
client.Connect(clientId);
Console.WriteLine("Connect");
var strValue = Convert.ToString(10);


At TlsSocket
  this.tlsSocket = new TlsClientSocket();
            tlsSocket.LogWriter = new Rebex.FileLogWriter(@"log.txt", Rebex.LogLevel.Debug);
            this.tlsSocket.Connect(new IPEndPoint(this.remoteIpAddress, this.remotePort));
            tlsSocket.Parameters.Version = TlsVersion.TLS12;
            tlsSocket.Parameters.CertificateRequestHandler = CertificateRequestHandler.CreateRequestHandler(clientCert);
            tlsSocket.Parameters.CertificateVerifier = CertificateVerifier.Default;
            tlsSocket.ValidatingCertificate += new EventHandler<SslCertificateValidationEventArgs>(tlsSocket_ValidatingCertificate);


I am getting this error
"The first certificate in the chain does not have an associated private key.\r\nParameter name: certificateChain


Not sure what am I doing wrong here?
by (148k points)
The error ("The first certificate in the chain does not have an associated private key") is thrown by CertificateRequestHandler.CreateRequestHandler if it determines that the private key for the certificate is not available. Does this fail as well?

    var clientCert = Certificate.LoadDerWithKey(Path.Combine(root,"devicecert.cer"), Path.Combine(root, "devicecert.key"), "m2mlogger");
    var requestHandler = CertificateRequestHandler.CreateRequestHandler(clientCert);
by (148k points)
Please try running the same code using .NET 4.x version of Rebex TLS on Windows. This will make it possible to determine whether the problem is related only to .NET CF, or whether it affects the classic .NET Framework as well. Thanks!
by (120 points)
Hi Lukas

var clientCert = Certificate.LoadDerWithKey(Path.Combine(root,"devicecert.cer"), Path.Combine(root, "devicecert.key"), "m2mlogger");
    var requestHandler = CertificateRequestHandler.CreateRequestHandler(clientCert);

No error received on running these two lines. However in requestHandler object RootCertificate property I could see "Could notevaluate expression"

The other test will do and revert
by (148k points)
OK, so if you are actually able to create a CertificateRequestHandler, try something like this:

            var clientCert = Certificate.LoadDerWithKey(Path.Combine(root,"devicecert.cer"), Path.Combine(root, "devicecert.key"), "m2mlogger");
            var requestHandler = CertificateRequestHandler.CreateRequestHandler(clientCert);
            ...

            this.tlsSocket = new TlsClientSocket();
            tlsSocket.LogWriter = new Rebex.FileLogWriter(@"log.txt", Rebex.LogLevel.Debug);
            this.tlsSocket.Connect(new IPEndPoint(this.remoteIpAddress, this.remotePort));
            tlsSocket.Parameters.Version = TlsVersion.TLS12;
            tlsSocket.Parameters.CertificateRequestHandler = requestHandler;
            tlsSocket.Parameters.CertificateVerifier = CertificateVerifier.Default;
            tlsSocket.ValidatingCertificate += new EventHandler<SslCertificateValidationEventArgs>(tlsSocket_ValidatingCertificate);

The RootCertificate property can be null. It's not required by the server anyway because the server already has access to root certificates it trusts.
by (120 points)
2023-05-29 22:17:16.854 DEBUG TlsClientSocket(1)[5] TLS: Verifying server key exchange signature.
2023-05-29 22:17:16.881 DEBUG TlsClientSocket(1)[5] TLS: Using ephemeral ECDH public key exchange with NIST P-256 curve.
2023-05-29 22:17:16.895 DEBUG TlsClientSocket(1)[5] TLS: Client certificate authentication was requested.
2023-05-29 22:17:16.895 DEBUG TlsClientSocket(1)[5] TLS: Suitable client certificate is available ('CN=AWS IoT Certificate').
2023-05-29 22:17:16.910 DEBUG TlsClientSocket(1)[5] TLS: HandshakeMessage:Certificate was sent.
2023-05-29 22:17:16.922 DEBUG TlsClientSocket(1)[6] TLS: HandshakeMessage:ClientKeyExchange was sent.
2023-05-29 22:17:16.945 INFO TlsClientSocket(1)[6] TLS: Performing client certificate authentication.
2023-05-29 22:17:16.975 DEBUG TlsClientSocket(1)[6] TLS: Error while processing TLS packet: System.Security.Cryptography.CryptographicException: Unable to export private key in order to use a more capable algorithm. ---> System.Security.Cryptography.CryptographicException: Private key is not exportable.
   at xoosa.nghvv.jyowc(Boolean p0, ICspAsymmetricAlgorithm p1, Boolean p2)
   at xoosa.njzfh.kbjyg(Boolean p0)
   at xoosa.uzrll.zdwrd(rdmyh p0, Func`2 p1, String p2)
   --- End of inner exception stack trace ---
   at xoosa.uzrll.zdwrd(rdmyh p0, Func`2 p1, String p2)
   at xoosa.uzrll.zzwgx(wkbqw p0)
   at xoosa.uzrll.aqxjn(inlme p0)
   at xoosa.uzrll.cnpdg(Byte[] p0, inlme p1)
   at Rebex.Security.Cryptography.AsymmetricKeyAlgorithm.SignHash(Byte[] hash, SignatureHashAlgorithm hashAlgorithm)
   at Rebex.Security.Certificates.Certificate.SignHash(Byte[] hash, SignatureHashAlgorithm alg, Boolean silent)
   at xoosa.ftwpq.<OnHandshakeReceivedClient>d__46.tbjgj()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at xoosa.ftwpq.<OnHandshakeReceived>d__44.rqnzf()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at xoosa.sccnz.<ProcessHandshakeAsync>d__73.jqlma()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at xoosa.sccnz.<processInnerAsync>d__79.bantj()
2023-05-29 22:17:16.983 INFO TlsClientSocket(1)[6] TLS: Fatal Alert:InternalError was sent.
by (120 points)
Hi Lukas,

If you have any working sample / instruction to use TLS library with AWs IoT for WinCE6 devices then it will be great. We can follow the same process.
by (148k points)
Sorry, we don't have any ready-to-use sample code yet.

The last log was created on desktop Windows, right? Did you use Certificate.LoadPfx there? In that case, specify the KeySetOptions.AlwaysCng option in the LoadPfx call. Otherwise, the key might get imported in to the legacy CryptoAPI container which is not fully capable.

But just guessing here, it's hard to tell with partial log and no code.
by (120 points)
Sorry my bad for not specifying the code.
Tried the KeySetOptions.AlwaysCng option getting error.

var cert = Certificate.LoadPfx("devicecert.pfx", string.Empty, KeySetOptions.AlwaysCng);
            cert.Save("device.cer", CertificateFormat.Base64Der);
            cert.SavePrivateKey("device.key", "", PrivateKeyFormat.Base64Pkcs8, false);


Error:
System.Security.Cryptography.CryptographicException: 'Unable to export CNG key (0x80090029).'
by (148k points)
For key conversion, you have to specify KeySetOptions.Exportable as well:
    var cert = Certificate.LoadPfx("devicecert.pfx", string.Empty, KeySetOptions.AlwaysCng | KeySetOptions.Exportable);
    cert.Save("device.cer", CertificateFormat.Base64Der);
    cert.SavePrivateKey("device.key", "", PrivateKeyFormat.Base64Pkcs8, false);
by (120 points)
Hi Lukas,


Ran the corrected code you shared
            var cert = Certificate.LoadPfx("devicecert.pfx", string.Empty, KeySetOptions.AlwaysCng | KeySetOptions.Exportable);
            cert.Save("device.cer", CertificateFormat.Base64Der);
            cert.SavePrivateKey("device.key", "", PrivateKeyFormat.Base64Pkcs8, false);

Still looks to be same error:
System.Security.Cryptography.CryptographicException
  HResult=0x80131430
  Message=Unable to export CNG key (0x80090029).
  Source=Rebex.Common
  StackTrace:
   at xoosa.pupml.rpmgi(Boolean p0, String p1)
   at xoosa.pupml.kbjyg(Boolean p0)
   at xoosa.uzrll.sxati(Boolean p0)
   at Rebex.Security.Cryptography.AsymmetricKeyAlgorithm.GetPrivateKey()
   at Rebex.Security.Certificates.Certificate.SavePrivateKey(String fileName, String password, PrivateKeyFormat format, Boolean silent)
   at ConsoleApp1.Program.Main(String[] args)

I don't know if it helps, devicecert.pfx was created by this command:

openssl pkcs12 -export -out devicecert.pfx -inkey d509e24fa6-private.pem.key -in d509e24fa6-certificate.pem.crt
by (148k points)
Sorry, I somehow overlooked that you were still using LoadPfx in order to convert the .pfx to .cer/.key pair. AlwaysCng does not allow that.

So let's get back to "Unable to export private key in order to use a more capable algorithm" error. Could you please give this a try and let me know whether it fails as well?

var cert = Certificate.LoadPfx(devicecert.pfx", string.Empty);
cert.Save("device.cer", CertificateFormat.Base64Der);
cert.SavePrivateKey("device.key", "", PrivateKeyFormat.Base64Pkcs8, false);

var cert2 = Certificate.LoadDerWithKey("device.cer", "device.key", "");
cert2.GetRSAParameters(true, true);
by (120 points)
Hi Lukas

This works fine without any exception
            var cert = Certificate.LoadPfx("devicecert.pfx", string.Empty);
            cert.Save("device.cer", CertificateFormat.Base64Der);
            cert.SavePrivateKey("device.key", "", PrivateKeyFormat.Base64Pkcs8, false);

Loading the key in .Net4X environemnt
            var clientCert = Certificate.LoadDerWithKey("device.cer", "device.key", "");
            clientCert.GetRSAParameters(true, true);
            var client = new MqttClient("a14qk1rdcpv6rz-ats.iot.us-east-1.amazonaws.com", 8883, true, null,clientCert,
                                        MqttSslProtocols.TLSv1_2);

            var clientId = "1";
            client.Connect(clientId);

In the "Connect" method:
            this.tlsSocket = new TlsClientSocket();
            tlsSocket.LogWriter = new Rebex.FileLogWriter(@"log.txt", Rebex.LogLevel.Debug);
            this.tlsSocket.Connect(new IPEndPoint(this.remoteIpAddress, this.remotePort));
            tlsSocket.Parameters.Version = TlsVersion.TLS12;
            tlsSocket.Parameters.CertificateRequestHandler = CertificateRequestHandler.CreateRequestHandler(clientCert);
            tlsSocket.Parameters.CertificateVerifier = CertificateVerifier.Default;
            tlsSocket.ValidatingCertificate += new EventHandler<SslCertificateValidationEventArgs>(tlsSocket_ValidatingCertificate);


Exception
uPLibrary.Networking.M2Mqtt.Exceptions.MqttConnectionException: 'Exception connecting to the broker'
TlsException: Unable to export private key in order to use a more capable algorithm.
CryptographicException: Private key is not exportable.

Complete Log for your reference:
2023-06-02 05:31:26.077 Opening log file.
2023-06-02 05:31:26.083 INFO FileLogWriter(1)[1] Info: Assembly: Rebex.Common R6.12 for .NET 4.6-4.8
2023-06-02 05:31:26.085 INFO FileLogWriter(1)[1] Info: Platform: Windows 6.2.9200 32-bit; CLR: 4.0.30319.42000
2023-06-02 05:31:26.086 DEBUG FileLogWriter(1)[1] Info: Culture: en; Windows-1252
2023-06-02 05:31:26.114 INFO TlsClientSocket(1)[1] Info: Assembly: Rebex.Tls R6.12 for .NET 4.6-4.8 (Trial)
2023-06-02 05:31:26.114 INFO TlsClientSocket(1)[1] Info: Platform: Windows 6.2.9200 32-bit; CLR: 4.0.30319.42000
2023-06-02 05:31:26.114 DEBUG TlsClientSocket(1)[1] Info: Culture: en; Windows-1252
2023-06-02 05:31:26.114 INFO TlsClientSocket(1)[1] Info: Connecting to 2406:da00:ff00::12cc:7f64:8883 using TlsClientSocket.
2023-06-02 05:31:26.381 DEBUG TlsClientSocket(1)[1] Info: Connection established (socket #1CA0192).
2023-06-02 05:31:26.651 INFO TlsClientSocket(1)[1] TLS: Starting TLS negotiation.
2023-06-02 05:31:26.651 DEBUG TlsClientSocket(1)[1] TLS: Using TLS 1.2 core.
2023-06-02 05:31:26.932 DEBUG TlsClientSocket(1)[1] TLS: Enabled cipher suites: 0x000F3DF7EBE00640.
2023-06-02 05:31:26.932 DEBUG TlsClientSocket(1)[1] TLS: Applicable cipher suites: 0x000F3DF7EBE00640.
2023-06-02 05:31:27.090 DEBUG TlsClientSocket(1)[1] TLS: HandshakeMessage:ClientHello was sent.
2023-06-02 05:31:27.118 DEBUG TlsClientSocket(1)[1] Info: Using modern transport layer.
2023-06-02 05:31:27.519 DEBUG TlsClientSocket(1)[3] TLS: HandshakeMessage:ServerHello was received.
2023-06-02 05:31:27.529 INFO TlsClientSocket(1)[3] TLS: Negotiating TLS 1.2, RSA with ephemeral ECDH, AES with 128-bit key in GCM mode, AEAD.
2023-06-02 05:31:27.553 DEBUG TlsClientSocket(1)[3] TLS: The server supports secure renegotiation.
2023-06-02 05:31:27.560 DEBUG TlsClientSocket(1)[3] TLS: Extended master secret is enabled.
2023-06-02 05:31:27.586 DEBUG TlsClientSocket(1)[5] TLS: HandshakeMessage:Certificate was received.
2023-06-02 05:31:27.606 DEBUG TlsClientSocket(1)[5] TLS: HandshakeMessage:ServerKeyExchange was received.
2023-06-02 05:31:27.618 DEBUG TlsClientSocket(1)[5] TLS: HandshakeMessage:CertificateRequest was received.
2023-06-02 05:31:27.618 DEBUG TlsClientSocket(1)[5] TLS: HandshakeMessage:ServerHelloDone was received.
2023-06-02 05:31:27.626 DEBUG TlsClientSocket(1)[5] TLS: Verifying server certificate ('CN=*.iot.us-east-1.amazonaws.com').
2023-06-02 05:31:27.635 DEBUG TlsClientSocket(1)[5] TLS: Certificate verification result: Accept
2023-06-02 05:31:27.637 DEBUG TlsClientSocket(1)[5] TLS: Verifying server key exchange signature.
2023-06-02 05:31:27.684 DEBUG TlsClientSocket(1)[5] TLS: Using ephemeral ECDH public key exchange with NIST P-256 curve.
2023-06-02 05:31:27.695 DEBUG TlsClientSocket(1)[5] TLS: Client certificate authentication was requested.
2023-06-02 05:31:27.695 DEBUG TlsClientSocket(1)[5] TLS: Suitable client certificate is available ('CN=AWS IoT Certificate').
2023-06-02 05:31:27.708 DEBUG TlsClientSocket(1)[5] TLS: HandshakeMessage:Certificate was sent.
2023-06-02 05:31:27.717 DEBUG TlsClientSocket(1)[9] TLS: HandshakeMessage:ClientKeyExchange was sent.
2023-06-02 05:31:27.740 INFO TlsClientSocket(1)[9] TLS: Performing client certificate authentication.
2023-06-02 05:31:27.762 DEBUG TlsClientSocket(1)[9] TLS: Error while processing TLS packet: System.Security.Cryptography.CryptographicException: Unable to export private key in order to use a more capable algorithm. ---> System.Security.Cryptography.CryptographicException: Private key is not exportable.
   at xoosa.nghvv.jyowc(Boolean p0, ICspAsymmetricAlgorithm p1, Boolean p2)
   at xoosa.njzfh.kbjyg(Boolean p0)
   at xoosa.uzrll.zdwrd(rdmyh p0, Func`2 p1, String p2)
   --- End of inner exception stack trace ---
   at xoosa.uzrll.zdwrd(rdmyh p0, Func`2 p1, String p2)
   at xoosa.uzrll.zzwgx(wkbqw p0)
   at xoosa.uzrll.aqxjn(inlme p0)
   at xoosa.uzrll.cnpdg(Byte[] p0, inlme p1)
   at Rebex.Security.Cryptography.AsymmetricKeyAlgorithm.SignHash(Byte[] hash, SignatureHashAlgorithm hashAlgorithm)
   at Rebex.Security.Certificates.Certificate.SignHash(Byte[] hash, SignatureHashAlgorithm alg, Boolean silent)
   at xoosa.ftwpq.<OnHandshakeReceivedClient>d__46.tbjgj()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at xoosa.ftwpq.<OnHandshakeReceived>d__44.rqnzf()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at xoosa.sccnz.<ProcessHandshakeAsync>d__73.jqlma()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at xoosa.sccnz.<processInnerAsync>d__79.bantj()
2023-06-02 05:31:27.768 INFO TlsClientSocket(1)[9] TLS: Fatal Alert:InternalError was sent.
by (148k points)
We have been trying to reproduce this issue, but the error doesn't occur with any of our certificates and servers on any platform. Could you please try connecting to the target server with just the following code?

var cert = Certificate.LoadPfx("devicecert.pfx", string.Empty);
cert.Save("device.cer", CertificateFormat.Base64Der);
cert.SavePrivateKey("device.key", "", PrivateKeyFormat.Base64Pkcs8, false);

var clientCert = Certificate.LoadDerWithKey("device.cer", "device.key", "");
clientCert.GetRSAParameters(true, true);

var tlsSocket = new TlsClientSocket();
tlsSocket.LogWriter = TestUtils.LogWriter;

tlsSocket.Parameters.Version = TlsVersion.TLS12;
tlsSocket.Parameters.CertificateRequestHandler = CertificateRequestHandler.CreateRequestHandler(clientCert);
tlsSocket.Parameters.CertificateVerifier = CertificateVerifier.Default;
tlsSocket.ValidatingCertificate += (sender, args) => args.Accept();

string address = Dns.GetHostAddresses("a14qk1rdcpv6rz-ats.iot.us-east-1.amazonaws.com")[0];

tlsSocket.Connect(address, 8883);
tlsSocket.Negotiate();
tlsSocket.Dispose();

If this still keeps failing, we would have to provide a build of Rebex libraries with more thorough logging in order to find out what is going on.
by (120 points)
Will it help if I transfer the raw AWS certificates. If yes please share a secured link.
by (148k points)
Can you upload it via SFTP to our secure data exchange server? I'll send you the server info and credentials to your e-mail address.
by (120 points)
Hi Lukas,

Original Device Certificate, pfx certificate and all source codes are uploaded.
by (148k points)
Thanks! We found the cause of the issue. The MqttClient class constructor expects the client certificate as in insatnce of .NET's X509Certificate class. However, the application passes an instance of Rebex Certificate. This is converted to X509Certificate automatically, but the conversion causes the associated key (loaded using Certificate.LoadDerWith) to be ignored. Later, when TlsSocket is used, the instance of X509Certificate is converted back to Certificate, but the key is not there, causing an error in CreateRequestHandler call.

Check out the "Test Application Patched.zip" file we uploaded to the SFTP server - this includes patched versions of MqttClient and MqttNetworkChannel classes that replaces X509Certificate with Certificate. TlsSocket.Negotiate seems to work fine now.
by (120 points)
Hi Lukas,

Thanks for troubleshooting this. But with patched Code, soon after TLS negotiate

-06-07 22:02:45.009 INFO TlsClientSocket(1)[6] TLS: Connection secured using cipher: TLS 1.2, RSA with ephemeral ECDH, AES with 128-bit key in GCM mode, AEAD.
2023-06-07 22:02:45.378 DEBUG TlsClientSocket(1)[3] TLS: Alert:CloseNotify was received.
2023-06-07 22:02:45.381 DEBUG TlsClientSocket(1)[3] TLS: Alert:CloseNotify was sent.

And the connection is closed. This behavior is same as https://forum.rebex.net/22322/rebex-tlssocket-on-netcf3-5?show=22326#c22326
by (148k points)
Hi, I noticed this as well and investigated a bit - the server closes the connection when it receives the client's message (sent in MqttClient.SendReceive method). If the client does not send any message, the server keeps waiting and does not close the connection. The most likely explanation is that the server did not like the message and therefore closed the connection. A server-side log would hopefully reveal what's going on and why the server closed the connection.

Do you have any code using .NET's SslStream that sends the same message and the connection does not get closed? We could look into it and determine where's the difference.
by (120 points)
Hi Lukas,

Added Test Application Win.zip to the SFTP location.

Interestingly .NET X509Certificate was not working but with X509Certificate2 everything works fine. I thought to share with you incase this of any help.

Also, do you think it might be timeout related issues? tls.Negotiate() with Rebex libraries takes some time.

Since we are connecting with AWS server, we may not have any log from there.
by (148k points)
Hi, the cause of the issue turned out to be quite simple - in the Rebex-based version of MqttNetworkChannel.Connect method, you were connecting to an IP address but did not pass the remote host name to the server. Try adding this line:

    tlsSocket.Parameters.CommonName = this.remoteHostName;

(Also remove "this.netStream.Close()" and "this.socket.Close();" from the Close method as well because those field are unused and would cause a NullReferenceException.)
by (120 points)
Hi Lukas
Thanks it works like a charm on the Patched code that we were working on in SFTP folder. Will be testing on the device and let you know the result.
by (120 points)
Hi Lukas,

The WINCE NET CF test was delayed and I could not return back to you with results:

SoC: Toradex VF50
OS: WINCE6
NET CF: 3.5
Rebex binaries: 5.0.8930.0
License Key: Latest

After mqttClient.Connect() is called the applications goes in hang state. We are not able to connect any log from

tlsSocket = new TlsClientSocket();
tlsSocket.LogWriter = new Rebex.FileLogWriter(@"\\Flashdisk\\SandBag\\log.txt", Rebex.LogLevel.Debug);
tlsSocket.Connect(new IPEndPoint(remoteIpAddress, remotePort));

The same code works fine on Windows 11 PC with .NET 4.8

Please suggest!
by (148k points)
I am sorry, but we cannot afford to support you for free, particularly on legacy platforms that are no longer officially supported at all! Ale, please note that the evaluation period for Rebex libraries is one month, not one year. When the trial period expired, you were supposed to either stop using Rebex TLS library, or purchase a license.

Additionally, if the following code does not produce any log file at all:
    var tlsSocket = new TlsClientSocket();
    tlsSocket.LogWriter = new Rebex.FileLogWriter(@"\\Flashdisk\\SandBag\\log.txt", Rebex.LogLevel.Debug);
    tlsSocket.Connect(new IPEndPoint(remoteIpAddress, remotePort));

Then it means that something is seriously wrong with the device or OS, and I'm afraid we can't really help you with that with no access to that particular device. Does an application running on the WinCE device indeed hang and not produce any log file if no other action is performed? And are you able to connect to the same endpoint using .NET's System.Net.Sockets.Socket class?
by (120 points)
Lukas, your point is valid! And there is no intention for misuse of libraries or Trial period.

There was a resourcing issue and it was difficult to find new resource for legacy technology, in the mean time other product development caught up.

Making a purchase is not a problem. Post purchase need your support to ensure smooth integration on above platform.


Awaiting your confirmation.
by (148k points)
The thing is, Window CE 6.0 reached end-of-life more than 6 years ago, and supporting it is getting more difficult for us as well. To make things even worse, Microsoft has unfortunately shut down MSDN TechNet forums for .NET CF and Windows CE, making the vast database of problems and solutions inaccessible.

But let's try...
- Are you able to reproduce the issue on other WinCE devices, or in an emulator?
- Make sure you are actually able to connect to the remote endpoint using .NET's System.Net.Sockets.Socket class. If this fails as well, Rebex libraries won't be able to connect either.
- Instead of using the TlsClientSocket from Rebex.Tls assembly, try using TlsSocket from Rebex.Networking assembly (and remove the Rebex.Tls assembly reference from the project). Does this make any difference?
by (120 points)
Hi Lukas,

I understand the concerns you have mentioned and we are also experiencing difficulty maintaining these legacy products.

I am testing on actual device i.e. Toradex VF50 running WinCE6

Test 1: Testing System.Net.Sockets.Socket
        public void Connect()
        {
            Console.WriteLine("Socket Connect...");
            this.socket = new Socket(this.remoteIpAddress.GetAddressFamily(), SocketType.Stream, ProtocolType.Tcp);
            // try connection to the broker
            this.socket.Connect(new IPEndPoint(this.remoteIpAddress, this.remotePort));
            Console.WriteLine("Done");

            //this.tlsSocket = new TlsClientSocket();
            //tlsSocket.LogWriter = new Rebex.FileLogWriter(@"log.txt", Rebex.LogLevel.Debug);
            //this.tlsSocket.Connect(new IPEndPoint(this.remoteIpAddress, this.remotePort));
            //tlsSocket.Parameters.Version = TlsVersion.TLS12;
            //tlsSocket.Parameters.CertificateRequestHandler = CertificateRequestHandler.CreateRequestHandler(clientCert);
            //tlsSocket.Parameters.CertificateVerifier = CertificateVerifier.Default;
            //tlsSocket.ValidatingCertificate += new EventHandler<SslCertificateValidationEventArgs>(tlsSocket_ValidatingCertificate);
            //tlsSocket.Parameters.CommonName = this.remoteHostName;


Output:
\flashdisk\sandbag> sandbag
Starting...
Loaded Certificates...
Get RSA parameters...
MQTT Client...
Subscribe...
Socket Connect...
Done

Inference:
This mean System.Net.Sockets.Socket Connect is ok

Test 2: Rebex.Tls.Co

        public void Connect()
        {
            Console.WriteLine("Socket Connect...");
            this.tlsSocket = new TlsClientSocket();
            tlsSocket.LogWriter = new Rebex.FileLogWriter(@"\\Flashdisk\\SandBag\\log.txt", Rebex.LogLevel.Debug);
            this.tlsSocket.Connect(new IPEndPoint(this.remoteIpAddress, this.remotePort));
            Console.WriteLine("Done");
            tlsSocket.Parameters.Version = TlsVersion.TLS12;
            tlsSocket.Parameters.CertificateRequestHandler = CertificateRequestHandler.CreateRequestHandler(clientCert);
            tlsSocket.Parameters.CertificateVerifier = CertificateVerifier.Default;
            tlsSocket.ValidatingCertificate += new EventHandler<SslCertificateValidationEventArgs>(tlsSocket_ValidatingCertificate);
            tlsSocket.Parameters.CommonName = this.remoteHostName;

Output:
\flashdisk\sandbag> sandbag
Starting...
Loaded Certificates...
Get RSA parameters...
MQTT Client...
Subscribe...
Socket Connect...

Inference:
Rebex.Tls.TlsClientSocket Connect is not proceeding

I also tried using Rebex.Net.TlsSocket but same result as Test 2
by (148k points)
- Is there anything in the log file at \Flashdisk\SandBag\log.txt?

- Are you able to reproduce the issue on other WinCE device, or in an emulator?

- If you put the tls.Connect call inside a try/catch(Exception error) block, and do Console.WriteLine(error) in the catch block, does this write anything to the output?
...