【问题标题】:Building an ASN1 set using the openssl C API使用 openssl C API 构建 ASN1 集
【发布时间】:2018-12-17 05:37:35
【问题描述】:

我正在尝试使用 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
}

我从那里去哪里才能构建一组这些?

【问题讨论】:

  • 你见过这个吗? stackoverflow.com/a/12108234
  • 您知道它包含我需要的信息吗?我只是花了两个晚上去浏览其他没有解释的文档,所以如果你有答案,最好在这里提供它,而不是让我去追逐潜在的野鹅:)
  • 不,抱歉,我还没有打开这些文件并专门为您检查它们。我指出 POD 文件是因为它们似乎是“官方”文档,所以如果你还没有阅读它们,你需要这样做。

标签: c openssl asn.1


【解决方案1】:

OpenSSL 源代码是您最好的文档...

作为您尝试构建的构造示例,请查看the PKCS7_SIGNED ASN1 definition in 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,它本身就是a sequence defined in 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 字段表明,要捕获集合构造,您需要使用旨在处理集合的the STACK API。在您的情况下,这将是 STACK_OF(StringSequence)

【讨论】:

  • 非常完整的答案。谢谢!
  • 对此进行快速跟进,上面的示例仍然创建了一个包含一组的序列。我可以使用sk_StringSequence_new_null() 之类的东西来创建一个独立的集合,但我找不到任何方法将其编码为 ASN1。对于通过DEFINE_STACK_OF() 定义的对象,似乎没有等效的DECLARE_ASN1_FUNCTIONS()IMPLEMENT_ASN1_FUNCTIONS()。现在我决定将父序列转换为 ASN1,然后只从其中获取集合数据。这一切都是使用 ASN1 方法完成的,所以它应该是相当安全的,如果丑陋的话。
猜你喜欢
  • 2016-11-20
  • 2016-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-04
  • 1970-01-01
  • 2018-07-23
相关资源
最近更新 更多