Записать сертификат в DER

Я пытаюсь записать сертификат X509 в формат DER в памяти. Запись в файл работает отлично.

Мне нужен сертификат в формате PEM без заголовка, нижнего колонтитула или новой строки "-----BEGIN PRIVATE KEY-----". Я не могу понять, как это сделать напрямую, поэтому... Я вывожу в кодировку der и base64.

ЭТО РАБОТАЕТ.

int X509_to_DER_file(X509 *cert) {
  int res=0;

  out = BIO_new(BIO_s_file());
  if (NULL != out) {
    if(BIO_write_filename(out, "my.der") > 0) {
      res = i2d_X509_bio(out, cert);
    }
    BIO_free_all(out);
  }
 return (tres);
}

ЭТОГО НЕТ. Он возвращает и вычисляет правильное количество байтов и, кажется, правильно записывает в память, но результирующая строка неверна (первые 15 или около того позиций верны).

char *X509_to_DER_mem(X509 *cert) {
  char *der = NULL;
  bio = BIO_new(BIO_s_mem());

  if (NULL != bio) {
    //load cert into bio
    if (0 == i2d_X509_bio(bio, cert)) {
      BIO_flush(bio);
      BIO_free(bio);
      return NULL;
    }

   der = (char *) malloc(bio->num_write + 1);
   if (NULL == der) {
       BIO_free(bio);
       return NULL;
   }

   memset(der, 0, bio->num_write + 1);
   BIO_read(bio, der, bio->num_write);
   // Appears to work put "der" is incomplete. 
   BIO_free(bio);
 }

 return der;
}

person PaulE    schedule 06.09.2018    source источник
comment
Проверьте возвращаемое значение BIO_read   -  person Eugene Sh.    schedule 06.09.2018
comment
Кстати, я не думаю, что вы должны использовать внутренние поля BIO напрямую ... это должен быть непрозрачный тип.   -  person Eugene Sh.    schedule 06.09.2018
comment
Является ли bio каким-то глобальным?   -  person tadman    schedule 06.09.2018


Ответы (1)


Он возвращает и вычисляет правильное количество байтов и, кажется, правильно записывает в память, но результирующая строка неверна.

Результатом i2d_X509_bio() является не строка (заканчивающаяся нулем), а набор байтов. Если вы попытаетесь записать его в файл в виде строки, это может показаться неполным, потому что вы можете встретить 0-байт в месте, прежде чем дойдете до конца. Таким образом, в дополнение к результату char * ваша функция X509_to_DER_mem() должна будет вернуть количество байтов, составляющих результат.

Что касается памяти BIO, другим способом получения ее данных является BIO_get_mem_data() функция. Что-то вроде этого:

char *ptr = NULL;
long len = BIO_get_mem_data(bio, &ptr);
der = malloc(len);
memcpy(der, ptr, len);

Наконец, ваш фактический вопрос:

Мне нужен сертификат в формате PEM без заголовка, нижнего колонтитула или новой строки "-----BEGIN PRIVATE KEY-----".

Запись сертификата в формате DER, похоже, не дает вам того, что вам нужно. Этот ответ на другой вопрос SO объясняет, как вы можете использовать функцию PEM_read_bio() в сочетании с EVP_EncodeBlock() для этой цели.

person Reinier Torenbeek    schedule 11.09.2018
comment
Спасибо за ответ. . Щедрая, познавательная и полезная. - person PaulE; 12.09.2018
comment
С удовольствием и добро пожаловать в StackOverflow. Если этот ответ был полезен и полностью решил вашу проблему, рассмотрите возможность его принятия, как описано в Что мне делать, когда кто-то ответит на мой вопрос?< /а> - person Reinier Torenbeek; 12.09.2018