Hi,
Just chiming in to confirm your idea of using CMS_encrypt() on a BIO, then
CMS_sign(). That's what I ended up doing (cf. code I posted on StackOverflow at
the time[1]). If someone else knows a better approach though, I'm interested
too. Hopefully the overhead from BIO/CMS juggling will not increase latency too
much...
I don't know anything about CMS_dataInit(). A quick look at 1.0.1j's sources
shows that it's only called in a couple of files in crypto/cms/ (notably at the
beginning of CMS_final()), so maybe it's not even supposed to be part of the
public API? The doc for CMS_encrypt() and CMS_sign() says that they "create and
return" a new CMS structure, so I have no idea what the purpose of
CMS_dataInit() is. Hopefully someone on this list will know.
Not a terribly useful answer I'm afraid :/ I hope someone else will contribute.
[1]
/* Make EnvelopedData structure */
BIO* in = BIO_new_file(in_path, "rb");
int flags = CMS_BINARY | CMS_USE_KEYID | CMS_PARTIAL | CMS_KEY_PARAM;
CMS_ContentInfo* edata = CMS_encrypt(NULL, NULL, cipher, flags);
CMS_RecipientInfo* r_info = CMS_add1_recipient_cert(edata, r_cert, flags);
EVP_PKEY_CTX* wrap_ctx = CMS_RecipientInfo_get0_pkey_ctx(r_info);
EVP_PKEY_CTX_set_rsa_padding(wrap_ctx, RSA_PKCS1_OAEP_PADDING);
EVP_PKEY_CTX_set_rsa_oaep_md(wrap_ctx, EVP_sha256());
EVP_PKEY_CTX_set_rsa_mgf1_md(wrap_ctx, EVP_sha256());
EVP_PKEY_CTX_set0_rsa_oaep_label(wrap_ctx, oaep_label, oaep_label_l);
/* NB: oaep_label must be heap-allocated, and will be freed by OSSL */
CMS_final(edata, in, NULL, flags);
BIO* tmp = BIO_new(BIO_s_mem());
i2d_CMS_bio(tmp, edata);
/* Make SignedData structure */
flags|= CMS_NOSMIMECAP | CMS_NOCERTS;
flags&= ~(CMS_KEY_PARAM);
CMS_ContentInfo* sdata = CMS_sign(NULL, NULL, NULL, NULL, flags);
ASN1_OBJECT* ectype_edata = OBJ_nid2obj(NID_pkcs7_enveloped);
CMS_set1_eContentType(sdata, ectype_edata);
CMS_SignerInfo* s_info =
CMS_add1_signer(sdata, s_cert, s_key, NULL, flags);
CMS_SignerInfo_sign(s_info);
CMS_final(sdata, tmp, NULL, flags);
BIO* out = BIO_new_file(out_path, "wb");
i2d_CMS_bio(out, sdata);
BIO_flush(out);
----- Original Message -----
From: "Philip Prindeville" <[email protected]>
To: [email protected]
Sent: Saturday, November 15, 2014 7:25:41 AM
Subject: CMS question on encrypting and signing
Hi.
I’m working on an application that requires datagrams of ASN.1 PDU’s to be
exchanged.
The application data needs to be first encrypted, then signed. I will not be
using streams, but rather memory BIO’s.
I could use the CMS_encrypt() into one BIO, then reset that and pass it as
input to CMS_sign() placing its output into a 3rd BIO.
But I’m wondering if there’s an easier way to do this. I could use chained
BIO’s and a stream, but I want to avoid using streams because they place
indeterminate lengths as the OCTET STRINGs followed by EOCs, which some of the
implementations that I need to interact with have a hard time parsing.
If there’s a flexible way to do this, I might contribute to the library a
convenience function to handle this, e.g. CMS_encrypt_sign(). Speaking of
convenience functions, when do you know if you need to use CMS_dataInit(), for
instance? It’s not documented...
Can someone point me in the right direction to do this efficiently? Even
though I’m not passing a lot of data in these messages, I do need to keep the
latency from processing down.
Thanks,
-Philip
P.S. Back in May it sounded like Kevin Le Gouguec was trying to do something
similar, so putting it into a convenience function in the library sounds like
the right thing to do.
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [email protected]
Automated List Manager [email protected]
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [email protected]
Automated List Manager [email protected]