On Tue, Nov 22, 2016, Wim Lewis wrote: > I'm trying to produce nested structures, like signed-enveloped-signed data. This is explicitly described in the various RFCs, but I can't figure out how to get OpenSSL to produce valid output, and I can't find any code examples of doing this. > > What I'm doing (which doesn't quite work) is this: first I create the inner content using (e.g.) CMS_encrypt(), getting a CMS_ContentInfo structure. This works correctly and if I write it out I get what I expect. Then I want to create another CMS_ContentInfo, e.g. using CMS_sign(), which envelops the first one. How do I cause the ContentInfo of the SignedData structure to be the ContentInfo I obtained from CMS_encrypt()? The closest I can come is code like this: > > > CMS_ContentInfo *innerCms = ....; // Create the inner CMS content. > BIO *inbetween = BIO_new(BIO_s_mem()); // Write it to a buffer. > i2d_CMS_bio(inbetween, innerCms); > CMS_ContentInfo *outerCms = CMS_sign(cert, key, NULL, inbetween, CMS_BINARY|CMS_PARTIAL|CMS_NOSMIMECAP); > CMS_set1_eContentType(outerCms, OBJ_nid2obj(NID of innerCms)); // Set the content-type > CMS_final(outerCms, inbetween, NULL, CMS_BINARY|CMS_NOSMIMECAP); // Finalize the CMS structure > > (My actual code checks all the return values, but I left those off for clarity.) > > Unfortunately, this produces output like this: > > ContentInfo { > contentType = :pkcs7-signedData; > content = SignedData { > ... various ... > contentInfo = ContentInfo { > contentType = :pkcs7-envelopedData; > content = [0] EXPLICIT OctetString{...} > } > } > } > > where the inner OCTET STRING contains *another* ContentInfo, which then contains the nested object. > > But from my understanding, the correct syntax for a nested CMS structure is this: > > ContentInfo { > contentType = :pkcs7-signedData; > content = SignedData { > ... various ... > contentInfo = ContentInfo { > contentType = :pkcs7-envelopedData; > content = [0] EXPLICIT EnvelopedData { > ...fields of the EnvelopedData structure... > } > } > } > } > > In other words, I have two extra, incorrect levels of encapsulation: the OCTET STRING and the extra ContentInfo. > Something like that did happen for PKCS#7 but the OCTET STRING encapsulation is correct for CMS. If you look in RFC5652: SignedData ::= SEQUENCE { version CMSVersion, digestAlgorithms DigestAlgorithmIdentifiers, encapContentInfo EncapsulatedContentInfo, certificates [0] IMPLICIT CertificateSet OPTIONAL, crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, signerInfos SignerInfos } The content is of type Encapsulated ConentInfo: EncapsulatedContentInfo ::= SEQUENCE { eContentType ContentType, eContent [0] EXPLICIT OCTET STRING OPTIONAL } ContentType ::= OBJECT IDENTIFIER Here eContent is always an OCTET STRING if it is present. It also says: eContent is the content itself, carried as an octet string. The eContent need not be DER encoded. Steve. -- Dr Stephen N. Henson. OpenSSL project core developer. Commercial tech support now available see: http://www.openssl.org -- openssl-users mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users