Создание набора ASN1 с использованием openssl C API - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь создать набор последовательностей, используя openssl C API.Как было отмечено в разных местах, документация по этому вопросу ОЧЕНЬ редка, и примеры кода, по-видимому, отсутствуют.

Я нашел в Интернете различные предложения, но ни одно из них не показалось корректным.

Я продвинулся так далеко, чтобы создать последовательности:

#include <openssl/asn1t.h>

countdef struct StringStructure {
    ASN1_INTEGER *count;
    ASN1_INTEGER *asnVersion;
    ASN1_OCTET_STRING *value;
} StringSequence;

DECLARE_ASN1_FUNCTIONS(StringSequence)

ASN1_SEQUENCE(StringSequence) = {
    ASN1_SIMPLE(StringSequence, count, ASN1_INTEGER),
    ASN1_SIMPLE(StringSequence, asnVersion, ASN1_INTEGER),
    ASN1_SIMPLE(StringSequence, value, ASN1_OCTET_STRING),
} ASN1_SEQUENCE_END(StringSequence)

IMPLEMENT_ASN1_FUNCTIONS(StringSequence)

auto aSeq = StringSequence_new();
aSeq->count = ASN1_INTEGER_new();
aSeq->asnVersion = ASN1_INTEGER_new();
aSeq->value = ASN1_OCTET_STRING_new();
if (!ASN1_INTEGER_set(aSeq->count, 10) ||
    !ASN1_INTEGER_set(aSeq->asnVersion, 1) ||
    !ASN1_STRING_set(aSeq->value, "Test", -1)) {
    // -- Error
}

auto anotherSeq = StringSequence_new();
anotherSeq->count = ASN1_INTEGER_new();
anotherSeq->asnVersion = ASN1_INTEGER_new();
anotherSeq->value = ASN1_OCTET_STRING_new();
if (!ASN1_INTEGER_set(anotherSeq->count, 32) ||
    !ASN1_INTEGER_set(anotherSeq->asnVersion, 1) ||
    !ASN1_STRING_set(anotherSeq->value, "Something Else", -1)) {
    // -- Error
}

Куда мне обратиться, чтобы создать набор из них?

1 Ответ

0 голосов
/ 17 декабря 2018

Исходный код OpenSSL - ваша лучшая документация ...

В качестве примера конструкции, подобной той, которую вы пытаетесь построить, посмотрите определение PKCS7_SIGNED ASN1 в crypto/pkcs7/pk7_asn1.c:

ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = {
        ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER),
        ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR),
        ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7),
        ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0),
        ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1),
        ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO)
} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGNED)

Его второй член, md_algs, представляет собой набор X509_ALGOR, который сам по себе является последовательностью, определенной в crypto/asn1/x_algor.c:

ASN1_SEQUENCE(X509_ALGOR) = {
        ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
        ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
} ASN1_SEQUENCE_END(X509_ALGOR)

Так что это поле md_algs представляет собой набор последовательностей, как вы и просили.Эквивалентные определения C-структуры можно найти в include/openssl/pkcs7.h:

typedef struct pkcs7_signed_st {
    ASN1_INTEGER *version;      /* version 1 */
    STACK_OF(X509_ALGOR) *md_algs; /* md used */
    STACK_OF(X509) *cert;       /* [ 0 ] */
    STACK_OF(X509_CRL) *crl;    /* [ 1 ] */
    STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
    struct pkcs7_st *contents;
} PKCS7_SIGNED;

Поле md_algs показывает, что для захвата конструкции множества вам необходимо использовать STACK API , который предназначен для обработки коллекций.В вашем случае это будет STACK_OF(StringSequence).

...