python - 如何使用 OpenSSL C 库创建退化的 PKCS7 文件?

标签 python c swig pkcs#7 m2crypto

如何使用 OpenSSL C 库创建给定单个 X509 证书的退化 PKCS#7 文件?

详细信息:

我通过添加一个名为 pkcs7_create_deg 的新函数来扩展 M2Crypto 中的 _pkcs7.i SWIG 接口(interface)文件。

当我在 SWIG 接口(interface)文件中使用以下 C 代码时,出现段错误。 为什么?

/* _pkcs7.i */
//
// Following 2 lines are part of the SWIG interface definition. Uncommented in _pkcs7.i file.
// %threadallow pkcs7_create_deg;
// %inline %{
//

PKCS7 *pkcs7_create_deg(X509 *x509) {
    PKCS7 *p7 = NULL;
    PKCS7_SIGNED *p7s = NULL;
    STACK_OF(X509_CRL) *crl_stack = NULL;
    STACK_OF(X509) *cert_stack = NULL;

    int ret = 1;

    if ((p7=PKCS7_new()) == NULL) goto end;
    if ((p7s=PKCS7_SIGNED_new()) == NULL) goto end;  
    p7->type=OBJ_nid2obj(NID_pkcs7_signed);
    p7->d.sign=p7s;
    p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data);

    if (!ASN1_INTEGER_set(p7s->version,1)) goto end;
    if ((crl_stack=sk_X509_CRL_new_null()) == NULL) goto end;
    p7s->crl=crl_stack;
    if ((cert_stack=sk_X509_new_null()) == NULL) goto end;
    p7s->cert=cert_stack;

    sk_X509_push(cert_stack, x509);
    // Shouldn't this mean take cert struct pointed to by x509
    // and push it on to cert_stack?  
    // I think this is WHY I am getting the segfault

end:
    if (p7 != NULL) PKCS7_free(p7);

    return (p7);    /* need to return a PKCS7* */

}

// Next line part of SWIG interface definition
// %}
# deg.py
#
from M2Crypto import *

cert = X509.load_cert('ra.crt')
print (cert)

p7_ptr = m2.pkcs7_create_deg(cert._ptr())
# Here I pass the X509 pointer to my cert object
# to the SWIG interface function I created above
# that is supposed to return a pointer to a PKCS#7 object

print (p7_ptr)
p7 = SMIME.PKCS7(p7_ptr)
print (p7)

bio = BIO.MemoryBuffer()
print (bio)

p7.write_der(bio)
# This is WHEN I get the segfault

f = open('deg.p7s', 'w')
f.write(bio.read())
f.close()
(venv)x-wing-air13:.test hansooloo$ python deg.py
<M2Crypto.X509.X509 instance at 0x106275710>
<Swig Object of type 'PKCS7 *' at 0x10625ea80>
<M2Crypto.SMIME.PKCS7 instance at 0x1062577e8>
<M2Crypto.BIO.MemoryBuffer instance at 0x1062757e8>
Segmentation fault: 11

最佳答案

最终 fork 了 M2Crypto 以添加一个新函数,该函数将创建一个退化的 PKCS7 对象。 https://github.com/HanSooloo/M2Crypto-martinpaljak

涉及的步骤如下:

  1. 将 M2Crypto 从 Martin Paljak 的存储库 fork 到新的存储库。
  2. 修改_pkcs7.i SWIG接口(interface)文件以添加以下功能。

_pkcs7.i 修改

// Adding X.509 related header files to be able to use their data types.
#include <openssl/x509.h>
#include <openssl/x509v3.h>

// Adding PKCS7_SIGNED data type to help create the degenerate data structure.
%apply Pointer NONNULL { PKCS7_SIGNED * };

// Additional interface definitions for degenerate PKCS#7 object creation.
// Inspired by the crl2p7.c file from OpenSSL.  Will need to clean up a bit for function returns.
%threadallow pkcs7_create_degenerate;
%inline %{
int pkcs7_create_degenerate(STACK_OF(X509) *cert_stack, BIO *bio) {
    int ret=1;
    PKCS7 *p7=NULL;
    PKCS7_SIGNED *p7s=NULL;
    X509_CRL *crl=NULL;
    STACK_OF(X509_CRL) *crl_stack=NULL;

    if ((p7=PKCS7_new()) == NULL) goto end;
    if ((p7s=PKCS7_SIGNED_new()) == NULL) goto end;  

    p7->type=OBJ_nid2obj(NID_pkcs7_signed);
    p7->d.sign=p7s;
    p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data);

    if (!ASN1_INTEGER_set(p7s->version,1)) goto end;
    if ((crl_stack=sk_X509_CRL_new_null()) == NULL) goto end;
    p7s->crl=crl_stack;
    p7s->cert=cert_stack;

    ret=i2d_PKCS7_bio(bio, p7);

end:
    p7s->cert=NULL;

    if (p7 != NULL) {
//      printf("about to free p7: ");
        PKCS7_free(p7);
//      printf("freed.\n");
    }

    return ret;

}
%}

功能详情

该函数将 X509 堆栈指针和 BIO 指针作为输入,并返回一个表示成功的整数。

X509 堆栈指针需要指向一个堆栈,其中包含希望放入退化 PKCS#7 对象中的证书。

BIO 指针需要指向一个空的 BIO 结构,稍后将用 PKCS#7 对象填充该结构。

使用上述函数的Python代码示例:

from M2Crypto import X509, BIO, m2

sk = X509.X509_Stack()

cert = X509.load_cert('ra.crt')
num = sk.push(cert)
cert = X509.load_cert('ca.crt')
num = sk.push(cert)

# At this point, the X509 stack contains 2 certificates.
print('num: %d' %num)

# Create the BIO that will hold the PKCS#7 object.    
bio = BIO.MemoryBuffer()

# Request to create the degenerate PCKS#7 object.
ret = m2.pkcs7_create_degenerate(sk._ptr(), bio._ptr())

# Open the file for writing.
f = open('deg.p7s', 'w')

# Read from BIO and write to file.
b = bio.read()
f.write(b)

# Close the file.
f.close()

关于python - 如何使用 OpenSSL C 库创建退化的 PKCS7 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23728234/

相关文章:

python - SWIG 'cstring.i' Python 返回字节类型而不是字符串类型

python - Webots 机器人在尝试与外部 Kinect 一起使用时不说话

python - 检查列表是否在列表列表中

python - 如何将一个系列分配给另一个系列或在索引不相交的情况下合并并保留其中一个系列中感兴趣的索引的值

C指针问题

c - 程序收到信号SIGSEGV、段错误、链表程序

java - 如何使用 Swig 将数组从 Java 传递到 C++?

python - 等同列表如何工作? -可变的基本概念

c - 仅公开 header 中一小部分函数

python - SWIG、C++ 和 Python : C++ temporary objects deleted too soon