我很想使用“p7”并将其写入一个简单的 std::string (或 char *,如果需要)。我编写的 milter 应用程序将拾取该字符串并执行更改主体(尚未编写,但这是我的想法)。
我不相信你可以把它放在char*
因为可能有一个嵌入的NULL
,这会截断结果。
Use a std::string
以及 (1)i2d_PKCS7_bio
对于 ASN.1/DER 或 (2)PEM_write_bio_PKCS7
对于质子交换膜。这个想法是你像往常一样使用该库,将输出写入MEM_BIO
然后使用获取生物的内容BUF_MEM
. The BUF_MEM
保存一个指向数据及其长度的指针。就像是...
using BIO_MEM_ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
using BIO_MEM_BUF_ptr = std::unique_ptr<BUF_MEM, decltype(&::BIO_free)>;
BIO_MEM_ptr bio(BIO_new(BIO_s_mem()), ::BIO_free);
int ret = i2d_PKCS7_bio(bio, p7);
ASSERT(ret == 1);
BIO_MEM_BUF_ptr buff;
BIO_get_mem_ptr(bio.get(), &buff.get());
const BUF_MEM& t = *buff.get();
std::string result((t.data ? t.data : ""), (t.data ? t.length : 0));
If你用PEM_write_bio_PKCS7
and a char*
,那么 PEM 编码将缺少终止符NULL
。请务必考虑到它,因为它不是 C 字符串。另请参阅生成随机 n 字节 Base64 字符串后的不可打印字符,其中讨论了如何在不进行编码的情况下写入 NULL。
由于 openssl 有超过 1600 个手册页,我不知道在哪里寻找信息......
查看子命令的源代码。它向您展示了库如何使用 API 进行操作。例如,当您使用openssl pkcs7
,它使用pkcs7
app.
$ cd <openssl src dir>
$ cd apps
$ ls *.c
app_rand.c dsaparam.c openssl.c rehash.c speed.c
apps.c ec.c opt.c req.c spkac.c
asn1pars.c ecparam.c passwd.c rsa.c srp.c
ca.c enc.c pkcs12.c rsautl.c ts.c
ciphers.c engine.c pkcs7.c s_cb.c verify.c
cms.c errstr.c pkcs8.c s_client.c version.c
crl.c gendsa.c pkey.c s_server.c vms_decc_init.c
crl2p7.c genpkey.c pkeyparam.c s_socket.c x509.c
dgst.c genrsa.c pkeyutl.c s_time.c
dhparam.c nseq.c prime.c sess_id.c
dsa.c ocsp.c rand.c smime.c
Using unique_ptr
使用 dtor 函数可确保自动清理对象,并有助于保持代码干净。每当 OpenSSL 与 C++ 交叉路径时我都会尝试使用它(请参阅如何使用openssl生成RSA私钥另一个例子)。
以下是我的一个使用 OpenSSL 的 C++ 项目中的一些内容:
using EC_KEY_ptr = std::unique_ptr<EC_KEY, decltype(&::EC_KEY_free)>;
using EC_GROUP_ptr = std::unique_ptr<EC_GROUP, decltype(&::EC_GROUP_free)>;
using EC_POINT_ptr = std::unique_ptr<EC_POINT, decltype(&::EC_POINT_free)>;
using DH_ptr = std::unique_ptr<DH, decltype(&::DH_free)>;
using RSA_ptr = std::unique_ptr<RSA, decltype(&::RSA_free)>;
using DSA_ptr = std::unique_ptr<DSA, decltype(&::DSA_free)>;
using EVP_PKEY_ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
using BN_ptr = std::unique_ptr<BIGNUM, decltype(&::BN_free)>;
using FILE_ptr = std::unique_ptr<FILE, decltype(&::fclose)>;
using BIO_MEM_ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
using BIO_FILE_ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
using EVP_MD_CTX_ptr = std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_destroy)>;
using X509_ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
using ASN1_INTEGER_ptr = std::unique_ptr<ASN1_INTEGER, decltype(&::ASN1_INTEGER_free)>;
using ASN1_TIME_ptr = std::unique_ptr<ASN1_TIME, decltype(&::ASN1_TIME_free)>;
using X509_EXTENSION_ptr = std::unique_ptr<X509_EXTENSION, decltype(&::X509_EXTENSION_free)>;
using X509_NAME_ptr = std::unique_ptr<X509_NAME, decltype(&::X509_NAME_free)>;
using X509_NAME_ENTRY_ptr = std::unique_ptr<X509_NAME_ENTRY, decltype(&::X509_NAME_ENTRY_free)>;
using X509_STORE_ptr = std::unique_ptr<X509_STORE, decltype(&::X509_STORE_free)>;
using X509_LOOKUP_ptr = std::unique_ptr<X509_LOOKUP, decltype(&::X509_LOOKUP_free)>;
using X509_STORE_CTX_ptr = std::unique_ptr<X509_STORE_CTX, decltype(&::X509_STORE_CTX_free)>;