Подскажите пожалуйста как распечатать значения расширений в х.509 - PullRequest
3 голосов
/ 06 октября 2011
HTML语言: Codee#23000

Расширения пользователя x.509 были определены следующим образом:

    X509v3 extensions:
        X509v3 Basic Constraints: 
            CA:FALSE
        Netscape Comment: 
            OpenSSL Generated Certificate
        X509v3 Subject Key Identifier: 
            D8:F0:12:EA:0D:67:55:96:C9:8E:A4:36:9E:62:84:7F:6F:41:0C:DB
        X509v3 Authority Key Identifier: 
            keyid:C4:33:98:59:50:6B:CC:48:5A:4A:D7:5B:C0:A7:7C:37:DE:15:24:33

        SEwVersion: 
            ..0.2
        SEww: 
            ..0X5699

скажите, пожалуйста, как извлечь значения расширений и распечатать их на экране в режиме строки ascii, а именно, мы можем идентифицировать их как обычно:

* формат печати *

        X509v3 Basic Constraints: 
            CA:FALSE
        Netscape Comment: 
            OpenSSL Generated Certificate
        X509v3 Subject Key Identifier: 
            D8:F0:12:EA:0D:67:55:96:C9:8E:A4:36:9E:62:84:7F:6F:41:0C:DB
        X509v3 Authority Key Identifier: 
            keyid:C4:33:98:59:50:6B:CC:48:5A:4A:D7:5B:C0:A7:7C:37:DE:15:24:33
        SEVersion: 
            0.2  // no prefix like ".."
        SE: 
            0X5699  // no prefix like ".."

и еще одна проблема:

        SEwVersion: 
            ..0.2
        SEww: 
            0...version..0X5699

тогда как я могу получить и напечатать на экран, как это:

        SEwVersion: 
            0.2 //no prefix ".."
        SEww: 
            version 0X5699// no "..."and ".."

и мои коды следующие:

int Ext_count = X509_get_ext_count(cert);
for (int k=0; k <Ext_count; k++ ){
    X509_EXTENSION* ex = X509_get_ext(cert, k);
    if( ex == NULL )
        continue;
    OBJ_obj2txt((char *)buf, 100, ex->object, 0);
    printf("name = %s\n", buf);        
    if (k>=Ext_count-2)
          //I distinguish basic extensions and my added extensions like this , so it is not good methode, please tell me how to ...
    {
        ASN1_OCTET_STRING* octet_str = X509_EXTENSION_get_data(ex);
        const unsigned char* octet_str_data = octet_str->data;
        long xlen;
        int tag, xclass;
        int ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, octet_str->length);
        printf("value: %s\n", octet_str_data);
    }
    else
    {
        BIO *bio = BIO_new(BIO_s_mem());
        if(!X509V3_EXT_print(bio, ex, 0, 0)) // read the text of this    extention
            M_ASN1_OCTET_STRING_print(bio,ex->value);
        len = BIO_read(bio, buf, 200);// here buffer contain    the text, len the lenght of it.
        buf[len] = '\0'; // add the EOT sign, buffer    contain a readable text.
        BIO_free(bio);
        printf("value = %s\n", buf);
    }

Большое спасибо за вашу любезную помощь заранее.

Ответы [ 2 ]

4 голосов
/ 16 апреля 2012

Вот пример чтения и распечатки идентификатора ключа авторизации из некоторого сертификата:

FILE *arq = fopen("<path to your certificate in PEM format>","rw");
int next;
X509 *cert; 
cert = PEM_read_X509(arq,NULL,NULL, NULL);
X509_EXTENSION *ext;
next = X509_get_ext_count(cert);
for (int i=0;i<next;i++)
{
    ext = X509_get_ext(cert, i);
    int nid = OBJ_obj2nid(ext->object);
    if(nid == NID_authority_key_identifier)
    {
        AUTHORITY_KEYID *authKeyId = (AUTHORITY_KEYID *)X509V3_EXT_d2i(ext);
        //converting to hex
        std::string data;
        char *hex_data = new char[authKeyId->keyid->length*2 +1];

        int j = 0;
        for(int i = 0; i < authKeyId->keyid->length; i++)
        {
            sprintf(&hex_data[j], "%02X", authKeyId->keyid->data[i]);
            j+=2;
        }
        hex_data[j] = '\0';
        data = hex_data;
        delete[] hex_data;
        cout << "Authority Key Id: " << data << endl;

    }
}
0 голосов
/ 21 февраля 2019

Спасибо, Джовани, ваш ответ решает основную проблему, единственная проблема, с которой я столкнулся, это получение шестнадцатеричных данных. Управление и обработка длины в следующей части кода были критически важны и могут привести к лишним / пустым данным.

    char *hex_data = new char[authKeyId->keyid->length*2 +1];

    int j = 0;
    for(int i = 0; i < authKeyId->keyid->length; i++)
    {
        sprintf(&hex_data[j], "%02X", authKeyId->keyid->data[i]);
        j+=2;
    }
    hex_data[j] = '\0';

Это можно легко сделать с помощью API-интерфейса " hex_to_string ", который уже имеется в библиотеке. Ниже приведен пример использования этого API.

int loc = X509_get_ext_by_NID(cert, NID_subject_key_identifier,-1);
X509_EXTENSION *ext = X509_get_ext(cert, loc);
if (ext) {
    const unsigned char* octet_str_data = ext->value->data;
    long xlen;
    int tag, xclass;
    int ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, ext->value->length);
    char* skid = hex_to_string(octet_str_data, xlen);
    if(skid != nullptr)
    {   
        certificate_skid.assign(skid);
        free(skid);
    }   
}  

Надеюсь, это поможет будущим читателям.

...