Как получить сертификат X509 в кодировке PEM в виде строки C с помощью openssl?

#c #openssl #x509certificate #x509 #pem

#c #openssl #x509certificate #x509 #pem

Вопрос:

У меня есть структура openssl X509 с самозаверяющим сертификатом. Мне нужно получить строку C в формате PEM из этой структуры. Какие API-интерфейсы openssl мне нужно использовать для достижения этой цели?

Я попытался следовать примеру программы в https://www.codeblog.org/gonzui/markup/openssl-0.9.8a/demos/x509/mkcert.c . Эта программа показывает способ записи сертификата в формате PEM в файл. Я могу прочитать содержимое этого файла в строку C , если другого способа сделать это нет.

Ответ №1:

У меня есть структура openssl X509 с самозаверяющим сертификатом. Мне нужно получить строку C в формате PEM из этой структуры.

Следующее должно хорошо работать для вас. В нем показаны API, необходимые для этого (без кода для заполнения полей сертификата).

 #include <iostream>
#include <memory>
#include <string>
using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::unique_ptr;

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

using X509_ptr = std::unique_ptr<X509, decltype(amp;::X509_free)>;
using BIO_MEM_ptr = std::unique_ptr<BIO, decltype(amp;::BIO_free)>;

int main(int argc, char* argv[])
{
    int rc = 0;
    unsigned long err = 0;

    X509_ptr x509(X509_new(), ::X509_free);
    /* ... */

    BIO_MEM_ptr bio(BIO_new(BIO_s_mem()), ::BIO_free);

    rc = PEM_write_bio_X509(bio.get(), x509.get());
    err = ERR_get_error();

    if (rc != 1)
    {
        cerr << "PEM_write_bio_X509 failed, error " << err << ", ";
        cerr << std::hex << "0x" << err;
        exit(1);
    }

    BUF_MEM *mem = NULL;
    BIO_get_mem_ptr(bio.get(), amp;mem);
    err = ERR_get_error();

    if (!mem || !mem->data || !mem->length)
    {
        cerr << "BIO_get_mem_ptr failed, error " << err << ", ";
        cerr << std::hex << "0x" << err;
        exit(2);
    }

    string pem(mem->data, mem->length);
    cout << pem << endl;

    return 0;
}
  

Скомпилируйте со следующим:

 g   -g -O -std=c  11 x509.cpp -o x509.exe 
    -I/usr/local/ssl/include 
    /usr/local/ssl/lib/libcrypto.a -ldl
  

Типичный результат:

 $ ./x509.exe 
-----BEGIN CERTIFICATE-----
MCYwHAIBADADBgEAMAAwBB8AHwAwADAIMAMGAQADAQAwAwYBAAMBAA==
-----END CERTIFICATE-----
  

Комментарии:

1. небольшое замечание о вашем коде: x509 и bio должно быть проверено nullptr перед использованием

Ответ №2:

посмотрите на источник команды openssl x509 и посмотрите, как она выполняет операцию по чтению файла в кодировке DER и записывает файл PEM — ie:

 openssl x509 -in mycert.der -inform DER -out mycert.pem
  

Код утилит cli довольно прост для понимания

Комментарии:

1. Я просмотрел код x509.c, как вы предложили, и обнаружил, что они используют функцию PEM_write_bio_X509 для записи данных в формате PEM. Затем я считываю эти данные в массив символов с помощью BIO_read. Спасибо.