【发布时间】:2018-12-28 13:05:29
【问题描述】:
我有工作命令行:
openssl cms -inform DER -cmsout -in sod.pkcs7 -verify -CAfile cert.pem
但我正在努力使这项工作在 C(在 iOS 下)中工作。
我找到了使用 PKCS7_verify 但带有 SMIME 信息的示例。所以我想我应该使用CMS_verify 但不太确定...
我的测试:
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h> /* open() */
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/pkcs7.h>
#include <openssl/safestack.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h> /* X509_PURPOSE_ANY */
#include <openssl/x509_vfy.h>
#include <openssl/cms.h>
#include <openssl/pem.h>
int testssl(const char* cert_path, const char* sod_path)
{
X509_STORE *trusted_store;
X509_STORE_CTX *ctx;
STACK_OF(X509) *cert_chain;
X509 *root, *intermediate, *signing;
BIO *in;
int purpose, ret;
X509_VERIFY_PARAM *verify_params;
PKCS7 *p7;
FILE *fp;
int fd;
SSL_library_init();
SSL_load_error_strings();
fd = open(sod_path, O_RDONLY);
in = BIO_new_fd(fd, BIO_NOCLOSE);
p7 = SMIME_read_PKCS7(in, NULL);
cert_chain = sk_X509_new_null();
fp = fopen(cert_path, "r");
root = PEM_read_X509(fp, NULL, NULL, NULL);
sk_X509_push(cert_chain, root);
// <C> not sure what this is good for...
// fp = fopen("intermediate.pem", "r");
fp = fopen(cert_path, "r");
intermediate = PEM_read_X509(fp, NULL, NULL, NULL);
sk_X509_push(cert_chain, intermediate);
trusted_store = X509_STORE_new();
X509_STORE_add_cert(trusted_store, root);
// fp = fopen("signing-ext-no-smimesign.pem", "r");
// signing = PEM_read_X509(fp, NULL, NULL, NULL);
BIO *cont = NULL;
CMS_ContentInfo *cms = NULL;
// cms = d2i_CMS_bio(in, NULL);
// cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
cms = SMIME_read_CMS(in, &cont);
// <C> all of above return NULL thus CMS_verify() fails
// 1st attempt
//
ret = CMS_verify(cms, cert_chain,trusted_store, NULL, NULL, 0);
printf("CMS_verify: %s\n", ret ? "OK" : "failure");
// 2nd attempt
//
ret = PKCS7_verify(p7, cert_chain, trusted_store, NULL, NULL, 0);
printf("Verification without specifying params: %s\n", ret ? "OK" : "failure");
/* Now set a suitable OpenSSL's "purpose", or disable its checking.
* Note: since OpenSSL 1.1.0, we'd not need `ctx`, but could just use:
* verify_params = X509_STORE_get0_param(trusted_store); */
ctx = X509_STORE_CTX_new();
X509_STORE_CTX_init(ctx, trusted_store, signing, cert_chain);
verify_params = X509_STORE_CTX_get0_param(ctx);
purpose = X509_PURPOSE_get_by_sname("crlsign"); /* Or: purpose = X509_PURPOSE_ANY */
X509_VERIFY_PARAM_set_purpose(verify_params, purpose);
X509_STORE_set1_param(trusted_store, verify_params);
// 3rd attempt
//
ret = PKCS7_verify(p7, cert_chain, trusted_store, NULL, NULL, 0);
printf("Verification with 'crlsign' purpose: %s\n", ret ? "OK" : "failure");
return 0;
}
【问题讨论】:
-
你可以在github.com/openssl/openssl/blob/master/apps/cms.c看到
openssl cms命令的作用 -
这实际上是我开始用来修改我的测试的。这就是我尝试设置 cms 变量的原因。不幸的是,所有 3 个案例都返回 NULL (d2i_CMS_bio/PEM_read_bio_CMS/SMIME_read_CMS)。我没有找到为 DER 格式创建 cms 的方法。有什么线索吗?
标签: ios c openssl cryptography pkcs#7