Taking the code from this answer, saving the parentCert
and the cert
to .crt files, and trying to verify the certificate with OpenSSL as follows:
openssl verify -CAfile parentCert.crt cert.crt
Fails with this error:
Error loading file parentCert.crt
98580000:error:05800088:x509 certificate routines:X509_load_cert_crl_file_ex:no certificate or crl found:crypto\x509\by_file.c:251:
So the question is, how to create a ca.crt and a cert.crt (signed with that ca.crt) in .NET that OpenSSL can verify?
Here the full code for the test I did:
using (RSA parent = RSA.Create(4096))
using (RSA rsa = RSA.Create(2048))
{
CertificateRequest parentReq = new CertificateRequest(
"CN=Experimental Issuing Authority",
parent,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
parentReq.CertificateExtensions.Add(
new X509BasicConstraintsExtension(true, false, 0, true));
parentReq.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(parentReq.PublicKey, false));
using (X509Certificate2 parentCert = parentReq.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-45),
DateTimeOffset.UtcNow.AddDays(365)))
{
CertificateRequest req = new CertificateRequest(
"CN=Valid-Looking Timestamp Authority",
rsa,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
req.CertificateExtensions.Add(
new X509BasicConstraintsExtension(false, false, 0, false));
req.CertificateExtensions.Add(
new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
false));
req.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.8")
},
true));
req.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(req.PublicKey, false));
using (X509Certificate2 cert = req.Create(
parentCert,
DateTimeOffset.UtcNow.AddDays(-1),
DateTimeOffset.UtcNow.AddDays(90),
new byte[] { 1, 2, 3, 4 }))
{
// Do something with these certs, like export them to PFX,
// or add them to an X509Store, or whatever.
string path = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..\\..\\..\\"));
File.WriteAllBytes(Path.Combine(path, "parentCert.crt"), parentCert.Export(X509ContentType.Cert));
File.WriteAllBytes(Path.Combine(path, "cert.crt"), cert.Export(X509ContentType.Cert));
}
}
}
CodePudding user response:
The problem is you've created your files as DER, but that OpenSSL command only reads PEM.
You can either convert them with something like openssl x509 -in parentCert.cer -inform der -out parentCert.pem
, or just change your export code to something like
File.WriteAllText(
Path.Combine(path, "parentCert.crt"),
new string(PemEncoding.Write("CERTIFICATE", parentCert.RawData)));
File.WriteAllText(
Path.Combine(path, "cert.crt"),
new string(PemEncoding.Write("CERTIFICATE", cert.RawData)));
Or, in .NET 7 it's a little cleaner:
File.WriteAllText(
Path.Combine(path, "parentCert.crt"),
PemEncoding.WriteString("CERTIFICATE", parentCert.RawData));
File.WriteAllText(
Path.Combine(path, "cert.crt"),
PemEncoding.WriteString("CERTIFICATE", cert.RawData));