将signedInfo添加到OpenSSL CMS签名

时间:2018-05-14 06:51:30

标签: openssl

我尝试使用OpenSSL创建CMS签名。虽然我能够创建常规签名,但我的应用程序有一些我无法满足的要求。

我的应用程序要求我将带有OID 1.2.840.113635.100.9.1的signedAttr添加到签名中,但我无法这样做。我也找不到任何可以让我做到这一点的API。

我上传了两条符合https://transfer.sh/96w2l/sigARM64https://transfer.sh/kbmBO/sigARM规范的CMS消息。

如果有人能指出我正确的方向,我将不胜感激。

1 个答案:

答案 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;
}