I'm trying to load an X509Certificate2 from PEM files in a .NET standard library.
I created a self-signed certificate using openssl like so:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj /CN=localhost -days 365
I loaded the resulting PEM files into embedded string resources within the project and am trying to load them with the following code:
private X509Certificate2 GetCertificate()
{
try
{
byte[] pubPem = System.Text.Encoding.UTF8.GetBytes(Properties.Resources.DefaultPublicPem.Trim());
var cert = new X509Certificate2(pubPem);
var rsa = GetRSAFromPem(Properties.Resources.DefaultPrivatePem.Trim());
cert.PrivateKey = rsa;
return cert;
}
catch (Exception ex)
{
// ignore errors
return null;
}
}
public static RSA GetRSAFromPem(String pemstr)
{
RSA rsaKey = RSA.Create();
Func<RSA, RsaKeyParameters, RSA> MakePublicRCSP = (RSA rcsp, RsaKeyParameters rkp) =>
{
RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rkp);
rcsp.ImportParameters(rsaParameters);
return rsaKey;
};
Func<RSA, RsaPrivateCrtKeyParameters, RSA> MakePrivateRCSP = (RSA rcsp, RsaPrivateCrtKeyParameters rkp) =>
{
RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rkp);
rcsp.ImportParameters(rsaParameters);
return rsaKey;
};
PemReader reader = new PemReader(new StringReader(pemstr));
object kp = reader.ReadObject();
// If object has Private/Public property, we have a Private PEM
var hasPrivate = kp.GetType().GetProperty("Private") != null;
var isPrivate = kp is RsaPrivateCrtKeyParameters;
return isPrivate ? MakePrivateRCSP(rsaKey, (RsaPrivateCrtKeyParameters)kp) : hasPrivate ? MakePrivateRCSP(rsaKey, (RsaPrivateCrtKeyParameters)(((AsymmetricCipherKeyPair)kp).Private)) : MakePublicRCSP(rsaKey, (RsaKeyParameters)kp);
}
I tested it on Android and it works great.
On iOS I haven't tested yet, but on UWP it fails and I get a PlatformNotSupported Exception while trying to set the PrivateKey on the certificate.
So I'm wondering what's not supported, and whether I'm not doing it right.