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