Azure / azure-iot-sdk-csharp

A C# SDK for connecting devices to Microsoft Azure IoT services
Other
466 stars 493 forks source link

[Bug Report] SampleX509 not working when running on WSL #3043

Closed lucassousa-ciandt closed 5 months ago

lucassousa-ciandt commented 1 year ago

Context

Description of the issue

Trying to register a device with test X509 certificates using this sample code, but I'm receiving an Exception instead. I'm basing in this guide.

Steps to reproduce:

  1. Using the script provided here to generate the certificates; a. Generate the root and intermediate certificate running: ./certGen.sh create_root_and_intermediate b. Generate the device certificate running: ./certGen.sh create_device_certificate_from_intermediate device-01
  2. Add the root certificate to the Azure IoT DPS;
  3. Create a new Enrollment Group with the intermediate certificate
  4. Convert the full-chain certificate to .pfx (following this guide)
  5. Run the project: dotnet run -- -s <id-scope> -c new-device-full-chain.cert.pfx -p 1234

Console log of the issue

Loading the certificate...
Found certificate: 853DCB7AB54219040654CEBEA114321A745C7743 CN=Azure IoT Hub CA Cert Test Only; PrivateKey: False
Found certificate: A08794FA100E6EFFF2DA766E0726AA85B231109C CN=Azure IoT Hub Intermediate Cert Test Only; PrivateKey: False
Found certificate: 4CB05F8765ABF86C125733479A60D5A903E5120B CN=device-01; PrivateKey: True
Using certificate 4CB05F8765ABF86C125733479A60D5A903E5120B CN=device-01
Initializing the device provisioning client...
Initialized for registration Id device-01.
Registering with the device provisioning service... 
Unhandled exception. Microsoft.Azure.Devices.Provisioning.Client.ProvisioningTransportException: {"errorCode":401002,"trackingId":"dbb773f7-70dd-4b97-b23b-fc8f137c5479","message":"CA certificate not found.","timestampUtc":"2022-12-21T17:08:21.2769411Z"}
   at Microsoft.Azure.Devices.Provisioning.Client.Transport.ProvisioningTransportHandlerMqtt.ProvisionOverTcpCommonAsync(ProvisioningTransportRegisterMessage message, ClientTlsSettings tlsSettings, CancellationToken cancellationToken)
   at Microsoft.Azure.Devices.Provisioning.Client.Transport.ProvisioningTransportHandlerMqtt.RegisterAsync(ProvisioningTransportRegisterMessage message, CancellationToken cancellationToken)
   at Microsoft.Azure.Devices.Provisioning.Client.Samples.ProvisioningDeviceClientSample.RunSampleAsync() in ./azure-iot-sdk-csharp/provisioning/device/samples/getting started/X509Sample/ProvisioningDeviceClientSample.cs:line 54
   at Microsoft.Azure.Devices.Provisioning.Client.Samples.Program.Main(String[] args) in ./azure-iot-sdk-csharp/provisioning/device/samples/getting started/X509Sample/Program.cs:line 30
   at Microsoft.Azure.Devices.Provisioning.Client.Samples.Program.<Main>(String[] args)

This only happens when I try to run on WSL, if I run the same steps on base OS (Windows) it works, only with the additional step to add the root and intermediate certificates on Windows Certificate Store. Any additional step is required when running it on Linux distribution? Am I missing some detail?

The same certificates also works when used in the NodeJS sample, same steps, just running another project and using the .pem certificate instead of converting it to .pfx.

brycewang-microsoft commented 7 months ago

Hi @lucassousa-ciandt, apologize for the delay in getting back to you. I could repro this while investigating a similar issue a few months ago. It appears to be caused by a limitation in .NET where SslStream sends the certificate chain information only if it is available in the certificate store, and this happens for both Windows and Linux.

So similar to the additional steps for Windows, I could work this around in my WSL by installing the intermediate certificate (only this was sufficient for me) in the local trust store and make the device provisioning succeed. To do this, please follow with the steps described here.

brycewang-microsoft commented 5 months ago

Close due to inactivity