3

I have a certificate in PEM format that I want to convert it to DER format using OpenSLL functions in C++.

How can I do it?

Thanks.

itayb
  • 139
  • 3
  • 10
  • openssl x509 -outform der -in certificate.pem -out certificate.der https://www.sslshopper.com/ssl-converter.html – user1438832 Feb 13 '17 at 08:26
  • how do i do it in c++ using openssl functions? – itayb Feb 13 '17 at 08:43
  • Also see [Use OpenSSL RSA key with .Net](http://stackoverflow.com/q/30475758/608639). It shows you some C++ tricks with `unique_ptr` to manage resources. – jww Feb 13 '17 at 13:48

3 Answers3

2

You can do it like -

#include <stdio.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/err.h>

void convert(char* cert_filestr,char* certificateFile)
{
    X509* x509 = NULL;
    FILE* fd = NULL,*fl = NULL;

    fl = fopen(cert_filestr,"rb");
    if(fl) 
    {
        fd = fopen(certificateFile,"w+");
        if(fd) 
        {
            x509 = PEM_read_X509(fl,&x509,NULL,NULL);
            if(x509) 
            {
                 i2d_X509_fp(fd, x509);
            }
            else 
            {
                printf("failed to parse to X509 from fl");
            }
            fclose(fd);
        }
        else
        {
             printf("can't open fd");
        }
        fclose(fl);
    }
    else 
    {
         printf("can't open f");
    }
}


int main()
{
    convert("abc.pem","axc.der");
    return 0;
}
user1438832
  • 493
  • 3
  • 10
  • thanks, just one more question, if i get it as string and not as file, how can i do it? thanks you very much – itayb Feb 13 '17 at 09:59
2

You can do it without using OpenSSL functions. Try this-

int CertConv_pem2der(const uint8_t *pem, uint32_t plen, uint8_t **der,
                 uint32_t *dlen)
{
  int value = 0;
  int i;
  int j;
  int padZero = 0;
  uint8_t *derPtr;
  uint32_t derLen;

  if ((pem == NULL) || (der == NULL))
  {
    return (-1);
  }

  for (i = plen; pem[i - 1] == '='; i--)
  {
    padZero++;
  }

  /* Base64 decode: 4 characters to 3 bytes */
  derLen = (plen / 4) * 3;
  derPtr = (uint8_t *) malloc(derLen);
  if (!derPtr)
  {
    return (-1);
  }

  for (i = 0, j = 0; (i + 3) < plen && (j + 2) < derLen; i += 4, j += 3)
  {
    value = (base64Decode(pem[i]) << 18) + (base64Decode(pem[i + 1]) << 12)
            + (base64Decode(pem[i + 2]) << 6) + base64Decode(pem[i + 3]);

    derPtr[j] = (value >> 16) & 0xFF;
    derPtr[j + 1] = (value >> 8) & 0xFF;
    derPtr[j + 2] = value & 0xFF;
  }

  /* Actual length of buffer filled */
  *dlen = derLen - padZero;
  *der = derPtr;

  return (0);
}


static uint8_t base64Decode(uint8_t ch)
{
  uint8_t ret = 0;
  if (ch >= 'A' && ch <= 'Z')
  {
    ret = ch - 'A';
  }
  else if (ch >= 'a' && ch <= 'z')
  {
    ret = ch - 'a' + 26;
  }
  else if (ch >= '0' && ch <= '9')
  {
    ret = ch - '0' + 52;
  }
  else if (ch == '+')
  {
    ret = 62;
  }
  else if (ch == '/')
  {
    ret = 63;
  }

  return (ret);
}
ABD
  • 180
  • 11
1

Try this -

void convert(const unsigned char * pem_string_cert,char* certificateFile)
{
    X509* x509 = NULL;
    FILE* fd = NULL;

    BIO *bio;

    bio = BIO_new(BIO_s_mem());
    BIO_puts(bio, pem_string_cert);
    x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);

    fd = fopen(certificateFile,"w+");
    if(fd) 
    {
            i2d_X509_fp(fd, x509);
    }
    else 
    {
         printf("can't open fd");
    }
    fclose(fd);
}
user1438832
  • 493
  • 3
  • 10