/*
* Copyright (c) 2000-2011 Apple Inc. All Rights Reserved.
- *
+ *
* The contents of this file constitute Original Code as defined in and are
* subject to the Apple Public Source License Version 1.2 (the 'License').
* You may not use this file except in compliance with the License. Please obtain
* a copy of the License at http://www.apple.com/publicsource and read it before
* using this file.
- *
+ *
* This Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
* OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
/*
* TPCertInfo.h - TP's private certificate info and cert group classes
*/
-
+
#ifndef _TP_CERT_INFO_H_
#define _TP_CERT_INFO_H_
/* protects TP-wide access to time() and gmtime() */
extern ModuleNexus<Mutex> tpTimeLock;
-/*
+/*
* Prototypes for functions which are isomorphic between certs and CRLs at the
* CL API.
*/
const CSSM_OID *notAfterOid;
/* CL/cert specific errors */
CSSM_RETURN invalidItemRtn; // CSSMERR_TP_INVALID_{CERT,CRL}_POINTER
- CSSM_RETURN expiredRtn;
+ CSSM_RETURN expiredRtn;
CSSM_RETURN notValidYetRtn;
} TPClItemCalls;
class TPCertInfo;
/*
- * On construction of a TPClItemInfo, specifies whether or not to
+ * On construction of a TPClItemInfo, specifies whether or not to
* copy the incoming item data (in which we free it upon destruction)
- * or to use caller's data as is (in which case the caller maintains
+ * or to use caller's data as is (in which case the caller maintains
* the data).
*/
typedef enum {
TIC_NoCopy, // caller maintains
TIC_CopyData // we copy and free
} TPItemCopy;
-
+
/*
* State of a cert's mIsRoot flag. We do signature self-verify on demand.
*/
} TPRootState;
/*
- * Base class for TPCertInfo and TPCrlInfo. Encapsulates caching of
+ * Base class for TPCertInfo and TPCrlInfo. Encapsulates caching of
* an entity within the CL, field lookup/free, and signature verify,
* all of which use similar functions at the CL API.
*/
CSSM_CSP_HANDLE cspHand,
const TPClItemCalls &clCalls,
const CSSM_DATA *itemData,
- TPItemCopy copyItemData,
+ TPItemCopy copyItemData,
const char *verifyTime); // may be NULL
-
+
~TPClItemInfo();
void releaseResources();
-
- /*
+
+ /*
* Fetch arbitrary field from cached item.
* Only should be used when caller is sure there is either zero or one
* of the requested fields present in the cert.
CSSM_DATA_PTR *fieldData); // mallocd by CL and RETURNED
/* free arbitrary field obtained from fetchField() */
- CSSM_RETURN freeField(
+ CSSM_RETURN freeField(
const CSSM_OID *fieldOid,
CSSM_DATA_PTR fieldData);
- /*
+ /*
* Verify with an issuer cert - works on certs and CRLs.
* Issuer/subject name match already performed by caller.
* May return CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE without
- * performing a signature op, in which case it is the caller's
- * resposibility to complete this operation later when
+ * performing a signature op, in which case it is the caller's
+ * resposibility to complete this operation later when
* sufficient information is available.
*
* Optional paramCert is used to provide parameters when issuer
CSSM_CSP_HANDLE cspHand() const { return mCspHand; }
CSSM_HANDLE cacheHand() const { return mCacheHand; }
const CSSM_DATA *itemData() const { return mItemData; }
- const CSSM_DATA *issuerName() const { return mIssuerName; };
- unsigned index() const { return mIndex; }
+ const CSSM_DATA *issuerName() const { return mIssuerName; };
+ const CSSM_DATA *subjectKeyID() const { return mSubjectKeyID; };
+ const CSSM_DATA *authorityKeyID() const { return mAuthorityKeyID; };
+ unsigned index() const { return mIndex; }
void index(unsigned dex) { mIndex = dex; }
bool isExpired() { return mIsExpired; }
bool isNotValidYet() { return mIsNotValidYet; }
-
- /*
- * Calculate validity (not before/after). Returns
+
+ /*
+ * Calculate validity (not before/after). Returns
* CSSMERR_{TP_CERT,APPLETP_CRL}_NOT_VALID_YET
* CSSMERR_xxx_T_EXPIRED
* CSSM_OK
*/
CSSM_RETURN calculateCurrent(
const char *verifyString = NULL);
-
+
private:
/* Tell CL to parse and cache the item */
CSSM_RETURN cacheItem(
const CSSM_DATA *itemData,
- TPItemCopy copyItemData);
-
-
+ TPItemCopy copyItemData);
+
+
/* fetch not before/after fields */
void fetchNotBeforeAfter();
-
+
CSSM_CL_HANDLE mClHand; // always valid
CSSM_CSP_HANDLE mCspHand; // always valid
const TPClItemCalls &mClCalls;
- bool mWeOwnTheData; // if true, we have to free
+ bool mWeOwnTheData; // if true, we have to free
// mCertData
- /* following four valid subsequent to cacheItem(), generally
+ /* following are valid subsequent to cacheItem(), generally
* called by subclass's constructor */
- CSSM_HANDLE mCacheHand;
+ CSSM_HANDLE mCacheHand;
CSSM_DATA_PTR mIssuerName;
- CSSM_DATA *mItemData;
+ CSSM_DATA_PTR mSubjectKeyID;
+ CSSM_DATA_PTR mAuthorityKeyID;
+ CSSM_DATA_PTR mItemData;
CSSM_ALGORITHMS mSigAlg;
/* calculated implicitly at construction */
CFDateRef mNotBefore;
CFDateRef mNotAfter;
-
+
/* also calculated at construction, but can be recalculated at will */
bool mIsExpired;
bool mIsNotValidYet;
-
+
unsigned mIndex;
};
/*
* Class representing one certificate. The raw cert data usually comes from
- * a client (via incoming cert groups in CertGroupConstruct() and
- * CertGroupVerify()); in this case, we don't own the raw data and
- * don't copy or free it. Caller can optionally specify that we copy
- * (and own and eventually free) the raw cert data. Currently this is
- * done when we find a cert in a DlDb or from the net. The constructor throws
- * on any error (bad cert data); subsequent to successful construction, no CSSM
- * errors are thrown and it's guaranteed that the cert is basically good and
- * successfully cached in the CL, and that we have a locally cached subject
- * and issuer name (in normalized encoded format).
- */
+ * a client (via incoming cert groups in CertGroupConstruct() and
+ * CertGroupVerify()); in this case, we don't own the raw data and
+ * don't copy or free it. Caller can optionally specify that we copy
+ * (and own and eventually free) the raw cert data. Currently this is
+ * done when we find a cert in a DlDb or from the net. The constructor throws
+ * on any error (bad cert data); subsequent to successful construction, no CSSM
+ * errors are thrown and it's guaranteed that the cert is basically good and
+ * successfully cached in the CL, and that we have a locally cached subject
+ * and issuer name (in normalized encoded format).
+ */
class TPCertInfo : public TPClItemInfo
{
NOCOPY(TPCertInfo)
public:
- /*
+ /*
* No default constructor - this is the only way.
* This caches the cert and fetches subjectName and issuerName
* to ensure the incoming certData is well-constructed.
CSSM_CL_HANDLE clHand,
CSSM_CSP_HANDLE cspHand,
const CSSM_DATA *certData,
- TPItemCopy copyCertData,
-
+ TPItemCopy copyCertData,
+
const char *verifyTime); // may be NULL
-
+
/* frees mSubjectName, mIssuerName, mCacheHand via mClHand */
~TPCertInfo();
-
+
/* accessors */
const CSSM_DATA *subjectName();
SecTrustSettingsDomain trustSettingsDomain() { return mTrustSettingsDomain; }
SecTrustSettingsResult trustSettingsResult() { return mTrustSettingsResult; }
bool ignoredError() { return mIgnoredError; }
-
+
/* true means "verification terminated due to user trust setting" */
bool trustSettingsFound();
/*
* Am I the issuer of the specified subject item? Returns true if so.
- * Works for subject certs as well as CRLs.
+ * Works for subject certs as well as CRLs.
*/
bool isIssuerOf(
const TPClItemInfo &subject);
-
- /*
+
+ /*
+ * Does my subject key id match the authority key id of the specified
+ * subject item? Returns true if so.
+ */
+ bool isAuthorityKeyOf(
+ const TPClItemInfo &subject);
+
+ /*
* Add error status to mStatusCodes[]. Check to see if the
* added status is allowed per mAllowedErrs; if not return true.
* Returns false of the status *is* an allowed error.
bool hasStatusCode(
CSSM_RETURN code);
- /*
+ /*
* See if the specified error status is allowed (return false) or
* fatal (return true) per mAllowedErrs[].
*/
bool isStatusFatal(
CSSM_RETURN code);
-
- /*
+
+ /*
* Indicate whether this cert's public key is a CSSM_KEYATTR_PARTIAL
* key.
*/
/*
* Flag to indicate that at least one revocation policy has successfully
- * achieved a positive verification of the cert.
+ * achieved a positive verification of the cert.
*/
bool revokeCheckGood() { return mRevCheckGood; }
void revokeCheckGood(bool b) { mRevCheckGood = b; }
-
+
/*
* Flag to indicate "I have successfully been checked for revocation
- * status and the per-policy action data indicates that I need not be
- * checked again by any other revocation policy". E.g.,
+ * status and the per-policy action data indicates that I need not be
+ * checked again by any other revocation policy". E.g.,
* CSSM_TP_ACTION_CRL_SUFFICIENT is set and CRL revocation checking
- * was successful for this cert.
+ * was successful for this cert.
*/
bool revokeCheckComplete() { return mRevCheckComplete; }
void revokeCheckComplete(bool b) { mRevCheckComplete = b; }
-
+
/*
* Evaluate user trust; returns true if positive match found - i.e.,
- * cert chain construction is done.
+ * cert chain construction is done.
* The foundEntry return value indicates that *some* entry was found for
- * the cert, regardless of the trust setting evaluation.
+ * the cert, regardless of the trust setting evaluation.
*/
OSStatus evaluateTrustSettings(
const CSSM_OID &policyOid,
SecTrustSettingsKeyUsage keyUse, // optional
bool *foundMatchingEntry,
bool *foundEntry); // RETURNED
-
+
bool hasEmptySubjectName();
-
+
/* Free mUniqueRecord if it exists */
void freeUniqueRecord();
-
+
private:
/* obtained from CL at construction */
CSSM_DATA_PTR mSubjectName; // always valid
CSSM_DATA_PTR mPublicKeyData; // mPublicKey obtained from this field
CSSM_KEY_PTR mPublicKey;
-
+
/* maintained by caller, default at constructor 0/false */
bool mIsAnchor;
bool mIsFromInputCerts;
CSSM_RETURN *mStatusCodes;
CSSM_DL_DB_HANDLE mDlDbHandle;
CSSM_DB_UNIQUE_RECORD_PTR mUniqueRecord;
- bool mUsed; // e.g., used in current loop
+ bool mUsed; // e.g., used in current loop
bool mIsLeaf; // first in chain
TPRootState mIsRoot; // subject == issuer
bool mRevCheckGood; // >= 1 revoke check good
bool mRevCheckComplete; // no more revoke checking needed
-
- /*
+
+ /*
* When true, we've already called SecTrustSettingsEvaluateCert,
* and the cached results are in following member vars.
*/
SecTrustSettingsResult mTrustSettingsResult;
bool mTrustSettingsFoundAnyEntry;
bool mTrustSettingsFoundMatchingEntry;
-
+
/* allowed errors obtained from SecTrustSettingsEvaluateCert() */
CSSM_RETURN *mAllowedErrs;
uint32 mNumAllowedErrs;
-
+
/* we actually ignored one of mAllowedErrors[] */
bool mIgnoredError;
/* key usage for which mTrustSettingsResult was evaluated */
SecTrustSettingsKeyUsage mTrustSettingsKeyUsage;
-
+
/* for SecTrustSettingsEvaluateCert() */
- CFStringRef mCertHashStr;
-
+ CFStringRef mCertHashStr;
+
void releaseResources();
};
TPCertGroup(
Allocator &alloc,
TPGroupOwner whoOwns); // if TGO_Group, we delete
-
+
/*
* Construct from unordered, untrusted CSSM_CERTGROUP. Resulting
* TPCertInfos are more or less in the same order as the incoming
* certs, though incoming certs are discarded if they don't parse.
- * No verification of any sort is performed.
+ * No verification of any sort is performed.
*/
TPCertGroup(
const CSSM_CERTGROUP &CertGroupFrag,
Allocator &alloc,
const char *verifyString, // may be NULL
bool firstCertMustBeValid,
- TPGroupOwner whoOwns);
-
+ TPGroupOwner whoOwns);
+
/*
* Deletes all TPCertInfo's.
*/
~TPCertGroup();
-
+
/*
- * Construct ordered, verified cert chain from a variety of inputs.
+ * Construct ordered, verified cert chain from a variety of inputs.
* Time validity is ignored and needs to be checked by caller (it's
* stored in each TPCertInfo we add to ourself during construction).
- * The only error returned is CSSMERR_APPLETP_INVALID_ROOT, meaning
+ * The only error returned is CSSMERR_APPLETP_INVALID_ROOT, meaning
* we verified back to a supposed root cert which did not in fact
* self-verify. Other interesting status is returned via the
- * verifiedToRoot and verifiedToAnchor flags.
+ * verifiedToRoot and verifiedToAnchor flags.
*
- * NOTE: is it the caller's responsibility to call setAllUnused()
- * for both incoming cert groups (inCertGroup and gatheredCerts).
- * We don't do that here because we may call ourself recursively.
+ * NOTE: is it the caller's responsibility to call setAllUnused()
+ * for both incoming cert groups (inCertGroup and gatheredCerts).
+ * We don't do that here because we may call ourself recursively.
*
* subjectItem may or may not be in the cert group (currently, it
- * is in the group if it's a cert and it's not if it's a CRL, but
- * we don't rely on that).
+ * is in the group if it's a cert and it's not if it's a CRL, but
+ * we don't rely on that).
*/
CSSM_RETURN buildCertGroup(
const TPClItemInfo &subjectItem, // Cert or CRL
/* FIXME - maybe this should be a TPCertGroup */
uint32 numAnchorCerts,
const CSSM_DATA *anchorCerts,
-
- /*
+
+ /*
* 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,
-
+
/*
* Other certificates gathered during the course of this operation,
* currently consisting of certs fetched from DBs and from the net.
* the net which are needed to verify both the subject cert and a CRL.
*/
TPCertGroup *gatheredCerts,
-
+
/*
* Indicates that subjectItem is a cert in this cert group.
- * If true, that cert will be tested for "root-ness", including
+ * If true, that cert will be tested for "root-ness", including
* -- subject/issuer compare
* -- signature self-verify
* -- anchor compare
*/
CSSM_BOOL subjectIsInGroup,
-
- /* currently, only CSSM_TP_ACTION_FETCH_CERT_FROM_NET and
+
+ /* currently, only CSSM_TP_ACTION_FETCH_CERT_FROM_NET and
* CSSM_TP_ACTION_TRUST_SETTINGS are interesting */
CSSM_APPLE_TP_ACTION_FLAGS actionFlags,
-
+
/* CSSM_TP_ACTION_TRUST_SETTINGS parameters */
const CSSM_OID *policyOid,
const char *policyStr,
CSSM_BOOL &verifiedToRoot, // end of chain self-verifies
CSSM_BOOL &verifiedToAnchor, // end of chain in anchors
CSSM_BOOL &verifiedViaTrustSettings); // chain ends per User Trust setting
-
+
/* add/remove/access TPTCertInfo's. */
void appendCert(
TPCertInfo *certInfo); // appends to end of mCertInfo
TPCertInfo *certAtIndex(
unsigned index);
TPCertInfo *removeCertAtIndex(
- unsigned index); // doesn't delete the cert, just
+ unsigned index); // doesn't delete the cert, just
// removes it from our list
- unsigned numCerts() const // how many do we have?
+ unsigned numCerts() const // how many do we have?
{ return mNumCerts; }
-
- /*
+
+ /*
* Convenience accessors for first and last cert, only valid when we have
* at least one cert.
*/
TPCertInfo *firstCert();
TPCertInfo *lastCert();
-
+
/* build a CSSM_CERTGROUP corresponding with our mCertInfo */
CSSM_CERTGROUP_PTR buildCssmCertGroup();
/* build a CSSM_TP_APPLE_EVIDENCE_INFO array corresponding with our
* mCertInfo */
CSSM_TP_APPLE_EVIDENCE_INFO *buildCssmEvidenceInfo();
-
+
/* Given a status for basic construction of a cert group and a status
* of (optional) policy verification, plus the implicit notBefore/notAfter
- * status in the certs, calculate a global return code. This just
+ * status in the certs, calculate a global return code. This just
* encapsulates a policy for CertGroupConstruct and CertGroupVerify.
*/
CSSM_RETURN getReturnCode(
CSSM_RETURN constructStatus,
CSSM_RETURN policyStatus,
CSSM_APPLE_TP_ACTION_FLAGS actionFlags);
-
+
Allocator
&alloc() {return mAlloc; }
-
+
/* set all TPCertInfo.mUsed flags false */
void setAllUnused();
/* free records obtained from DBs */
void freeDbRecords();
- /*
+ /*
* See if the specified error status is allowed (return true) or
* fatal (return false) per each cert's mAllowedErrs[]. Returns
- * true if any cert returns false for its isStatusFatal() call.
+ * true if any cert returns false for its isStatusFatal() call.
* The list of errors which can apply to cert-chain-wide allowedErrors
* is right here; if the incoming error is not in that list, we
* return false. If the incoming error code is CSSM_OK we return
- * true as a convenience for our callers.
+ * true as a convenience for our callers.
*/
bool isAllowedError(
CSSM_RETURN code);
-
- /*
+
+ /*
* Determine if we already have the specified cert in this group.
*/
bool isInGroup(TPCertInfo &certInfo);
* Caller is responsible for freeing the data.
*/
void encodeIssuers(CSSM_DATA &issuers);
-
+
private:
-
- /*
- * Search unused incoming certs to find an issuer of specified
+
+ /*
+ * Search unused incoming certs to find an issuer of specified
* cert or CRL.
- * WARNING this assumes a valied "used" state for all certs
+ * WARNING this assumes a valied "used" state for all certs
* in this group.
* If partialIssuerKey is true on return, caller must re-verify signature
- * of subject later when sufficient info is available.
- */
+ * of subject later when sufficient info is available.
+ */
TPCertInfo *findIssuerForCertOrCrl(
const TPClItemInfo &subject,
bool &partialIssuerKey);
- /*
+ /*
* Called from buildCertGroup as final processing of a constructed
* group when CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE has been
* detected. Perform partial public key processing.
* Returns:
* CSSMERR_TP_CERTIFICATE_CANT_OPERATE - can't complete partial key
- * CSSMERR_TP_INVALID_CERT_AUTHORITY - sig verify failed with
+ * CSSMERR_TP_INVALID_CERT_AUTHORITY - sig verify failed with
* (supposedly) completed partial key
*/
CSSM_RETURN verifyWithPartialKeys(
const TPClItemInfo &subjectItem); // Cert or CRL
-
+
Allocator &mAlloc;
TPCertInfo **mCertInfo; // just an array of pointers
unsigned mNumCerts; // valid certs in certInfo
unsigned mSizeofCertInfo; // mallocd space in certInfo
- TPGroupOwner mWhoOwns; // if TGO_Group, we delete certs
+ TPGroupOwner mWhoOwns; // if TGO_Group, we delete certs
// upon destruction
};
#endif /* _TP_CERT_INFO_H_ */