0

I need to convert a bunch of certificate revocation list in .crl extension,they are in DER format (Binary), and I need to convert them into PEM format (Base64 string representation of the binary content of each .crl file).

As per instructions in Convert .der to .pem using OpenSSL-Net, I have created the following code trying to convert a single .crl file from its DER format to PEM format:

    private static void generateCrl()
    {
        byte [] certbyte = File.ReadAllBytes("D:\\certsunzip\\DODIDCA_44.crl");
        Console.WriteLine("First byte: {0}", certbyte[0]);
        X509Certificate2 cert = new X509Certificate2(certbyte);
        string pem = "-----BEGIN X509 CRL-----\r\n" + Convert.ToBase64String(cert.RawData, Base64FormattingOptions.InsertLineBreaks) + "-----END X509 CRL-----";
        using (StreamWriter outputFile = new StreamWriter(@"D:\certsunzip\test.crl"))
        {
            foreach (char chr in pem)
            outputFile.WriteLine(chr);
        }
    }

However, when I run the code, the X509Certificate2 constructor is throwing me an CryptographicException saying "Cannot find the requested object". I would like to know is there another way I can do this conversion, maybe the X509Certificate2 constructor does not like the crl files?

Community
  • 1
  • 1
Harvey Lin
  • 724
  • 11
  • 25

1 Answers1

3

Remove 3rd line, because it doesn't make sense (because X509Certificate2 class doesn't support CRLs) and use 'certbyte' variable on a 4th line:

private static void generateCrl()
{
    byte [] certbyte = File.ReadAllBytes("D:\\certsunzip\\DODIDCA_44.crl");
    Console.WriteLine("First byte: {0}", certbyte[0]);
    string pem = "-----BEGIN X509 CRL-----\r\n" + Convert.ToBase64String(certbyte, Base64FormattingOptions.InsertLineBreaks) + "-----END X509 CRL-----";
    using (StreamWriter outputFile = new StreamWriter(@"D:\certsunzip\test.crl"))
    {
        outputFile.Write(pem);
    }
}

This will work.

Crypt32
  • 12,850
  • 2
  • 41
  • 70
  • This will give every character on a new line. Skip `using (StreamWriter outputFile....` and just use `File.WriteAllText(@"D:\certsunzip\test.crl", pem);` – pepo Oct 25 '16 at 08:34
  • 1
    Also `Base64FormattingOptions.InsertLineBreaks` wil add newline after every 76 character. Call me old school but I am used to see 64 characters per line in PEM encoded files. But I checked the output with openssl.exe and it parsed it correctly so I guess it's fine. – pepo Oct 25 '16 at 08:37
  • Line breaks are really irrelevant. So, you can even put each character on its own line and proper parser must correctly handle this. – Crypt32 Oct 25 '16 at 08:57
  • Well, it would possibly be true but the newlines are even after each character in headers :) – pepo Oct 25 '16 at 09:17
  • Just checked with openssl.exe with newlines after each character even in headers: `unable to load CRL 783032:error:0906D06C:PEM routines:PEM_read_bio:no start line:.\crypto\pem\pem_lib.c:650:Expecting: X509 CRL` – pepo Oct 25 '16 at 09:18
  • Nope, headers are not allowed to contain newlines, because they are not part of Base64 content. – Crypt32 Oct 25 '16 at 09:19
  • I have tried your suggestion pepo, seems like its working better, except its having a line break every 76 byte char, I want it to have a line break on every 64 byte char like how openssl.exe would use to generate the .crl files in PEM format, do you know how can I set exactly where can I have the line breaks in PEM format? – Harvey Lin Oct 25 '16 at 18:04
  • There is no real difference between linebreaks after each 64 or 72 characters. It is just formatting question. They are not part of the message. I edited my response to make output file more accurate. – Crypt32 Oct 25 '16 at 18:06
  • How do I edit the line breaks then? I think I just found out that my newly generated .crl file need to have line breaks at 64 byte char, but it is having one at every 76 byte char. – Harvey Lin Oct 25 '16 at 18:10
  • @pepo, InsertLineBreaks breaking Base64 into 72 character lines caught me after encoding A LOT of certificates (not CRLs). I found the standard line length for X509 certs was 64 (documented in an RFC) and ALL the tools I used output 64 character lines. Even though no tools I tested had a problem when the input was 72 character lines, I still went back, had the API not line break then implemented line breaks into 64-character lines myself. – jimhark Apr 08 '21 at 01:04