Error: No credentials are available in the security package when using PEM files.
ksaye opened this issue · 3 comments
ksaye commented
Context
- OS, version, SKU and CPU architecture used: Version 10.0.19043.1165 on AMD64
- Application's .NET Target Framework : net5.0
- Device: Laptop
- SDK version used:
<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.37.2" />
<PackageReference Include="Microsoft.Azure.Devices.Provisioning.Client" Version="1.17.1" />
<PackageReference Include="Microsoft.Azure.Devices.Provisioning.Transport.Mqtt" Version="1.15.1" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="5.0.1" />
Description of the issue
Getting the error "No credentials are available in the security package" when importing PEM files. If I create a X509Certificate2 object from a PEM file (new feature in .Net 5.0), export it to a PFX file and then create an X509Cerfificate2 from that object, it works.
Note the error here if I just import the certificate from PEM:
Note the success if I save to PFX and then import:
Code sample exhibiting the issue
using Microsoft.Azure.Devices.Provisioning.Client;
using Microsoft.Azure.Devices.Shared;
using Microsoft.Azure.Devices.Provisioning.Client.Transport;
using System.Security.Cryptography.X509Certificates;
using System;
using Microsoft.Azure.Devices.Client;
using System.Text;
using System.IO;
namespace DPSBug
{
class Program
{
private static string dspScopeID = "0neXXXXXX";
private static string dspURL = "global.azure-devices-provisioning.net";
const string publicKeyFileName = "device.crt";
const string privateKeyFileName = "device.key";
static void Main(string[] args)
{
var certificate = X509Certificate2.CreateFromPemFile(publicKeyFileName, privateKeyFileName);
/* why is this section needed? */
byte[] exportCertificate = certificate.Export(X509ContentType.Pfx, "1234");
File.WriteAllBytes("export.pfx", exportCertificate);
certificate = new X509Certificate2(@"export.pfx", "1234");
/* why is this section needed? */
var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly);
var security = new SecurityProviderX509Certificate(certificate);
ProvisioningDeviceClient provClient =
ProvisioningDeviceClient.Create(dspURL, dspScopeID, security, transport);
var result = provClient.RegisterAsync().Result;
var auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId.ToString(), certificate);
var protocol2 = TransportType.Mqtt;
DeviceClient client = DeviceClient.Create(result.AssignedHub.ToString(), auth, protocol2);
client.OpenAsync().Wait();
client.SendEventAsync(new Message(Encoding.UTF8.GetBytes("Hello"))).Wait();
client.CloseAsync().Wait();
Console.WriteLine("Hello World!");
}
}
}
ksaye commented
ksaye commented
Closing this issue as it is an issue with SCHANNEL in Windows: dotnet/runtime#23749 (comment). Linux does not show the issue and in code it can be addressed with the following simple command:
certificate = new X509Certificate2(certificate.Export(X509ContentType.Pfx));