]> git.saurik.com Git - apple/security.git/blob - AppleX509TP/TPCertInfo.h
Security-177.tar.gz
[apple/security.git] / AppleX509TP / TPCertInfo.h
1 /*
2 * Copyright (c) 2000-2001 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 * TPCertInfo.h - TP's private certificate info and cert group classes
21 *
22 * Written 10/23/2000 by Doug Mitchell.
23 */
24
25 #ifndef _TP_CERT_INFO_H_
26 #define _TP_CERT_INFO_H_
27
28 #include <Security/cssmtype.h>
29 #include <Security/utilities.h>
30 #include <Security/cssmalloc.h>
31 #include <Security/threading.h>
32 #include <Security/globalizer.h>
33
34 /* protects TP-wide access to time() and gmtime() */
35 extern ModuleNexus<Mutex> tpTimeLock;
36
37 /*
38 * Prototypes for functions which are isomorphic between certs and CRLs at the
39 * CL API.
40 */
41 typedef 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);
48 typedef CSSM_RETURN (*clAbortQueryFcn)(
49 CSSM_CL_HANDLE CLHandle,
50 CSSM_HANDLE ResultsHandle); // from clGetFirstFieldFcn
51 typedef CSSM_RETURN (*clCacheItemFcn)(
52 CSSM_CL_HANDLE CLHandle,
53 const CSSM_DATA *Item, // raw cert or CRL
54 CSSM_HANDLE_PTR CertHandle);
55 typedef CSSM_RETURN (*clAbortCacheFcn)(
56 CSSM_CL_HANDLE CLHandle,
57 CSSM_HANDLE ItemHandle); // from clCacheItemFcn
58 typedef 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
66 typedef 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
82 class 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 */
90 typedef 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 */
99 typedef 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 */
111 class TPClItemInfo
112 {
113 NOCOPY(TPClItemInfo)
114 public:
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 cert.
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 unsigned index() const { return mIndex; }
162 void index(unsigned dex) { mIndex = dex; }
163 bool isExpired() { return mIsExpired; }
164 bool isNotValidYet() { return mIsNotValidYet; }
165
166 /*
167 * Calculate validity (not before/after). Returns
168 * CSSMERR_{TP_CERT,APPLETP_CRL}_NOT_VALID_YET
169 * CSSMERR_xxx_T_EXPIRED
170 * CSSM_OK
171 * CSSMERR_xxx_INVALID_CERT_POINTER, other "bogus cert" errors
172 */
173 CSSM_RETURN calculateCurrent(
174 const char *verifyString = NULL);
175
176 private:
177
178 /* Tell CL to parse and cache the item */
179 CSSM_RETURN cacheItem(
180 const CSSM_DATA *itemData,
181 TPItemCopy copyItemData);
182
183
184 /* fetch not before/after fields */
185 void fetchNotBeforeAfter();
186
187 CSSM_CL_HANDLE mClHand; // always valid
188 CSSM_CSP_HANDLE mCspHand; // always valid
189 const TPClItemCalls &mClCalls;
190 bool mWeOwnTheData; // if true, we have to free
191 // mCertData
192 /* following four valid subsequent to cacheItem(), generally
193 * called by subclass's constructor */
194 CSSM_HANDLE mCacheHand;
195 CSSM_DATA_PTR mIssuerName;
196 CSSM_DATA *mItemData;
197 CSSM_ALGORITHMS mSigAlg;
198
199 /* calculated implicitly at construction */
200 struct tm mNotBefore;
201 struct tm mNotAfter;
202
203 /* also calculated at construction, but can be recalculated at will */
204 bool mIsExpired;
205 bool mIsNotValidYet;
206
207 unsigned mIndex;
208 };
209
210 /*
211 * Class representing one certificate. The raw cert data usually comes from
212 * a client (via incoming cert groups in CertGroupConstruct() and
213 * CertGroupVerify()); in this case, we don't own the raw data and
214 * don't copy or free it. Caller can optionally specify that we copy
215 * (and own and eventually free) the raw cert data. Currently this is
216 * only done when we find a cert in a DlDb. The constructor throws
217 * on any error (bad cert data); subsequent to successful construction, no CSSM
218 * errors are thrown and it's guaranteed that the cert is basically good and
219 * successfully cached in the CL, and that we have a locally cached subject
220 * and issuer name (in normalized encoded format).
221 */
222 class TPCertInfo : public TPClItemInfo
223 {
224 NOCOPY(TPCertInfo)
225 public:
226 /*
227 * No default constructor - this is the only way.
228 * This caches the cert and fetches subjectName and issuerName
229 * to ensure the incoming certData is well-constructed.
230 */
231 TPCertInfo(
232 CSSM_CL_HANDLE clHand,
233 CSSM_CSP_HANDLE cspHand,
234 const CSSM_DATA *certData,
235 TPItemCopy copyCertData,
236
237 const char *verifyTime); // may be NULL
238
239 /* frees mSubjectName, mIssuerName, mCacheHand via mClHand */
240 ~TPCertInfo();
241
242 /* accessors */
243 const CSSM_DATA *subjectName();
244
245 bool isSelfSigned();
246
247 bool isAnchor() { return mIsAnchor; }
248 void isAnchor(bool a) { mIsAnchor = a; }
249 bool isFromNet() { return mIsFromNet; }
250 void isFromNet(bool n) { mIsFromNet = n; };
251 unsigned numStatusCodes() { return mNumStatusCodes; }
252 CSSM_RETURN *statusCodes() { return mStatusCodes; }
253 CSSM_DL_DB_HANDLE dlDbHandle() { return mDlDbHandle; }
254 void dlDbHandle(CSSM_DL_DB_HANDLE hand)
255 { mDlDbHandle = hand; }
256 CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord()
257 { return mUniqueRecord; }
258 void uniqueRecord(CSSM_DB_UNIQUE_RECORD_PTR rec)
259 { mUniqueRecord = rec; }
260 CSSM_KEY_PTR pubKey() { return mPublicKey; }
261 bool used() { return mUsed; }
262 void used(bool u) { mUsed = u; }
263 bool isLeaf() { return mIsLeaf; }
264 void isLeaf(bool l) { mIsLeaf = l; }
265 /*
266 * Am I the issuer of the specified subject item? Returns true if so.
267 * Works for subject certs as well as CRLs.
268 */
269 bool isIssuerOf(
270 const TPClItemInfo &subject);
271
272 void addStatusCode(
273 CSSM_RETURN code);
274
275 /*
276 * Indicate whether this cert's public key is a CSSM_KEYATTR_PARTIAL
277 * key.
278 */
279 bool hasPartialKey();
280
281 private:
282 /* obtained from CL at construction */
283 CSSM_DATA_PTR mSubjectName; // always valid
284 CSSM_KEY_PTR mPublicKey;
285
286 /* maintained by caller, default at constructor 0/false */
287 bool mIsAnchor;
288 bool mIsFromDb;
289 bool mIsFromNet;
290 unsigned mNumStatusCodes;
291 CSSM_RETURN *mStatusCodes;
292 CSSM_DL_DB_HANDLE mDlDbHandle;
293 CSSM_DB_UNIQUE_RECORD_PTR mUniqueRecord;
294 bool mUsed; // e.g., used in current loop
295 bool mIsLeaf; // first in chain
296 TPRootState mIsRoot; // subject == issuer
297
298 void releaseResources();
299 };
300
301 /* Describe who owns the items in a TP{Cert,Crl}Group */
302 typedef enum {
303 TGO_None = 0, // not used
304 TGO_Group, // TP{Cert,Crl}Group owns the items
305 TGO_Caller // caller owns the items
306 } TPGroupOwner;
307
308 /*
309 * TP's private Cert Group class. Provides a list of TPCertInfo pointers,
310 * to which caller can append additional elements, access an element at
311 * an arbitrary position, and remover an element at an arbitrrary position.
312 */
313 class TPCertGroup
314 {
315 NOCOPY(TPCertGroup)
316 public:
317 /*
318 * No default constructor.
319 * This one creates an empty TPCertGroup.
320 */
321 TPCertGroup(
322 CssmAllocator &alloc,
323 TPGroupOwner whoOwns); // if TGO_Group, we delete
324
325 /*
326 * Construct from unordered, untrusted CSSM_CERTGROUP. Resulting
327 * TPCertInfos are more or less in the same order as the incoming
328 * certs, though incoming certs are discarded if they don't parse.
329 * No verification of any sort is performed.
330 */
331 TPCertGroup(
332 const CSSM_CERTGROUP &CertGroupFrag,
333 CSSM_CL_HANDLE clHand,
334 CSSM_CSP_HANDLE cspHand,
335 CssmAllocator &alloc,
336 const char *verifyString, // may be NULL
337 bool firstCertMustBeValid,
338 TPGroupOwner whoOwns);
339
340 /*
341 * Deletes all TPCertInfo's.
342 */
343 ~TPCertGroup();
344
345 /*
346 * Construct ordered, verified cert chain from a variety of inputs.
347 * Time validity is ignored and needs to be checked by caller (it's
348 * stored in each TPCertInfo we add to ourself during construction).
349 * The only error returned is CSSMERR_APPLETP_INVALID_ROOT, meaning
350 * we verified back to a supposed root cert which did not in fact
351 * self-verify. Other interesting status is returned via the
352 * verifiedToRoot and verifiedToAnchor flags.
353 *
354 * NOTE: is it the caller's responsibility to call setAllUnused()
355 * for both incoming cert groups (inCertGroup and gatheredCerts).
356 * We don't do that here because we may call ourself recursively.
357 *
358 * subjectItem may or may not be in the cert group (currently, it
359 * is in the group if it's a cert and it's not if it's a CRL, but
360 * we don't rely on that).
361 */
362 CSSM_RETURN buildCertGroup(
363 const TPClItemInfo &subjectItem, // Cert or CRL
364 TPCertGroup *inCertGroup, // optional
365 const CSSM_DL_DB_LIST *dbList, // optional
366 CSSM_CL_HANDLE clHand,
367 CSSM_CSP_HANDLE cspHand,
368 const char *verifyString, // optional, for establishing
369 // validity of new TPCertInfos
370 /* trusted anchors, optional */
371 /* FIXME - maybe this should be a TPCertGroup */
372 uint32 numAnchorCerts,
373 const CSSM_DATA *anchorCerts,
374
375 /*
376 * Certs to be freed by caller (i.e., TPCertInfo which we allocate
377 * as a result of using a cert from anchorCerts or dbList) are added
378 * to this group.
379 */
380 TPCertGroup &certsToBeFreed,
381
382 /*
383 * Other certificates gathered during the course of this operation,
384 * currently consisting of certs fetched from DBs and from the net.
385 * This is not used when called by AppleTPSession::CertGroupConstructPriv;
386 * it's an optimization for the case when we're building a cert group
387 * for TPCrlInfo::verifyWithContext - we avoid re-fetching certs from
388 * the net which are needed to verify both the subject cert and a CRL.
389 */
390 TPCertGroup *gatheredCerts,
391
392 /*
393 * Indicates that subjectItem is the last element in this cert group.
394 * If true, that cert will be tested for "root-ness", including
395 * -- subject/issuer compare
396 * -- signature self-verify
397 * -- anchor compare
398 */
399 CSSM_BOOL subjectIsInGroup,
400
401 /* currently, only CSSM_TP_ACTION_FETCH_CERT_FROM_NET is
402 * interesting */
403 CSSM_APPLE_TP_ACTION_FLAGS actionFlags,
404
405 /* returned */
406 CSSM_BOOL &verifiedToRoot, // end of chain self-verifies
407 CSSM_BOOL &verifiedToAnchor); // end of chain in anchors
408
409 /* add/remove/access TPTCertInfo's. */
410 void appendCert(
411 TPCertInfo *certInfo); // appends to end of mCertInfo
412 TPCertInfo *certAtIndex(
413 unsigned index);
414 TPCertInfo *removeCertAtIndex(
415 unsigned index); // doesn't delete the cert, just
416 // removes it from our list
417 unsigned numCerts() const // how many do we have?
418 { return mNumCerts; }
419
420 /*
421 * Convenience accessors for first and last cert, only valid when we have
422 * at least one cert.
423 */
424 TPCertInfo *firstCert();
425 TPCertInfo *lastCert();
426
427 /* build a CSSM_CERTGROUP corresponding with our mCertInfo */
428 CSSM_CERTGROUP_PTR buildCssmCertGroup();
429
430 /* build a CSSM_TP_APPLE_EVIDENCE_INFO array corresponding with our
431 * mCertInfo */
432 CSSM_TP_APPLE_EVIDENCE_INFO *buildCssmEvidenceInfo();
433
434 /* Given a status for basic construction of a cert group and a status
435 * of (optional) policy verification, plus the implicit notBefore/notAfter
436 * status in the certs, calculate a global return code. This just
437 * encapsulates a policy for CertGroupeConstruct and CertGroupVerify.
438 */
439 CSSM_RETURN getReturnCode(
440 CSSM_RETURN constructStatus,
441 CSSM_BOOL allowExpired,
442 CSSM_BOOL allowExpiredRoot,
443 CSSM_RETURN policyStatus = CSSM_OK);
444
445 CssmAllocator
446 &alloc() {return mAlloc; }
447
448 /* set all TPCertInfo.mUsed flags false */
449 void setAllUnused();
450
451 private:
452
453 /*
454 * Search unused incoming certs to find an issuer of specified
455 * cert or CRL.
456 * WARNING this assumes a valied "used" state for all certs
457 * in this group.
458 * If partialIssuerKey is true on return, caller must re-verify signature
459 * of subject later when sufficient info is available.
460 */
461 TPCertInfo *findIssuerForCertOrCrl(
462 const TPClItemInfo &subject,
463 bool &partialIssuerKey);
464
465 /*
466 * Called from buildCertGroup as final processing of a constructed
467 * group when CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE has been
468 * detected. Perform partial public key processing.
469 * Returns:
470 * CSSMERR_TP_CERTIFICATE_CANT_OPERATE - can't complete partial key
471 * CSSMERR_TP_INVALID_CERT_AUTHORITY - sig verify failed with
472 * (supposedly) completed partial key
473 */
474 CSSM_RETURN verifyWithPartialKeys(
475 const TPClItemInfo &subjectItem); // Cert or CRL
476
477 CssmAllocator &mAlloc;
478 TPCertInfo **mCertInfo; // just an array of pointers
479 unsigned mNumCerts; // valid certs in certInfo
480 unsigned mSizeofCertInfo; // mallocd space in certInfo
481 TPGroupOwner mWhoOwns; // if TGO_Group, we delete certs
482 // upon destruction
483 };
484 #endif /* _TP_CERT_INFO_H_ */