You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When configuring MQTTnet with mTLS using WithClientCertificates, disposing the X509Certificate2 object before MqttClientOptionsBuilder.Build() causes the TLS handshake to fail with a tlsv13 alert certificate required error. This suggests MQTTnet (or underlying .NET SslStream) might retain a reference to the X509Certificate2 object rather than copying its data immediately, leading to issues when the object is disposed early. This behavior is inconsistent with the expectation that certificate data is copied during configuration, as noted in .NET networking patterns.
Create an MQTT client with mTLS using a PEM certificate and key and use the keyword using for the X509Certificate2
varmqttClient=newMqttFactory().CreateMqttClient();varcertPem=File.ReadAllText("cert.pem");varkeyPem=File.ReadAllText("key.pem");usingvarclientCertificate=X509Certificate2.CreateFromPem(certPem,keyPem);// Case 1: Dispose before Build() - FailsusingvarclientCertificatePfx=newX509Certificate2(clientCertificate.Export(X509ContentType.Pkcs12));varoptionsBuilder=newMqttClientOptionsBuilder().WithTcpServer("broker.example.com",8883).WithTlsOptions(o =>o.WithClientCertificates([clientCertificatePfx]));varoptions=optionsBuilder.Build();// clientCertificatePfx disposed hereawaitmqttClient.ConnectAsync(options);// Fails
Compare with non-disposed version
varclientCertificatePfx=newX509Certificate2(clientCertificate.Export(X509ContentType.Pkcs12));varoptionsBuilder=newMqttClientOptionsBuilder().WithTcpServer("broker.example.com",8883).WithTlsOptions(o =>o.WithClientCertificates([clientCertificatePfx]));varoptions=optionsBuilder.Build();// clientCertificatePfx still aliveawaitmqttClient.ConnectAsync(options);// Succeeds
Expected Behavior:
WithClientCertificates should copy the certificate data (public cert and private key) when called, allowing the X509Certificate2 object to be safely disposed before Build() or ConnectAsync(). This aligns with typical .NET networking patterns (e.g., HttpClient with client certificates).
Actual Behavior:
Disposing the X509Certificate2 object before Build() causes the TLS handshake to fail with:
Forces users to keep X509Certificate2 objects alive longer than necessary, risking memory leaks or requiring manual management.
Breaks idiomatic C# patterns like using for disposable resources, leading to unexpected failures in production code.
Suggested Fix:
Ensure WithClientCertificates deep-copies the certificate data (e.g., raw bytes of cert and key) into MqttClientOptions, avoiding reliance on the original X509Certificate2 object post-configuration.
Alternatively, document this behavior explicitly, warning users against early disposal.
The text was updated successfully, but these errors were encountered:
Description
When configuring MQTTnet with mTLS using WithClientCertificates, disposing the X509Certificate2 object before MqttClientOptionsBuilder.Build() causes the TLS handshake to fail with a tlsv13 alert certificate required error. This suggests MQTTnet (or underlying .NET SslStream) might retain a reference to the X509Certificate2 object rather than copying its data immediately, leading to issues when the object is disposed early. This behavior is inconsistent with the expectation that certificate data is copied during configuration, as noted in .NET networking patterns.
Environment:
MQTTnet Version: 5.0.1.1416
.NET Version: .NET 8.0
OS: Ubuntu 22.04,
Broker: custom MQTT broker requiring TLS 1.3 mTLS
Steps to Reproduce:
Create an MQTT client with mTLS using a PEM certificate and key and use the keyword using for the X509Certificate2
Compare with non-disposed version
Expected Behavior:
WithClientCertificates should copy the certificate data (public cert and private key) when called, allowing the X509Certificate2 object to be safely disposed before Build() or ConnectAsync(). This aligns with typical .NET networking patterns (e.g., HttpClient with client certificates).
Actual Behavior:
Disposing the X509Certificate2 object before Build() causes the TLS handshake to fail with:
Impact:
Forces users to keep X509Certificate2 objects alive longer than necessary, risking memory leaks or requiring manual management.
Breaks idiomatic C# patterns like using for disposable resources, leading to unexpected failures in production code.
Suggested Fix:
Ensure WithClientCertificates deep-copies the certificate data (e.g., raw bytes of cert and key) into MqttClientOptions, avoiding reliance on the original X509Certificate2 object post-configuration.
Alternatively, document this behavior explicitly, warning users against early disposal.
The text was updated successfully, but these errors were encountered: