如何使用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
答案 0 :(得分:1)
结束分叉M2Crypto以添加一个新函数,该函数将创建一个退化的PKCS7对象。 https://github.com/HanSooloo/M2Crypto-martinpaljak
所涉及的步骤如下:
_pkcs7.i
SWIG接口文件以添加以下功能。// 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对象进行填充。
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()