我尝试使用OpenSSL创建CMS签名。虽然我能够创建常规签名,但我的应用程序有一些我无法满足的要求。
我的应用程序要求我将带有OID 1.2.840.113635.100.9.1的signedAttr添加到签名中,但我无法这样做。我也找不到任何可以让我做到这一点的API。
我上传了两条符合https://transfer.sh/96w2l/sigARM64和https://transfer.sh/kbmBO/sigARM规范的CMS消息。
如果有人能指出我正确的方向,我将不胜感激。
答案 0 :(得分:0)
诀窍是将attr添加到SignerInfo,然后使用它来签署CMS_ContentInfo。
#include <openssl/cms.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <string.h>
char *lol = "roflcopter";
int main(int argc, char **argv) {
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
int flags = CMS_BINARY | CMS_PARTIAL | CMS_NOSMIMECAP | CMS_DETACHED;
int ret = -1;
BIO *bio_cert_and_key = BIO_new_file("/home/umang/.isign/pair.pem", "r");
if (!bio_cert_and_key)
goto err;
X509 *scert = PEM_read_bio_X509(bio_cert_and_key, NULL, 0, NULL);
BIO_reset(bio_cert_and_key);
EVP_PKEY *skey = PEM_read_bio_PrivateKey(bio_cert_and_key, NULL, 0, NULL);
if (!scert || !skey)
goto err;
BIO *in = BIO_new_file("/tmp/test2", "r");
CMS_ContentInfo *cms = CMS_sign(NULL, NULL, NULL, in, flags);
if (!cms)
goto err;
CMS_SignerInfo *si = CMS_add1_signer(cms, scert, skey, NULL, flags);
ASN1_OBJECT *obj = OBJ_txt2obj("1.2.840.113635.100.9.1", 1);
if (!si || !obj)
goto err;
if (!CMS_signed_add1_attr_by_OBJ(si, obj, 0x4, lol, strlen(lol)) || !CMS_SignerInfo_sign(si))
goto err;
int len = i2d_CMS_ContentInfo(cms, NULL);
unsigned char *buf = malloc(len);
unsigned char *buf_2 = buf;
i2d_CMS_ContentInfo(cms, &buf);
BIO *out = BIO_new_file("/tmp/test", "wb");
if (!out)
goto err;
BIO_write(out, buf_2, len);
ret = 0;
err:
BIO_free(bio_cert_and_key);
BIO_free(in);
BIO_free(out);
CMS_ContentInfo_free(cms);
ASN1_OBJECT_free(obj);
EVP_PKEY_free(skey);
X509_free(scert);
free(buf_2);
ERR_print_errors_fp(stderr);
return ret;
}