Question

How to enforce definite length encoding with CMS in NSS?

I am trying to get NSS's CMS encoder to encode with DER, but the folks as mozilla have apparently only worried about BER encoding (as far as I can tell.) I am able to get definite encoding with primitive types, but all constructed types have indefinite encoding.

Code I am currently using (with NSS-3.12.7):

/* Create memory pool (aka an arena.) */
  PLArenaPool * arena = PORT_NewArena(4096);

  /* Create the CMS Message object */
  fprintf(stderr, "Create the CMS Message object\n");
  NSSCMSMessage * cmsMessage = NSS_CMSMessage_Create(arena);
  NSSCMSContentInfo * cinfo = NSS_CMSMessage_GetContentInfo(cmsMessage);

  /* Create a DigestedData object who's parent is cmsMessage */
  fprintf(stderr, "Create a DigestedData object who's parent is cmsMessage\n");
  SECAlgorithmID * id = CreateDigestAlgorithmID(arena, SEC_OID_SHA1);
  NSSCMSDigestedData * digestedData =
    NSS_CMSDigestedData_Create(cmsMessage, id);
  NSSCMSContentInfo * dcinfo =
    NSS_CMSDigestedData_GetContentInfo(digestedData);

  /* Tell the DigestedData object to include the content (not detached.) */
  fprintf(stderr, "Tell the DigestedData object to include the content (Length: %d)\n", in_len);
  SECItem * in_data = CreateSECItemString(arena, in, in_len);
  NSS_CMSContentInfo_SetContent_Data(cmsMessage, dcinfo, in_data, PR_FALSE);

  /* Put digestedData into cmsMessage's contentInfo section */
  fprintf(stderr, "Put digestedData into cmsMessage's contentInfo section\n");
  NSS_CMSContentInfo_SetContent_DigestedData(cmsMessage, cinfo, digestedData);

  /* Encode input data to DER format with following parameters */
  fprintf(stderr, "Encode input data to DER format\n");
  SECItem * encodedOutput = (SECItem*)PORT_ArenaZAlloc(arena, sizeof(SECItem));

  NSSCMSEncoderContext * ecx =
    NSS_CMSEncoder_Start(cmsMessage, NULL, NULL, encodedOutput, arena,
      NULL, NULL, NULL, NULL, NULL, NULL);
  fprintf(stderr, "NSS_CMSEncoder_Update\n");
  NSS_CMSEncoder_Update(ecx, NULL, 0);
  fprintf(stderr, "NSS_CMSEncoder_Finish\n");
  NSS_CMSEncoder_Finish(ecx);

Any help appreciated, Chenz

Was it helpful?

Solution

CMS itself is a BER standard, so by default NSS encodes using indefinite encoding. This is because NSS expects to stream the data through it's pipeline, providing the application with intermediate results without having to receive the entire stream before it produces any output.

That being said, there are some applications for the CMS encoder where you don't care about streaming the data, and want to use definite encoding. The NSS team recently added a function which will turn off indefinite encoding called:

NSS_CMSContentInfo_SetDontStream()

call it on your top level contentinfo. Unfortunately it was added in NSS 3.12.10, so you'll have to move up to use it.

If you have other NSS questions, you should try the Mozilla crypto mailing lists: dev-tech-crypto@lists.mozilla.org

bob

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top