1/*
2 * Copyright (c) 2002 Apple Computer, 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 * TPCrlInfo.h - TP's private CRL and CRL group classes
21 *
22 * Written 9/25/2001 by Doug Mitchell.
23 */
24
25#ifndef	_TP_CRL_INFO_H_
26#define _TP_CRL_INFO_H_
27
28#include <Security/cssmtype.h>
29#include <security_utilities/alloc.h>
30#include <security_utilities/threading.h>
31#include <security_utilities/globalizer.h>
32#include "TPCertInfo.h"
33#include "tpCrlVerify.h"
34
35/*
36 * Verification state of a TPCrlInfo. Verification refers to the process
37 * of cert chain validation from the CRL to a trusted root. Since this
38 * is a rather heavyweight operation, this is done on demand, when a given
39 * CRL is "believed to be" the appropriate one for a given cert. It
40 * is separate from not before/after verification, which is performed
41 * on the fly as needed.
42 */
43typedef enum {
44	CVS_Unknown,		// initial default state
45	CVS_Good,			// known good
46	CVS_Bad				// known bad
47} TPCrlVerifyState;
48
49/*
50 * Indicates where a particular CRL came from. Currently only used
51 * in the tpCrlVerify module.
52 */
53typedef enum {
54	CFW_Nowhere,		// default, never returned
55	CFW_InGroup,		// from incoming TPCrlGroup
56	CFW_DlDb,			// verifyContext.dbList
57	CFW_LocalCache,		// tpGlobalCrlCache
58	CFW_Net,			// tpFetchCrlFromNet
59	/* probably others */
60} TPCrlFromWhere;
61
62
63/*
64 * Class representing one CRL. The raw CRL data usually comes from
65 * a client (via incoming CSSM_TP_VERIFY_CONTEXT.Crls); in this case, we
66 * don't own the raw data and don't copy or free it. Caller can
67 * optionally specify that we copy (and own and eventually free) the raw cert data.
68 * Currently this is only done when we find a CRL in a DlDb. The constructor throws
69 * on any error (bad CRL data); subsequent to successful construction, no CSSM
70 * errors are thrown and it's guaranteed that the CRL is basically readable and
71 * successfully cached in the CL, and that we have a locally cached
72 * CSSM_X509_SIGNED_CRL and issuer name (in normalized encoded format).
73 */
74class TPCrlInfo : public TPClItemInfo
75{
76	NOCOPY(TPCrlInfo)
77public:
78	/*
79	 * No default constructor - this is the only way.
80	 */
81	TPCrlInfo(
82		CSSM_CL_HANDLE		clHand,
83		CSSM_CSP_HANDLE		cspHand,
84		const CSSM_DATA		*crlData,
85		TPItemCopy			copyCrlData,
86		const char 			*verifyTime);	// NULL ==> time = right now
87
88	/* frees mIssuerName, mCacheHand, mX509Crl via mClHand */
89	~TPCrlInfo();
90
91	/*
92	 * The heavyweight "perform full verification" op.
93	 * If doCrlVerify is true, we'll do an eventually recursive
94	 * CRL verification test on the cert group we construct
95	 * here to verify the CRL in question. This recursive
96	 * verify is also done if the CRL is an indirect CRL.
97	 * Currently, the doCrlVerifyFlag will be set false in the
98	 * normal case of verifying a cert chain; in that case the
99	 * various certs needed to verify the CRL are assumed to
100	 * be a subset of the cert chain being verified, and CRL
101	 * verification of that cert chain is being performed
102	 * elsewhere. The caller would set doCrlVerify true when
103	 * the top-level op is simply a CRL verify.
104	 */
105	CSSM_RETURN verifyWithContext(
106		TPVerifyContext		&tpVerifyContext,
107		TPCertInfo			*forCert,			// optional
108		bool				doCrlVerify = false);
109
110	/*
111 	 * Wrapper for verifyWithContext for use when evaluating a CRL
112  	 * "now" instead of at the time in TPVerifyContext.verifyTime.
113	 */
114	CSSM_RETURN verifyWithContextNow(
115		TPVerifyContext		&tpVerifyContext,
116		TPCertInfo			*forCert,			// optional
117		bool				doCrlVerify = false);
118
119	/*
120	 * Do I have the same issuer as the specified subject cert?
121	 * Returns true if so.
122	 */
123	bool hasSameIssuer(
124		const TPCertInfo		&subject);
125
126	/*
127	 * Determine if specified cert has been revoked as of the
128	 * provided time; a NULL timestring indicates "now".
129	 * Assumes that the current CRL has been fully verified.
130	 */
131	CSSM_RETURN isCertRevoked(
132		TPCertInfo 				&subjectCert,
133		CSSM_TIMESTRING 		verifyTime);
134
135	/* accessors */
136	const CSSM_X509_SIGNED_CRL *x509Crl()		{ return mX509Crl; }
137	TPCrlVerifyState			verifyState() 	{ return mVerifyState; }
138
139	const CSSM_DATA				*uri()			{ return &mUri; }
140	void 						uri(const CSSM_DATA &uri);
141
142	/*
143	 * Ref count info maintained by caller (currently only in
144	 * tpCrlVfy.cpp's global cache module).
145	 */
146	int 					mRefCount;
147
148	/* used only by tpCrlVerify */
149	TPCrlFromWhere			mFromWhere;
150
151
152private:
153	CSSM_X509_SIGNED_CRL	*mX509Crl;
154	CSSM_DATA_PTR			mCrlFieldToFree;
155	TPCrlVerifyState		mVerifyState;
156	CSSM_RETURN				mVerifyError;		// only if mVerifyState = CVS_Bad
157	CSSM_DATA				mUri;				// if fetched from net
158
159	void releaseResources();
160	CSSM_RETURN parseExtensions(
161		TPVerifyContext				&tpVerifyContext,
162		bool						isPerEntry,
163		uint32						entryIndex,		// if isPerEntry
164		const CSSM_X509_EXTENSIONS	&extens,
165		TPCertInfo					*forCert,		// optional
166		bool						&isIndirectCrl);// RETURNED
167
168};
169
170/*
171 * TP's private CRL Group class.
172 */
173class TPCrlGroup
174{
175	NOCOPY(TPCrlGroup)
176public:
177	/* construct empty CRL group */
178	TPCrlGroup(
179		Allocator				&alloc,
180		TPGroupOwner			whoOwns);		// if TGO_Group, we delete
181
182	/*
183	 * Construct from unordered, untrusted CSSM_CRLGROUP. Resulting
184	 * TPCrlInfos are more or less in the same order as the incoming
185	 * CRLs, though incoming CRLs are discarded if they don't parse.
186	 * No verification of any sort is performed.
187	 */
188	TPCrlGroup(
189		const CSSM_CRLGROUP 	*cssmCrlGroup,		// optional
190		CSSM_CL_HANDLE 			clHand,
191		CSSM_CSP_HANDLE 		cspHand,
192		Allocator				&alloc,
193		const char				*cssmTimeStr,		// may be NULL
194		TPGroupOwner			whoOwns);
195
196	/*
197	 * Deletes all TPCrlInfo's.
198	 */
199	~TPCrlGroup();
200
201	/* add/remove/access TPCrlInfo's. */
202	void appendCrl(
203		TPCrlInfo			&crlInfo);			// appends to end of mCertInfo
204	TPCrlInfo *crlAtIndex(
205		unsigned			index);
206	TPCrlInfo &removeCrlAtIndex(
207		unsigned			index);				// doesn't delete the cert, just
208												// removes it from our list
209	void removeCrl(
210		TPCrlInfo			&crlInfo);			// ditto
211
212	/*
213	 * Convenience accessors for first and last CRL, only valid when we have
214	 * at least one cert.
215	 */
216	TPCrlInfo *firstCrl();
217	TPCrlInfo *lastCrl();
218
219	/*
220	 * Find a CRL whose issuer matches specified subject cert.
221	 * Returned CRL has not necessarily been verified.
222	 */
223	TPCrlInfo *findCrlForCert(
224		TPCertInfo			&subject);
225
226	Allocator &alloc() 							{ return mAlloc; }
227	unsigned numCrls()								{ return mNumCrls; }
228
229private:
230	Allocator				&mAlloc;
231	TPCrlInfo				**mCrlInfo;			// just an array of pointers
232	unsigned				mNumCrls;			// valid certs in certInfo
233	unsigned				mSizeofCrlInfo;		// mallocd space in certInfo
234	TPGroupOwner			mWhoOwns;			// if TGO_Group, we delete CRLs
235												//    upon destruction
236};
237#endif	/* _TP_CRL_INFO_H_ */
238
239