1/*
2 * Copyright (c) 2000-2011 Apple Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19/*
20 * TPCertInfo.h - TP's private certificate info and cert group classes
21 */
22
23#ifndef	_TP_CERT_INFO_H_
24#define _TP_CERT_INFO_H_
25
26#include <Security/cssm.h>
27#include <Security/SecTrust.h>
28#include <Security/SecTrustSettings.h>
29#include <security_utilities/alloc.h>
30#include <security_utilities/threading.h>
31#include <security_utilities/globalizer.h>
32#include <CoreFoundation/CFDate.h>
33
34/* protects TP-wide access to time() and gmtime() */
35extern ModuleNexus<Mutex> tpTimeLock;
36
37/*
38 * Prototypes for functions which are isomorphic between certs and CRLs at the
39 * CL API.
40 */
41typedef CSSM_RETURN (*clGetFirstFieldFcn)(
42	CSSM_CL_HANDLE CLHandle,
43	CSSM_HANDLE ItemHandle,			// cached cert or CRL
44	const CSSM_OID *ItemField,
45	CSSM_HANDLE_PTR ResultsHandle,
46	uint32 *NumberOfMatchedFields,
47	CSSM_DATA_PTR *Value);
48typedef CSSM_RETURN (*clAbortQueryFcn)(
49	CSSM_CL_HANDLE CLHandle,
50	CSSM_HANDLE ResultsHandle);		// from clGetFirstFieldFcn
51typedef CSSM_RETURN (*clCacheItemFcn)(
52	CSSM_CL_HANDLE CLHandle,
53	const CSSM_DATA *Item,			// raw cert or CRL
54	CSSM_HANDLE_PTR CertHandle);
55typedef CSSM_RETURN (*clAbortCacheFcn)(
56	CSSM_CL_HANDLE CLHandle,
57	CSSM_HANDLE ItemHandle);		// from clCacheItemFcn
58typedef CSSM_RETURN (*clItemVfyFcn)(
59	CSSM_CL_HANDLE CLHandle,
60	CSSM_CC_HANDLE CCHandle,
61	const CSSM_DATA *CrlOrCertToBeVerified,
62	const CSSM_DATA *SignerCert,
63	const CSSM_FIELD *VerifyScope,
64	uint32 ScopeSize);
65
66typedef struct {
67	/* CL/cert-specific functions */
68	clGetFirstFieldFcn	getField;
69	clAbortQueryFcn		abortQuery;
70	clCacheItemFcn		cacheItem;
71	clAbortCacheFcn		abortCache;
72	clItemVfyFcn		itemVerify;
73	/* CL/cert-specific OIDs */
74	const CSSM_OID		*notBeforeOid;
75	const CSSM_OID		*notAfterOid;
76	/* CL/cert specific errors */
77	CSSM_RETURN			invalidItemRtn;	// CSSMERR_TP_INVALID_{CERT,CRL}_POINTER
78	CSSM_RETURN			expiredRtn;
79	CSSM_RETURN			notValidYetRtn;
80} TPClItemCalls;
81
82class TPCertInfo;
83
84/*
85 * On construction of a TPClItemInfo, specifies whether or not to
86 * copy the incoming item data (in which we free it upon destruction)
87 * or to use caller's data as is (in which case the caller maintains
88 * the data).
89 */
90typedef enum {
91	TIC_None = 0,		// never used
92	TIC_NoCopy,			// caller maintains
93	TIC_CopyData		// we copy and free
94} TPItemCopy;
95
96/*
97 * State of a cert's mIsRoot flag. We do signature self-verify on demand.
98 */
99typedef enum {
100	TRS_Unknown,		// initial state
101	TRS_NamesMatch,		// subject == issuer, but no sig verify yet
102	TRS_NotRoot,		// subject != issuer, OR sig verify failed
103	TRS_IsRoot			// it's a root
104} TPRootState;
105
106/*
107 * Base class for TPCertInfo and TPCrlInfo. Encapsulates caching of
108 * an entity within the CL, field lookup/free, and signature verify,
109 * all of which use similar functions at the CL API.
110 */
111class TPClItemInfo
112{
113	NOCOPY(TPClItemInfo)
114public:
115	TPClItemInfo(
116		CSSM_CL_HANDLE		clHand,
117		CSSM_CSP_HANDLE		cspHand,
118		const TPClItemCalls	&clCalls,
119		const CSSM_DATA		*itemData,
120		TPItemCopy			copyItemData,
121		const char			*verifyTime);		// may be NULL
122
123	~TPClItemInfo();
124	void releaseResources();
125
126	/*
127	 * Fetch arbitrary field from cached item.
128	 * Only should be used when caller is sure there is either zero or one
129	 * of the requested fields present in the cert.
130	 */
131	CSSM_RETURN fetchField(
132		const CSSM_OID	*fieldOid,
133		CSSM_DATA_PTR	*fieldData);			// mallocd by CL and RETURNED
134
135	/* free arbitrary field obtained from fetchField() */
136	CSSM_RETURN freeField(
137		const CSSM_OID	*fieldOid,
138		CSSM_DATA_PTR	fieldData);
139
140	/*
141	 * Verify with an issuer cert - works on certs and CRLs.
142	 * Issuer/subject name match already performed by caller.
143	 * May return CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE without
144	 * performing a signature op, in which case it is the caller's
145	 * resposibility to complete this operation later when
146	 * sufficient information is available.
147	 *
148	 * Optional paramCert is used to provide parameters when issuer
149	 * has a partial public key.
150	 */
151	CSSM_RETURN verifyWithIssuer(
152		TPCertInfo		*issuerCert,
153		TPCertInfo		*paramCert = NULL) const;
154
155	/* accessors */
156	CSSM_CL_HANDLE	clHand()	  	const { return mClHand; }
157	CSSM_CSP_HANDLE	cspHand()	  	const { return mCspHand; }
158	CSSM_HANDLE		cacheHand()	  	const { return mCacheHand; }
159	const CSSM_DATA *itemData()	  	const { return mItemData; }
160	const CSSM_DATA *issuerName() 	const { return mIssuerName; };
161	const CSSM_DATA *subjectKeyID()	const { return mSubjectKeyID; };
162	const CSSM_DATA *authorityKeyID()	const { return mAuthorityKeyID; };
163	unsigned 		index()			const { return mIndex; }
164	void 			index(unsigned dex)	  { mIndex = dex; }
165	bool			isExpired()			  { return mIsExpired; }
166	bool			isNotValidYet()		  { return mIsNotValidYet; }
167
168	/*
169	 * Calculate validity (not before/after). Returns
170	 * 		CSSMERR_{TP_CERT,APPLETP_CRL}_NOT_VALID_YET
171	 *		CSSMERR_xxx_T_EXPIRED
172	 *		CSSM_OK
173	 *		CSSMERR_xxx_INVALID_CERT_POINTER, other "bogus cert" errors
174	 */
175	CSSM_RETURN calculateCurrent(
176		const char 			*verifyString = NULL);
177
178private:
179
180	/* Tell CL to parse and cache the item */
181	CSSM_RETURN cacheItem(
182		const CSSM_DATA		*itemData,
183		TPItemCopy			copyItemData);
184
185
186	/* fetch not before/after fields */
187	void fetchNotBeforeAfter();
188
189	CSSM_CL_HANDLE			mClHand;				// always valid
190	CSSM_CSP_HANDLE			mCspHand;				// always valid
191	const TPClItemCalls		&mClCalls;
192	bool					mWeOwnTheData;			// if true, we have to free
193													//    mCertData
194	/* following are valid subsequent to cacheItem(), generally
195	 * called by subclass's constructor */
196	CSSM_HANDLE				mCacheHand;
197	CSSM_DATA_PTR			mIssuerName;
198	CSSM_DATA_PTR			mSubjectKeyID;
199	CSSM_DATA_PTR			mAuthorityKeyID;
200	CSSM_DATA_PTR			mItemData;
201	CSSM_ALGORITHMS			mSigAlg;
202
203	/* calculated implicitly at construction */
204	CFDateRef				mNotBefore;
205	CFDateRef				mNotAfter;
206
207	/* also calculated at construction, but can be recalculated at will */
208	bool					mIsExpired;
209	bool					mIsNotValidYet;
210
211	unsigned				mIndex;
212};
213
214/*
215 * Class representing one certificate. The raw cert data usually comes from
216 * a client (via incoming cert groups in CertGroupConstruct() and
217 * CertGroupVerify()); in this case, we don't own the raw data and
218 * don't copy or free it. Caller can optionally specify that we copy
219 * (and own and eventually free) the raw cert data. Currently this is
220 * done when we find a cert in a DlDb or from the net. The constructor throws
221 * on any error (bad cert data); subsequent to successful construction, no CSSM
222 * errors are thrown and it's guaranteed that the cert is basically good and
223 * successfully cached in the CL, and that we have a locally cached subject
224 * and issuer name (in normalized encoded format).
225 */
226class TPCertInfo : public TPClItemInfo
227{
228	NOCOPY(TPCertInfo)
229public:
230	/*
231	 * No default constructor - this is the only way.
232	 * This caches the cert and fetches subjectName and issuerName
233	 * to ensure the incoming certData is well-constructed.
234	 */
235	TPCertInfo(
236		CSSM_CL_HANDLE		clHand,
237		CSSM_CSP_HANDLE		cspHand,
238		const CSSM_DATA		*certData,
239		TPItemCopy			copyCertData,
240
241		const char			*verifyTime);		// may be NULL
242
243	/* frees mSubjectName, mIssuerName, mCacheHand via mClHand */
244	~TPCertInfo();
245
246	/* accessors */
247	const CSSM_DATA *subjectName();
248
249	bool 		isSelfSigned(bool avoidVerify = false);
250
251	bool		isAnchor()				{ return mIsAnchor; }
252	void		isAnchor(bool a)		{ mIsAnchor = a; }
253	bool		isFromNet()				{ return mIsFromNet; }
254	void		isFromNet(bool n)		{ mIsFromNet = n; };
255	bool		isFromInputCerts()		{ return mIsFromInputCerts; }
256	void		isFromInputCerts(bool i) { mIsFromInputCerts = i; }
257	unsigned	numStatusCodes()		{ return mNumStatusCodes; }
258	CSSM_RETURN	*statusCodes()			{ return mStatusCodes; }
259	CSSM_DL_DB_HANDLE dlDbHandle()		{ return mDlDbHandle; }
260	void dlDbHandle(CSSM_DL_DB_HANDLE hand)
261										{ mDlDbHandle = hand; }
262	CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord()
263										{ return mUniqueRecord; }
264	void uniqueRecord(CSSM_DB_UNIQUE_RECORD_PTR rec)
265										{ mUniqueRecord = rec; }
266	CSSM_KEY_PTR pubKey()				{ return mPublicKey; }
267	bool		used()					{ return mUsed; }
268	void 		used(bool u)			{ mUsed = u; }
269	bool		isLeaf()				{ return mIsLeaf; }
270	void		isLeaf(bool l)			{ mIsLeaf = l; }
271
272	SecTrustSettingsDomain 	trustSettingsDomain() { return mTrustSettingsDomain; }
273	SecTrustSettingsResult trustSettingsResult() { return mTrustSettingsResult; }
274	bool ignoredError()					{ return mIgnoredError; }
275
276	/* true means "verification terminated due to user trust setting" */
277	bool		trustSettingsFound();
278	/*
279	 * Am I the issuer of the specified subject item? Returns true if so.
280	 * Works for subject certs as well as CRLs.
281	 */
282	bool isIssuerOf(
283		const TPClItemInfo	&subject);
284
285	/*
286	 * Does my subject key id match the authority key id of the specified
287	 * subject item? Returns true if so.
288	 */
289	bool isAuthorityKeyOf(
290		const TPClItemInfo	&subject);
291
292	/*
293	 * Add error status to mStatusCodes[]. Check to see if the
294	 * added status is allowed per mAllowedErrs; if not return true.
295	 * Returns false of the status *is* an allowed error.
296	 */
297	bool addStatusCode(
298		CSSM_RETURN 		code);
299
300	/*
301	 * See if the specified error status is in the mStatusCodes array.
302	 */
303	bool hasStatusCode(
304		CSSM_RETURN			code);
305
306	/*
307	 * See if the specified error status is allowed (return false) or
308	 * fatal (return true) per mAllowedErrs[].
309	 */
310	bool isStatusFatal(
311		CSSM_RETURN			code);
312
313	/*
314	 * Indicate whether this cert's public key is a CSSM_KEYATTR_PARTIAL
315	 * key.
316	 */
317	bool 					hasPartialKey();
318
319	/* Indicate whether this cert should be explicitly rejected.
320	 */
321	bool					shouldReject();
322
323	/*
324	 * Flag to indicate that at least one revocation policy has successfully
325	 * achieved a positive verification of the cert.
326	 */
327	bool				revokeCheckGood()			{ return mRevCheckGood; }
328	void				revokeCheckGood(bool b)		{ mRevCheckGood = b; }
329
330	/*
331	 * Flag to indicate "I have successfully been checked for revocation
332	 * status and the per-policy action data indicates that I need not be
333	 * checked again by any other revocation policy". E.g.,
334	 * CSSM_TP_ACTION_CRL_SUFFICIENT is set and CRL revocation checking
335	 * was successful for this cert.
336	 */
337	bool				revokeCheckComplete()		{ return mRevCheckComplete; }
338	void				revokeCheckComplete(bool b)	{ mRevCheckComplete = b; }
339
340	/*
341	 * Evaluate user trust; returns true if positive match found - i.e.,
342	 * cert chain construction is done.
343	 * The foundEntry return value indicates that *some* entry was found for
344	 * the cert, regardless of the trust setting evaluation.
345	 */
346	OSStatus evaluateTrustSettings(
347				const CSSM_OID			&policyOid,
348				const char				*policyString,		// optional
349				uint32					policyStringLen,
350				SecTrustSettingsKeyUsage keyUse,				// optional
351				bool 					*foundMatchingEntry,
352				bool					*foundEntry);		// RETURNED
353
354	bool 				hasEmptySubjectName();
355
356	/* Free mUniqueRecord if it exists */
357	void	freeUniqueRecord();
358
359private:
360	/* obtained from CL at construction */
361	CSSM_DATA_PTR			mSubjectName;		// always valid
362	CSSM_DATA_PTR			mPublicKeyData;		// mPublicKey obtained from this field
363	CSSM_KEY_PTR			mPublicKey;
364
365	/* maintained by caller, default at constructor 0/false */
366	bool					mIsAnchor;
367	bool					mIsFromInputCerts;
368	bool					mIsFromNet;
369	unsigned				mNumStatusCodes;
370	CSSM_RETURN				*mStatusCodes;
371	CSSM_DL_DB_HANDLE		mDlDbHandle;
372	CSSM_DB_UNIQUE_RECORD_PTR mUniqueRecord;
373	bool					mUsed;			// e.g., used in current loop
374	bool					mIsLeaf;		// first in chain
375	TPRootState				mIsRoot;		// subject == issuer
376	bool					mRevCheckGood;		// >= 1 revoke check good
377	bool					mRevCheckComplete;	// no more revoke checking needed
378
379	/*
380	 * When true, we've already called SecTrustSettingsEvaluateCert,
381	 * and the cached results are in following member vars.
382	 */
383	bool					mTrustSettingsEvaluated;
384
385	/* result of trust settings evaluation */
386	SecTrustSettingsDomain	mTrustSettingsDomain;
387	SecTrustSettingsResult	mTrustSettingsResult;
388	bool					mTrustSettingsFoundAnyEntry;
389	bool					mTrustSettingsFoundMatchingEntry;
390
391	/* allowed errors obtained from SecTrustSettingsEvaluateCert() */
392	CSSM_RETURN				*mAllowedErrs;
393	uint32					mNumAllowedErrs;
394
395	/* we actually ignored one of mAllowedErrors[] */
396	bool					mIgnoredError;
397
398	/* key usage for which mTrustSettingsResult was evaluated */
399	SecTrustSettingsKeyUsage mTrustSettingsKeyUsage;
400
401	/* for SecTrustSettingsEvaluateCert() */
402	CFStringRef				mCertHashStr;
403
404	void 					releaseResources();
405};
406
407/* Describe who owns the items in a TP{Cert,Crl}Group */
408typedef enum {
409	TGO_None = 0,		// not used
410	TGO_Group,			// TP{Cert,Crl}Group owns the items
411	TGO_Caller			// caller owns the items
412} TPGroupOwner;
413
414/*
415 * TP's private Cert Group class. Provides a list of TPCertInfo pointers,
416 * to which caller can append additional elements, access an element at
417 * an arbitrary position, and remove an element at an arbitrary position.
418 */
419class TPCertGroup
420{
421	NOCOPY(TPCertGroup)
422public:
423	/*
424	 * No default constructor.
425	 * This one creates an empty TPCertGroup.
426	 */
427	TPCertGroup(
428		Allocator			&alloc,
429		TPGroupOwner		whoOwns);		// if TGO_Group, we delete
430
431	/*
432	 * Construct from unordered, untrusted CSSM_CERTGROUP. Resulting
433	 * TPCertInfos are more or less in the same order as the incoming
434	 * certs, though incoming certs are discarded if they don't parse.
435	 * No verification of any sort is performed.
436	 */
437	TPCertGroup(
438		const CSSM_CERTGROUP 	&CertGroupFrag,
439		CSSM_CL_HANDLE 			clHand,
440		CSSM_CSP_HANDLE 		cspHand,
441		Allocator				&alloc,
442		const char				*verifyString,			// may be NULL
443		bool					firstCertMustBeValid,
444		TPGroupOwner			whoOwns);
445
446	/*
447	 * Deletes all TPCertInfo's.
448	 */
449	~TPCertGroup();
450
451	/*
452	 * Construct ordered, verified cert chain from a variety of inputs.
453	 * Time validity is ignored and needs to be checked by caller (it's
454	 * stored in each TPCertInfo we add to ourself during construction).
455	 * The only error returned is CSSMERR_APPLETP_INVALID_ROOT, meaning
456	 * we verified back to a supposed root cert which did not in fact
457	 * self-verify. Other interesting status is returned via the
458	 * verifiedToRoot and verifiedToAnchor flags.
459	 *
460	 * NOTE: is it the caller's responsibility to call setAllUnused()
461	 * for both incoming cert groups (inCertGroup and gatheredCerts).
462	 * We don't do that here because we may call ourself recursively.
463	 *
464	 * subjectItem may or may not be in the cert group (currently, it
465	 * is in the group if it's a cert and it's not if it's a CRL, but
466	 * we don't rely on that).
467	 */
468	CSSM_RETURN buildCertGroup(
469		const TPClItemInfo		&subjectItem,	// Cert or CRL
470		TPCertGroup				*inCertGroup,	// optional
471		const CSSM_DL_DB_LIST 	*dbList,		// optional
472		CSSM_CL_HANDLE 			clHand,
473		CSSM_CSP_HANDLE 		cspHand,
474		const char 				*verifyString,	// optional, for establishing
475												//   validity of new TPCertInfos
476		/* trusted anchors, optional */
477		/* FIXME - maybe this should be a TPCertGroup */
478		uint32 					numAnchorCerts,
479		const CSSM_DATA			*anchorCerts,
480
481		/*
482		 * Certs to be freed by caller (i.e., TPCertInfo which we allocate
483		 * as a result of using a cert from anchorCerts or dbList) are added
484		 * to this group.
485		 */
486		TPCertGroup				&certsToBeFreed,
487
488		/*
489		* Other certificates gathered during the course of this operation,
490		* currently consisting of certs fetched from DBs and from the net.
491		* This is not used when called by AppleTPSession::CertGroupConstructPriv;
492		* it's an optimization for the case when we're building a cert group
493		* for TPCrlInfo::verifyWithContext - we avoid re-fetching certs from
494		* the net which are needed to verify both the subject cert and a CRL.
495		*/
496		TPCertGroup				*gatheredCerts,
497
498		/*
499		* Indicates that subjectItem is a cert in this cert group.
500		* If true, that cert will be tested for "root-ness", including
501		*   -- subject/issuer compare
502		*   -- signature self-verify
503		*   -- anchor compare
504		*/
505		CSSM_BOOL				subjectIsInGroup,
506
507		/* currently, only CSSM_TP_ACTION_FETCH_CERT_FROM_NET and
508		 * CSSM_TP_ACTION_TRUST_SETTINGS are interesting */
509		CSSM_APPLE_TP_ACTION_FLAGS	actionFlags,
510
511		/* CSSM_TP_ACTION_TRUST_SETTINGS parameters */
512		const CSSM_OID			*policyOid,
513		const char				*policyStr,
514		uint32					policyStrLen,
515		SecTrustSettingsKeyUsage	leafKeyUse,
516
517		/* returned */
518		CSSM_BOOL				&verifiedToRoot,		// end of chain self-verifies
519		CSSM_BOOL				&verifiedToAnchor,		// end of chain in anchors
520		CSSM_BOOL				&verifiedViaTrustSettings);	// chain ends per User Trust setting
521
522	/* add/remove/access TPTCertInfo's. */
523	void appendCert(
524		TPCertInfo			*certInfo);			// appends to end of mCertInfo
525	TPCertInfo *certAtIndex(
526		unsigned			index);
527	TPCertInfo *removeCertAtIndex(
528		unsigned			index);				// doesn't delete the cert, just
529												// removes it from our list
530	unsigned numCerts() const 					// how many do we have?
531		{ return mNumCerts; }
532
533	/*
534	 * Convenience accessors for first and last cert, only valid when we have
535	 * at least one cert.
536	 */
537	TPCertInfo *firstCert();
538	TPCertInfo *lastCert();
539
540	/* build a CSSM_CERTGROUP corresponding with our mCertInfo */
541	CSSM_CERTGROUP_PTR buildCssmCertGroup();
542
543	/* build a CSSM_TP_APPLE_EVIDENCE_INFO array corresponding with our
544	 * mCertInfo */
545	CSSM_TP_APPLE_EVIDENCE_INFO *buildCssmEvidenceInfo();
546
547	/* Given a status for basic construction of a cert group and a status
548	 * of (optional) policy verification, plus the implicit notBefore/notAfter
549	 * status in the certs, calculate a global return code. This just
550	 * encapsulates a policy for CertGroupConstruct and CertGroupVerify.
551	 */
552	CSSM_RETURN getReturnCode(
553		CSSM_RETURN					constructStatus,
554		CSSM_RETURN					policyStatus,
555		CSSM_APPLE_TP_ACTION_FLAGS	actionFlags);
556
557	Allocator
558		&alloc() {return mAlloc; }
559
560	/* set all TPCertInfo.mUsed flags false */
561	void					setAllUnused();
562
563	/* free records obtained from DBs */
564	void					freeDbRecords();
565
566	/*
567	 * See if the specified error status is allowed (return true) or
568	 * fatal (return false) per each cert's mAllowedErrs[]. Returns
569	 * true if any cert returns false for its isStatusFatal() call.
570	 * The list of errors which can apply to cert-chain-wide allowedErrors
571	 * is right here; if the incoming error is not in that list, we
572	 * return false. If the incoming error code is CSSM_OK we return
573	 * true as a convenience for our callers.
574	 */
575	bool isAllowedError(
576		CSSM_RETURN	code);
577
578	/*
579	 * Determine if we already have the specified cert in this group.
580	 */
581	bool isInGroup(TPCertInfo &certInfo);
582
583	/*
584	 * Given a constructed cert group, encode all the issuers
585	 * (i.e. chain minus the leaf, unless numCerts() is 1) as a PEM data blob.
586	 * Caller is responsible for freeing the data.
587	 */
588	void encodeIssuers(CSSM_DATA &issuers);
589
590private:
591
592	/*
593	 * Search unused incoming certs to find an issuer of specified
594	 * cert or CRL.
595	 * WARNING this assumes a valied "used" state for all certs
596	 * in this group.
597	 * If partialIssuerKey is true on return, caller must re-verify signature
598     * of subject later when sufficient info is available.
599	 */
600	TPCertInfo *findIssuerForCertOrCrl(
601		const TPClItemInfo 	&subject,
602		bool				&partialIssuerKey);
603
604	/*
605	 * Called from buildCertGroup as final processing of a constructed
606	 * group when CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE has been
607	 * detected. Perform partial public key processing.
608	 * Returns:
609	 *   	CSSMERR_TP_CERTIFICATE_CANT_OPERATE - can't complete partial key
610	 *		CSSMERR_TP_INVALID_CERT_AUTHORITY - sig verify failed with
611	 *			(supposedly) completed partial key
612	 */
613	CSSM_RETURN				verifyWithPartialKeys(
614		const TPClItemInfo	&subjectItem);		// Cert or CRL
615
616	Allocator				&mAlloc;
617	TPCertInfo				**mCertInfo;		// just an array of pointers
618	unsigned				mNumCerts;			// valid certs in certInfo
619	unsigned				mSizeofCertInfo;	// mallocd space in certInfo
620	TPGroupOwner			mWhoOwns;			// if TGO_Group, we delete certs
621												//    upon destruction
622};
623#endif	/* _TP_CERT_INFO_H_ */
624