/*
 * Private version of CertGroupConstruct, used by CertGroupConstruct and
 * CertGroupVerify. Populates a TP-style TPCertGroup for further processing.
 * This only throws CSSM-style exceptions in the following cases:
 *
 *  -- input parameter errors
 *  -- the first (leaf) cert is bad (doesn't parse, expired, not valid yet).
 *  -- root found but it doesn't self-verify
 *
 *  All other cert-related errors simply result in the bad cert being ignored.
 *  Other exceptions are gross system errors like malloc failure.
 */
void AppleTPSession::CertGroupConstructPriv(CSSM_CL_HANDLE clHand,
		CSSM_CSP_HANDLE 		cspHand,
		TPCertGroup 			&inCertGroup,
		const CSSM_DL_DB_LIST 	*DBList,			// optional here
		const char 				*cssmTimeStr,		// optional

		/* trusted anchors, optional */
		/* FIXME - maybe this should be a TPCertGroup */
		uint32 					numAnchorCerts,
		const CSSM_DATA			*anchorCerts,

		/* CSSM_TP_ACTION_FETCH_CERT_FROM_NET, CSSM_TP_ACTION_TRUST_SETTINGS */
		CSSM_APPLE_TP_ACTION_FLAGS	actionFlags,

		/* optional user trust parameters */
		const CSSM_OID			*policyOid,
		const char				*policyStr,
		uint32					policyStrLen,
		SecTrustSettingsKeyUsage	keyUse,

		/*
		 * Certs to be freed by caller (i.e., TPCertInfo which we allocate
		 * as a result of using a cert from anchorCerts or dbList) are added
		 * to this group.
		 */
		TPCertGroup				&certsToBeFreed,

		/* returned */
		CSSM_BOOL				&verifiedToRoot,		// end of chain self-verifies
		CSSM_BOOL				&verifiedToAnchor,		// end of chain in anchors
		CSSM_BOOL				&verifiedViaTrustSetting,	// chain ends per User Trust setting
		TPCertGroup 			&outCertGroup)			// RETURNED
{
	TPCertInfo			*subjectCert;				// the one we're working on
	CSSM_RETURN			outErr = CSSM_OK;

	/* this'll be the first subject cert in the main loop */
	subjectCert = inCertGroup.certAtIndex(0);

	/* Append leaf cert to outCertGroup */
	outCertGroup.appendCert(subjectCert);
	subjectCert->isLeaf(true);
	subjectCert->isFromInputCerts(true);
	outCertGroup.setAllUnused();
	subjectCert->used(true);

	outErr = outCertGroup.buildCertGroup(
		*subjectCert,
		&inCertGroup,
		DBList,
		clHand,
		cspHand,
		cssmTimeStr,
		numAnchorCerts,
		anchorCerts,
		certsToBeFreed,
		&certsToBeFreed,	// gatheredCerts to accumulate net/DB fetches
		CSSM_TRUE,			// subjectIsInGroup - enables root check on
							//    subject cert
		actionFlags,
		policyOid,
		policyStr,
		policyStrLen,
		keyUse,

		verifiedToRoot,
		verifiedToAnchor,
		verifiedViaTrustSetting);
	if(outErr) {
		CssmError::throwMe(outErr);
	}
}