I am working in Unity C# and I would like to combine 3 files into a .pfx file programmatically for an MQTT connection. I have found several posts on SO that are similar to what I am looking for, but I have not been able to modify them and get my desired result. Here are a few of the pages that I have been looking at:
Associate a private key with the X509Certificate2 class in .net
Create X509Certificate2 from Cert and Key, without making a PFX file
How to create .pfx file from certificate and private key?
This is the terminal command that I want to replicate in Unity C#:
openssl pkcs12 -export -out final.pfx -inkey private.pem.key -in AmazonRootCA1.pem -in certificate.pem.crt
I thought something like this might work, but .pfx file is not getting created:
X509Certificate2 GetPFX(string certPath, string keyFile, string caFile, string certFile, string pfxFile, string pfxPassword)
{
if (!File.Exists(pfxFile))
{
// Generate PFX
//openssl pkcs12 -export -out final.pfx -inkey private.pem.key -in AmazonRootCA1.pem -in certificate.pem.crt
string arguments = "openssl pkcs12 -export -out " + certPath + "" + pfxFile + " -inkey " + certPath + "" + keyFile + " -in " + certPath + "" + caFile + " -in " + certPath + "" + certFile;
ProcessStartInfo opensslPsi = new ProcessStartInfo("sudo", arguments);
opensslPsi.UseShellExecute = false;
opensslPsi.RedirectStandardOutput = true;
using (Process p = Process.Start(opensslPsi))
{
p.WaitForExit();
}
// Set Permission
ProcessStartInfo chmodPsi1 = new ProcessStartInfo("sudo", "chmod 644 " + certPath + "" + keyFile);
ProcessStartInfo chmodPsi2 = new ProcessStartInfo("sudo", "chmod 644 " + certPath + "" + caFile);
ProcessStartInfo chmodPsi3 = new ProcessStartInfo("sudo", "chmod 644 " + certPath + "" + certFile);
chmodPsi1.UseShellExecute = false;
chmodPsi1.RedirectStandardOutput = true;
using (Process p = Process.Start(chmodPsi1))
{
p.WaitForExit();
}
chmodPsi2.UseShellExecute = false;
chmodPsi2.RedirectStandardOutput = true;
using (Process p = Process.Start(chmodPsi2))
{
p.WaitForExit();
}
chmodPsi3.UseShellExecute = false;
chmodPsi3.RedirectStandardOutput = true;
using (Process p = Process.Start(chmodPsi3))
{
p.WaitForExit();
}
}
return new X509Certificate2(certPath + "" + pfxFile, pfxPassword);
}
I have also tried converting each file into a X509Certificate:
//ca
X509Certificate2 ca = new X509Certificate2();
byte[] rawData_ca = ReadFile(@"Assets/DevAppCerts/AmazonRootCA1.pem");
ca.Import(rawData_ca);
//certificate.pem.crt
X509Certificate2 certPem = new X509Certificate2(Encoding.UTF8.GetBytes(certificatePem_str));
//private
X509Certificate2 privateKeyCert = new X509Certificate2(Encoding.UTF8.GetBytes(privateKey_str));
But when I do this I get an exception on the private key that says, "Unable to decode certificate."
If I add the password as the second parameter (X509Certificate2 privateKeyCert = new X509Certificate2(Encoding.UTF8.GetBytes(privateKey_str), "");) I get an exception that says, "Input data cannot be coded as a valid certificate. ---> System.ArgumentOutOfRangeException: Length cannot be less than zero."
The privateKey_str variable is a String formatted with a "-----BEGIN RSA PRIVATE KEY-----" header and a "-----END RSA PRIVATE KEY-----" footer. If I try removing the header and footer first I get an exception that says, "Input data cannot be coded as a valid certificate."
At the end of the day I want to have either a List<X509Certificate> with either a element (from the .pfx) or multiple X509Certificates that I can send the request with these options:
_mqttCerts = new List<X509Certificate>
{
//1 pfx or multiple X509Certificate
};
_mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer(brokerHostname, brokerPort)
.WithKeepAlivePeriod(new TimeSpan(0, 0, 0, 300))
.WithTls(new MqttClientOptionsBuilderTlsParameters
{
Certificates = _mqttCerts,
SslProtocol = System.Security.Authentication.SslProtocols.Tls12,
UseTls = true,
AllowUntrustedCertificates = true,
CertificateValidationHandler = rootCertificateTrust.VerifyServerCertificate
})
.WithClientId(_mqttClientId)
.Build();
Can anyone help me determine what I need to be doing differently?