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

时间:2014-05-19 00:34:00

标签: python c swig pkcs#7 m2crypto

如何使用OpenSSL C库提供单个X509证书来创建简并PKCS#7文件?

详细说明:

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

当我在SWIG接口文件中使用下面的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

1 个答案:

答案 0 :(得分:1)

结束分叉M2Crypto以添加一个新函数,该函数将创建一个退化的PKCS7对象。 https://github.com/HanSooloo/M2Crypto-martinpaljak

所涉及的步骤如下:

  1. 将来自Martin Paljak的回购的M2Crypto转换为新的回购。
  2. 修改_pkcs7.i SWIG接口文件以添加以下功能。
  3. _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()