Bug 499440

Summary: Pre-specified data ignored by the NSS CMS Encoder
Product: [Fedora] Fedora Reporter: Miloslav Trmač <mitr>
Component: nssAssignee: Kai Engert (:kaie) (inactive account) <kengert>
Status: CLOSED UPSTREAM QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: 10CC: emaldona, kengert, rrelyea
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2009-05-07 19:33:23 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Reproducer, see comment#0. none

Description Miloslav Trmač 2009-05-06 16:57:38 UTC
Created attachment 342687 [details]
Reproducer, see comment#0.

Version:
nss-3.12.2.0-5.fc10.x86_64, and a locally rebuilt nss-3.23.3-3.

If NSS_CMSContentInfo_SetContent_Data() is called without specifing a SECItem for the data, and data is later supplied in by NSS_CMSEncoder_Update(), everything works correctly.

If NSS_CMSContentInfo_SetContent_Data() is called with a SECItem, the data in the SECItem does not appear in the output at all.

To reproduce, compile the attached file with
   gcc $(pkg-config --cflags --libs nss glib-2.0) repro.c
and run
   ./a.out a/path/to/a/certificate.pem > x
"x" will be 1360 bytes large, and (cmsutil -D) will correctly display the content.

If you redefine INLINE_DATA in the file to "1" and recompile, after
   ./a.out a/path/to/a/certificate.pem > x
"x" will be only 310 bytes large, and it won't contain the content.  derdump will show that the octetstring that would contain the encrypted data is simply missing.


AFAICS this is going on:
* When secasn1.e finishes encoding the contentEncAlg field of NSSCMSEncryptedContentInfoTemplate, sec_asn1e_next_in_sequence() gets called.
* ...next_in_sequence does the "after" field notification, advances the "child" template (to point to the rawContent field), and does the "before" notification.  Note that the "current ASN1 state" is not changed, only the template pointer is - the ASN1 state is inconsistent.
* the "before" notification ends up in the "if (before && dest == &(cinfo->rawContent))" condition of nss_cms_encoder_notify(), which correctly notices that the raw data was pre-supplied, and calls nss_cms_encoder_work_data ().
* nss_cms_encoder_work_data () encrypts the pre-supplied raw data, and calls SEC_ASN1EncoderUpdate() with it
* SEC_ASN1EncoderUpdate is in an inconsistent state - as noted above; it will call sec_asn1e_next_in_sequence() *again*
* sec_asn1e_next_in_sequence() does the "after" field notification - for rawContent (destroying the encryption context), advances the "child" template *after* rawContent
* ... The ASN1 encoder continues encoding, but the "raw" field was already stepped over and the supplied data will never be used.

Comment 1 Kai Engert (:kaie) (inactive account) 2009-05-07 19:32:48 UTC
Library functionality bugs should get reported upstream.
I've forwarded your bug reported 1:1 at 
https://bugzilla.mozilla.org/show_bug.cgi?id=491914