for (i = 0; signerinfos[i] != NULL; i++) { signerinfo = signerinfos[i];
while (signerinfos) { signerinfo = *signerinfos;
NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd){    NSSCMSSignerInfo **signerinfos, *signerinfo;    NSSCMSContentInfo *cinfo;    SECOidTag digestalgtag;    SECStatus ret = SECFailure;    SECStatus rv;    SECItem *contentType;    int certcount;    int i, ci, cli, n, rci, si;    PLArenaPool *poolp;    CERTCertificateList *certlist;    extern const SEC_ASN1Template NSSCMSSignerInfoTemplate[];    poolp = sigd->cmsg->poolp;    cinfo = &(sigd->contentInfo);    /* did we have digest calculation going on? */    if (cinfo->digcx) {	rv = NSS_CMSDigestContext_FinishMultiple(cinfo->digcx, poolp, &(sigd->digests));	if (rv != SECSuccess)	    goto loser;		/* error has been set by NSS_CMSDigestContext_FinishMultiple */	cinfo->digcx = NULL;    }    signerinfos = sigd->signerInfos;    certcount = 0;    /* prepare all the SignerInfos */    for (i = 0; signerinfos[i] != NULL; i++) {	signerinfo = signerinfos[i];	/* find correct digest for this signerinfo */	digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);	n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);	if (n < 0 || sigd->digests == NULL || sigd->digests[n] == NULL) {	    /* oops - digest not found */	    PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);	    goto loser;	}	/* XXX if our content is anything else but data, we need to force the	 * presence of signed attributes (RFC2630 5.3 "signedAttributes is a	 * collection...") */	/* pass contentType here as we want a contentType attribute */	if ((contentType = NSS_CMSContentInfo_GetContentTypeOID(cinfo)) == NULL)	    goto loser;	/* sign the thing */	rv = NSS_CMSSignerInfo_Sign(signerinfo, sigd->digests[n], contentType);	if (rv != SECSuccess)	    goto loser;	/* while we're at it, count number of certs in certLists */	certlist = NSS_CMSSignerInfo_GetCertList(signerinfo);	if (certlist)	    certcount += certlist->len;    }    /* this is a SET OF, so we need to sort them guys */    rv = NSS_CMSArray_SortByDER((void **)signerinfos, NSSCMSSignerInfoTemplate, NULL);    if (rv != SECSuccess)	goto loser;    /*     * now prepare certs & crls     */    /* count the rest of the certs */    if (sigd->certs != NULL) {	for (ci = 0; sigd->certs[ci] != NULL; ci++)	    certcount++;    }    if (sigd->certLists != NULL) {	for (cli = 0; sigd->certLists[cli] != NULL; cli++)	    certcount += sigd->certLists[cli]->len;    }    if (certcount == 0) {	sigd->rawCerts = NULL;    } else {	/*	 * Combine all of the certs and cert chains into rawcerts.	 * Note: certcount is an upper bound; we may not need that many slots	 * but we will allocate anyway to avoid having to do another pass.	 * (The temporary space saving is not worth it.)	 *	 * XXX ARGH - this NEEDS to be fixed. need to come up with a decent	 *  SetOfDERcertficates implementation	 */	sigd->rawCerts = (SECItem **)PORT_ArenaAlloc(poolp, (certcount + 1) * sizeof(SECItem *));	if (sigd->rawCerts == NULL)	    return SECFailure;	/*	 * XXX Want to check for duplicates and not add *any* cert that is	 * already in the set.  This will be more important when we start	 * dealing with larger sets of certs, dual-key certs (signing and	 * encryption), etc.  For the time being we can slide by...	 *	 * XXX ARGH - this NEEDS to be fixed. need to come up with a decent	 *  SetOfDERcertficates implementation	 */	rci = 0;	if (signerinfos != NULL) {	    for (si = 0; signerinfos[si] != NULL; si++) {		signerinfo = signerinfos[si];		for (ci = 0; ci < signerinfo->certList->len; ci++)		    sigd->rawCerts[rci++] = &(signerinfo->certList->certs[ci]);	    }	}	if (sigd->certs != NULL) {	    for (ci = 0; sigd->certs[ci] != NULL; ci++)		sigd->rawCerts[rci++] = &(sigd->certs[ci]->derCert);	}	if (sigd->certLists != NULL) {	    for (cli = 0; sigd->certLists[cli] != NULL; cli++) {		for (ci = 0; ci < sigd->certLists[cli]->len; ci++)		    sigd->rawCerts[rci++] = &(sigd->certLists[cli]->certs[ci]);	    }	}	sigd->rawCerts[rci] = NULL;	/* this is a SET OF, so we need to sort them guys - we have the DER already, though */	NSS_CMSArray_Sort((void **)sigd->rawCerts, NSS_CMSUtil_DERCompare, NULL, NULL);    }    ret = SECSuccess;loser:    return ret;}