|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: chain.h
//
// Contents: Certificate Chaining Infrastructure
//
// History: 13-Jan-98 kirtd Created
//
//----------------------------------------------------------------------------
#if !defined(__CHAIN_H__)
#define __CHAIN_H__
#include <windows.h>
#include <wincrypt.h>
#include <winchain.h>
#include <lrucache.h>
#include <md5.h>
// All internal chain hashes are MD5 (16 bytes)
#define CHAINHASHLEN MD5DIGESTLEN
// Limitation: no support for AES hash algorithm
#define CHAIN_MAX_SIG_HASH_LEN 20
#define CHAIN_MIN_SIG_HASH_LEN 16
//
// Certificate and Path Object Forward class declarations
//
class CCertObject; class CCertIssuerList; class CCertObjectCache; class CCertChainEngine; class CChainPathObject;
//
// Certificate and Path Object Class pointer typedefs
//
typedef CCertObject* PCCERTOBJECT; typedef CCertIssuerList* PCCERTISSUERLIST; typedef CCertObjectCache* PCCERTOBJECTCACHE; typedef CCertChainEngine* PCCERTCHAINENGINE; typedef CChainPathObject* PCCHAINPATHOBJECT;
//
// SSCTL Forward class declarations
//
class CSSCtlObject; class CSSCtlObjectCache;
//
// SSCTL Class pointer typedefs
//
typedef class CSSCtlObject* PCSSCTLOBJECT; typedef class CSSCtlObjectCache* PCSSCTLOBJECTCACHE;
//
// Call Context Forward class declarations
//
class CChainCallContext;
//
// Call Context class pointer typedefs
//
typedef CChainCallContext* PCCHAINCALLCONTEXT;
//
// Certificate Object Identifier. This is a unique identifier for a certificate
// object and is the MD5 hash of the issuer and serial no.
//
typedef BYTE CERT_OBJECT_IDENTIFIER[ CHAINHASHLEN ];
//
// CCertObject types
//
#define CERT_END_OBJECT_TYPE 1
#define CERT_CACHED_END_OBJECT_TYPE 2
#define CERT_CACHED_ISSUER_OBJECT_TYPE 3
#define CERT_EXTERNAL_ISSUER_OBJECT_TYPE 4
//
// Issuer match types
//
#define CERT_EXACT_ISSUER_MATCH_TYPE 1
#define CERT_KEYID_ISSUER_MATCH_TYPE 2
#define CERT_NAME_ISSUER_MATCH_TYPE 3
#define CERT_PUBKEY_ISSUER_MATCH_TYPE 4
//
// Issuer match flags
//
#define CERT_MATCH_TYPE_TO_FLAG(MatchType) (1 << (MatchType - 1))
#define CERT_EXACT_ISSUER_MATCH_FLAG \
CERT_MATCH_TYPE_TO_FLAG(CERT_EXACT_ISSUER_MATCH_TYPE) #define CERT_KEYID_ISSUER_MATCH_FLAG \
CERT_MATCH_TYPE_TO_FLAG(CERT_KEYID_ISSUER_MATCH_TYPE) #define CERT_NAME_ISSUER_MATCH_FLAG \
CERT_MATCH_TYPE_TO_FLAG(CERT_NAME_ISSUER_MATCH_TYPE) #define CERT_PUBKEY_ISSUER_MATCH_FLAG \
CERT_MATCH_TYPE_TO_FLAG(CERT_PUBKEY_ISSUER_MATCH_TYPE)
//
// Issuer status flags
//
#define CERT_ISSUER_PUBKEY_FLAG 0x00000001
#define CERT_ISSUER_VALID_SIGNATURE_FLAG 0x00000002
#define CERT_ISSUER_URL_FLAG 0x00000004
#define CERT_ISSUER_PUBKEY_PARA_FLAG 0x00000008
#define CERT_ISSUER_SELF_SIGNED_FLAG 0x00000010
#define CERT_ISSUER_TRUSTED_ROOT_FLAG 0x00000020
#define CERT_ISSUER_EXACT_MATCH_HASH_FLAG 0x00000100
#define CERT_ISSUER_NAME_MATCH_HASH_FLAG 0x00000200
//
// Misc info flags
//
#define CHAIN_INVALID_BASIC_CONSTRAINTS_INFO_FLAG 0x00000001
#define CHAIN_INVALID_ISSUER_NAME_CONSTRAINTS_INFO_FLAG 0x00000002
#define CHAIN_INVALID_KEY_USAGE_FLAG 0x00000004
//
// CTL cache entry used for a self signed, untrusted root CCertObject
//
typedef struct _CERT_OBJECT_CTL_CACHE_ENTRY CERT_OBJECT_CTL_CACHE_ENTRY, *PCERT_OBJECT_CTL_CACHE_ENTRY; struct _CERT_OBJECT_CTL_CACHE_ENTRY { PCSSCTLOBJECT pSSCtlObject; // AddRef'ed
PCERT_TRUST_LIST_INFO pTrustListInfo; PCERT_OBJECT_CTL_CACHE_ENTRY pNext; };
//
// Chain policies and usage info
//
// Issuance and application policy and usage info
typedef struct _CHAIN_ISS_OR_APP_INFO { PCERT_POLICIES_INFO pPolicy; PCERT_POLICY_MAPPINGS_INFO pMappings; PCERT_POLICY_CONSTRAINTS_INFO pConstraints; PCERT_ENHKEY_USAGE pUsage; // If NULL, any
DWORD dwFlags; } CHAIN_ISS_OR_APP_INFO, *PCHAIN_ISS_OR_APP_INFO;
#define CHAIN_INVALID_POLICY_FLAG 0x00000001
#define CHAIN_ANY_POLICY_FLAG 0x00000002
#define CHAIN_ISS_INDEX 0
#define CHAIN_APP_INDEX 1
#define CHAIN_ISS_OR_APP_COUNT 2
typedef struct _CHAIN_POLICIES_INFO { CHAIN_ISS_OR_APP_INFO rgIssOrAppInfo[CHAIN_ISS_OR_APP_COUNT];
PCERT_ENHKEY_USAGE pPropertyUsage; // If NULL, any
} CHAIN_POLICIES_INFO, *PCHAIN_POLICIES_INFO;
//
// Subject name constraint info
//
typedef struct _CHAIN_SUBJECT_NAME_CONSTRAINTS_INFO { BOOL fInvalid;
// NULL pointer implies not present in the subject certificate
PCERT_ALT_NAME_INFO pAltNameInfo; PCERT_NAME_INFO pUnicodeNameInfo;
// If the AltNameInfo doesn't have a RFC822 (email) choice, tries to find
// email attribute (szOID_RSA_emailAddr) in the above pUnicodeNameInfo.
// Note, not re-allocated.
PCERT_RDN_ATTR pEmailAttr;
// Set to TRUE if the pAltNameInfo has a DNS choice.
BOOL fHasDnsAltNameEntry; } CHAIN_SUBJECT_NAME_CONSTRAINTS_INFO, *PCHAIN_SUBJECT_NAME_CONSTRAINTS_INFO;
//
// CSSCtlObjectCache::EnumObjects callback data structure used to
// create the linked list of CTL cache entries.
//
typedef struct _CERT_OBJECT_CTL_CACHE_ENUM_DATA { BOOL fResult; DWORD dwLastError; PCCERTOBJECT pCertObject; } CERT_OBJECT_CTL_CACHE_ENUM_DATA, *PCERT_OBJECT_CTL_CACHE_ENUM_DATA;
//
// CCertObject. This is the main object used for caching information
// about a certificate
//
class CCertObject { public:
//
// Construction
//
CCertObject ( IN DWORD dwObjectType, IN PCCHAINCALLCONTEXT pCallContext, IN PCCERT_CONTEXT pCertContext, IN BYTE rgbCertHash[CHAINHASHLEN], OUT BOOL& rfResult );
~CCertObject ();
//
// Object type
//
inline DWORD ObjectType();
//
// Convert a CERT_END_OBJECT_TYPE to a CERT_CACHED_END_OBJECT_TYPE.
//
BOOL CacheEndObject( IN PCCHAINCALLCONTEXT pCallContext );
//
// Reference counting
//
inline VOID AddRef (); inline VOID Release ();
//
// Chain engine access
//
inline PCCERTCHAINENGINE ChainEngine ();
//
// Issuer's match and status flags
//
inline DWORD IssuerMatchFlags(); inline DWORD CachedMatchFlags(); inline DWORD IssuerStatusFlags(); inline VOID OrIssuerStatusFlags(IN DWORD dwFlags); inline VOID OrCachedMatchFlags(IN DWORD dwFlags);
//
// Misc Info status flags
//
inline DWORD InfoFlags();
//
// For CERT_ISSUER_SELF_SIGNED_FLAG && !CERT_ISSUER_TRUSTED_ROOT_FLAG.
//
// List of cached CTLs
//
inline PCERT_OBJECT_CTL_CACHE_ENTRY NextCtlCacheEntry( IN PCERT_OBJECT_CTL_CACHE_ENTRY pEntry ); inline VOID InsertCtlCacheEntry( IN PCERT_OBJECT_CTL_CACHE_ENTRY pEntry );
//
// Object's certificate context
//
inline PCCERT_CONTEXT CertContext ();
//
// Policies and enhanced key usage obtained from certificate context's
// extensions and property
//
inline PCHAIN_POLICIES_INFO PoliciesInfo ();
//
// Basic constraints obtained from the certificate context's
// extensions (NULL if this extension is omitted)
//
inline PCERT_BASIC_CONSTRAINTS2_INFO BasicConstraintsInfo ();
//
// Key usage obtained from the certificate context's
// extensions (NULL if this extension is omitted)
//
inline PCRYPT_BIT_BLOB KeyUsage ();
//
// Issuer name constraints obtained from the certificate context's
// extensions (NULL if this extension is omitted)
//
inline PCERT_NAME_CONSTRAINTS_INFO IssuerNameConstraintsInfo ();
//
// Subject name constraint info
//
PCHAIN_SUBJECT_NAME_CONSTRAINTS_INFO SubjectNameConstraintsInfo ();
//
// Issuer access
//
inline PCERT_AUTHORITY_KEY_ID_INFO AuthorityKeyIdentifier ();
//
// Hash access
//
inline LPBYTE CertHash ();
//
// Key identifier access
//
inline DWORD KeyIdentifierSize (); inline LPBYTE KeyIdentifier ();
//
// Public key hash access
//
inline LPBYTE PublicKeyHash ();
// Only valid when CERT_ISSUER_PUBKEY_FLAG is set in m_dwIssuerStatusFlags
inline LPBYTE IssuerPublicKeyHash ();
//
// The index entry handles for cached issuer certificates.
// The primary index entry is the hash index entry. The index entries
// aren't LRU'ed.
//
inline HLRUENTRY HashIndexEntry (); inline HLRUENTRY IdentifierIndexEntry (); inline HLRUENTRY SubjectNameIndexEntry (); inline HLRUENTRY KeyIdIndexEntry (); inline HLRUENTRY PublicKeyHashIndexEntry ();
//
// The index entry handle for cached end certificates. This is an LRU
// list.
//
inline HLRUENTRY EndHashIndexEntry ();
//
// Issuer match hashes. If match hash doesn't exist,
// returns pMatchHash->cbData = 0
//
VOID GetIssuerExactMatchHash( OUT PCRYPT_DATA_BLOB pMatchHash ); VOID GetIssuerKeyMatchHash( OUT PCRYPT_DATA_BLOB pMatchHash ); VOID GetIssuerNameMatchHash( OUT PCRYPT_DATA_BLOB pMatchHash );
private: //
// Object's type
//
DWORD m_dwObjectType;
//
// Reference count
//
LONG m_cRefs;
//
// Certificate Chain Engine which owns this certificate object (not
// AddRef'ed)
//
PCCERTCHAINENGINE m_pChainEngine;
//
// Issuer's match and status flags
//
DWORD m_dwIssuerMatchFlags; DWORD m_dwCachedMatchFlags; DWORD m_dwIssuerStatusFlags;
//
// Misc Info flags
//
DWORD m_dwInfoFlags;
//
// For CERT_ISSUER_SELF_SIGNED_FLAG && !CERT_ISSUER_TRUSTED_ROOT_FLAG.
// Only set for CERT_CACHED_ISSUER_OBJECT_TYPE.
//
// List of cached CTLs
//
PCERT_OBJECT_CTL_CACHE_ENTRY m_pCtlCacheHead;
//
// Certificate context (duplicated)
//
PCCERT_CONTEXT m_pCertContext;
//
// Policies and usage info
//
CHAIN_POLICIES_INFO m_PoliciesInfo;
//
// Basic constraints info (NULL if this extension is omitted)
//
PCERT_BASIC_CONSTRAINTS2_INFO m_pBasicConstraintsInfo;
//
// Key usage (NULL if this extension is omitted)
//
PCRYPT_BIT_BLOB m_pKeyUsage;
//
// Name constraints obtained from the certificate context's
// extensions (NULL if this extension is omitted)
//
PCERT_NAME_CONSTRAINTS_INFO m_pIssuerNameConstraintsInfo;
//
// Subject name constraint info (deferred get of)
//
BOOL m_fAvailableSubjectNameConstraintsInfo; CHAIN_SUBJECT_NAME_CONSTRAINTS_INFO m_SubjectNameConstraintsInfo;
//
// Authority Key Identifier. This contains the issuer and serial number
// and/or key identifier of the issuing certificate for this certificate
// object if the m_dwIssuerMatchFlags includes
// CERT_EXACT_ISSUER_MATCH_FLAG and/or CERT_KEYID_ISSUER_MATCH_FLAG
//
PCERT_AUTHORITY_KEY_ID_INFO m_pAuthKeyIdentifier;
//
// Certificate Object Identifier (MD5 hash of issuer and serial number)
//
CERT_OBJECT_IDENTIFIER m_ObjectIdentifier;
//
// MD5 Hash of the certificate
//
BYTE m_rgbCertHash[ CHAINHASHLEN ];
//
// Key Identifier of the certificate
//
DWORD m_cbKeyIdentifier; LPBYTE m_pbKeyIdentifier;
//
// MD5 Hash of the subject and issuer public keys
//
BYTE m_rgbPublicKeyHash[ CHAINHASHLEN ];
// Only valid when CERT_ISSUER_PUBKEY_FLAG is set in m_dwIssuerStatusFlags
BYTE m_rgbIssuerPublicKeyHash[ CHAINHASHLEN ];
// Only valid when CERT_ISSUER_EXACT_MATCH_HASH_FLAG is set in
// m_dwIssuerStatusFlags
BYTE m_rgbIssuerExactMatchHash[ CHAINHASHLEN ]; // Only valid when CERT_ISSUER_NAME_MATCH_HASH_FLAG is set in
// m_dwIssuerStatusFlags
BYTE m_rgbIssuerNameMatchHash[ CHAINHASHLEN ];
//
// Certificate Object Cache Index entries applicable to
// CERT_CACHED_ISSUER_OBJECT_TYPE.
//
HLRUENTRY m_hHashEntry; HLRUENTRY m_hIdentifierEntry; HLRUENTRY m_hSubjectNameEntry; HLRUENTRY m_hKeyIdEntry; HLRUENTRY m_hPublicKeyHashEntry;
//
// Certificate Object Cache Index entries applicable to
// CERT_CACHED_END_OBJECT_TYPE.
//
HLRUENTRY m_hEndHashEntry; };
//
// Chain quality values (ascending order)
//
#define CERT_QUALITY_SIMPLE_CHAIN 0x00000001
#define CERT_QUALITY_CHECK_REVOCATION 0x00000010
#define CERT_QUALITY_ONLINE_REVOCATION 0x00000020
#define CERT_QUALITY_PREFERRED_ISSUER 0x00000040
#define CERT_QUALITY_HAS_APPLICATION_USAGE 0x00000080
#define CERT_QUALITY_HAS_ISSUANCE_CHAIN_POLICY 0x00000100
#define CERT_QUALITY_POLICY_CONSTRAINTS_VALID 0x00000200
#define CERT_QUALITY_BASIC_CONSTRAINTS_VALID 0x00000400
#define CERT_QUALITY_HAS_NAME_CONSTRAINTS 0x00000800
#define CERT_QUALITY_NAME_CONSTRAINTS_VALID 0x00001000
#define CERT_QUALITY_NAME_CONSTRAINTS_MET 0x00002000
#define CERT_QUALITY_NOT_REVOKED 0x00010000
#define CERT_QUALITY_TIME_VALID 0x00020000
#define CERT_QUALITY_MEETS_USAGE_CRITERIA 0x00040000
#define CERT_QUALITY_NO_DUPLICATE_KEY 0x00400000
#define CERT_QUALITY_NOT_CYCLIC 0x00800000
#define CERT_QUALITY_HAS_TIME_VALID_TRUSTED_ROOT 0x01000000
#define CERT_QUALITY_HAS_TRUSTED_ROOT 0x02000000
#define CERT_QUALITY_COMPLETE_CHAIN 0x04000000
#define CERT_QUALITY_SIGNATURE_VALID 0x08000000
#define CERT_QUALITY_FOR_REVOCATION_CHECK ( \
CERT_QUALITY_HAS_TRUSTED_ROOT | \ CERT_QUALITY_COMPLETE_CHAIN | \ CERT_QUALITY_SIGNATURE_VALID )
__inline BOOL IsValidCertQualityForRevocationCheck( IN DWORD dwQuality ) { if (CERT_QUALITY_FOR_REVOCATION_CHECK == (dwQuality & CERT_QUALITY_FOR_REVOCATION_CHECK)) return TRUE; else return FALSE; }
#define CERT_TRUST_CERTIFICATE_ONLY_INFO_STATUS ( CERT_TRUST_IS_SELF_SIGNED |\
CERT_TRUST_HAS_EXACT_MATCH_ISSUER |\ CERT_TRUST_HAS_NAME_MATCH_ISSUER |\ CERT_TRUST_HAS_KEY_MATCH_ISSUER )
#define CERT_CHAIN_REVOCATION_CHECK_ALL ( CERT_CHAIN_REVOCATION_CHECK_END_CERT | \
CERT_CHAIN_REVOCATION_CHECK_CHAIN | \ CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT )
#define CERT_TRUST_ANY_NAME_CONSTRAINT_ERROR_STATUS ( \
CERT_TRUST_INVALID_NAME_CONSTRAINTS | \ CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT | \ CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT | \ CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT | \ CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT )
//
// Internal chain context. Wraps the exposed CERT_CHAIN_CONTEXT.
//
typedef struct _INTERNAL_CERT_CHAIN_CONTEXT INTERNAL_CERT_CHAIN_CONTEXT, *PINTERNAL_CERT_CHAIN_CONTEXT; struct _INTERNAL_CERT_CHAIN_CONTEXT { CERT_CHAIN_CONTEXT ChainContext; LONG cRefs; DWORD dwQuality; PINTERNAL_CERT_CHAIN_CONTEXT pNext; };
//
// Restricted issuance, application and property usage as we move from the
// top down to the end certificate
//
// Note, NULL PCERT_ENHKEY_USAGE implies any
typedef struct _CHAIN_RESTRICTED_USAGE_INFO { PCERT_ENHKEY_USAGE pIssuanceRestrictedUsage; PCERT_ENHKEY_USAGE pIssuanceMappedUsage; LPDWORD rgdwIssuanceMappedIndex; BOOL fRequireIssuancePolicy;
PCERT_ENHKEY_USAGE pApplicationRestrictedUsage; PCERT_ENHKEY_USAGE pApplicationMappedUsage; LPDWORD rgdwApplicationMappedIndex;
PCERT_ENHKEY_USAGE pPropertyRestrictedUsage; } CHAIN_RESTRICTED_USAGE_INFO, *PCHAIN_RESTRICTED_USAGE_INFO;
//
// Forward reference to the issuer element
//
typedef struct _CERT_ISSUER_ELEMENT CERT_ISSUER_ELEMENT, *PCERT_ISSUER_ELEMENT;
//
// CChainPathObject. This is the main object used for building the
// chain graph.
//
// Note, since this object isn't persisted across calls, NO REF COUNTING is
// done.
//
class CChainPathObject { public: //
// Construction
//
CChainPathObject ( IN PCCHAINCALLCONTEXT pCallContext, IN BOOL fCyclic, IN LPVOID pvObject, // fCyclic : pPathObject ? pCertObject
IN OPTIONAL HCERTSTORE hAdditionalStore, OUT BOOL& rfResult, OUT BOOL& rfAddedToCreationCache );
~CChainPathObject ();
//
// Certificate Object (AddRef'ed)
//
inline PCCERTOBJECT CertObject ();
//
// Pass 1 quality
//
inline DWORD Pass1Quality (); inline VOID SetPass1Quality (IN DWORD dwQuality);
//
// Pass 1 duplicate key depth
//
inline DWORD Pass1DuplicateKeyDepth (); inline VOID SetPass1DuplicateKeyDepth (IN DWORD dwDepth);
//
// Returns TRUE if we have completed the initialization and addition
// of issuers to this object. FALSE would normally indicate a cyclic
// issuer.
//
inline BOOL IsCompleted ();
//
// AdditionalStatus flag, down path object and up issuer element
//
inline BOOL HasAdditionalStatus (); inline PCCHAINPATHOBJECT DownPathObject (); inline PCERT_ISSUER_ELEMENT UpIssuerElement ();
//
// Find and add issuers
//
BOOL FindAndAddIssuers ( IN PCCHAINCALLCONTEXT pCallContext, IN OPTIONAL HCERTSTORE hAdditionalStore, IN OPTIONAL HCERTSTORE hIssuerUrlStore ); BOOL FindAndAddIssuersByMatchType( IN DWORD dwMatchType, IN PCCHAINCALLCONTEXT pCallContext, IN OPTIONAL HCERTSTORE hAdditionalStore, IN OPTIONAL HCERTSTORE hIssuerUrlStore ); BOOL FindAndAddIssuersFromCacheByMatchType( IN DWORD dwMatchType, IN PCCHAINCALLCONTEXT pCallContext, IN OPTIONAL HCERTSTORE hAdditionalStore ); BOOL FindAndAddIssuersFromStoreByMatchType( IN DWORD dwMatchType, IN PCCHAINCALLCONTEXT pCallContext, IN BOOL fExternalStore, IN OPTIONAL HCERTSTORE hAdditionalStore, IN OPTIONAL HCERTSTORE hIssuerUrlStore );
BOOL FindAndAddCtlIssuersFromCache ( IN PCCHAINCALLCONTEXT pCallContext, IN OPTIONAL HCERTSTORE hAdditionalStore ); BOOL FindAndAddCtlIssuersFromAdditionalStore ( IN PCCHAINCALLCONTEXT pCallContext, IN HCERTSTORE hAdditionalStore );
//
// Builds the top down chain graph for the next top object
//
PCCHAINPATHOBJECT NextPath ( IN PCCHAINCALLCONTEXT pCallContext, IN OPTIONAL PCCHAINPATHOBJECT pPrevTopPathObject );
PCCHAINPATHOBJECT NextPathWithoutDuplicateKeyCheck ( IN PCCHAINCALLCONTEXT pCallContext, IN OPTIONAL PCCHAINPATHOBJECT pPrevTopPathObject );
VOID ResetNextPath( IN PCCHAINCALLCONTEXT pCallContext, IN OPTIONAL PCCHAINPATHOBJECT pTopPathObject );
VOID CalculateAdditionalStatus ( IN PCCHAINCALLCONTEXT pCallContext, IN HCERTSTORE hAllStore ); VOID CalculatePolicyConstraintsStatus (); VOID CalculateBasicConstraintsStatus (); VOID CalculateKeyUsageStatus (); VOID CalculateNameConstraintsStatus ( IN PCERT_USAGE_MATCH pUsageToUse ); VOID CalculateRevocationStatus ( IN PCCHAINCALLCONTEXT pCallContext, IN HCERTSTORE hCrlStore, IN LPFILETIME pTime );
PINTERNAL_CERT_CHAIN_CONTEXT CreateChainContextFromPath ( IN PCCHAINCALLCONTEXT pCallContext, IN PCCHAINPATHOBJECT pTopPathObject );
BOOL UpdateChainContextUsageForPathObject ( IN PCCHAINCALLCONTEXT pCallContext, IN OUT PCERT_SIMPLE_CHAIN pChain, IN OUT PCERT_CHAIN_ELEMENT pElement, IN OUT PCHAIN_RESTRICTED_USAGE_INFO pRestrictedUsageInfo );
BOOL UpdateChainContextFromPathObject ( IN PCCHAINCALLCONTEXT pCallContext, IN OUT PCERT_SIMPLE_CHAIN pChain, IN OUT PCERT_CHAIN_ELEMENT pElement );
//
// AuthRoot Auto Update CTL Methods
//
BOOL GetAuthRootAutoUpdateUrlStore( IN PCCHAINCALLCONTEXT pCallContext, OUT HCERTSTORE *phIssuerUrlStore );
private: //
// Certificate Object (AddRef'ed)
//
PCCERTOBJECT m_pCertObject;
//
// Trust Status. This does not represent the full trust status
// for the object. Some of the bits are calculated on demand and placed
// into the ending chain context. The following are the trust status
// bits which can appear here
//
// CERT_TRUST_IS_SELF_SIGNED
// CERT_TRUST_HAS_EXACT_MATCH_ISSUER
// CERT_TRUST_HAS_NAME_MATCH_ISSUER
// CERT_TRUST_HAS_KEY_MATCH_ISSUER
//
// CERT_TRUST_IS_NOT_SIGNATURE_VALID (if the certificate is self-signed)
// CERT_TRUST_IS_UNTRUSTED_ROOT (if the certificate is self-signed)
// CERT_TRUST_HAS_PREFERRED_ISSUER (if the certificate is self-signed)
//
// CERT_TRUST_IS_CYCLIC (for cyclic cert)
//
CERT_TRUST_STATUS m_TrustStatus;
// Pass1 Quality is limited to the following:
// CERT_QUALITY_NO_DUPLICATE_KEY
// CERT_QUALITY_NOT_CYCLIC
// CERT_QUALITY_HAS_TIME_VALID_TRUSTED_ROOT
// CERT_QUALITY_HAS_TRUSTED_ROOT
// CERT_QUALITY_SIGNATURE_VALID
// CERT_QUALITY_COMPLETE_CHAIN
DWORD m_dwPass1Quality; DWORD m_dwPass1DuplicateKeyDepth;
//
// The chain context's chain and element indices
//
DWORD m_dwChainIndex; DWORD m_dwElementIndex;
//
// Down and up path pointers for a chain context
//
PCERT_ISSUER_ELEMENT m_pDownIssuerElement; PCCHAINPATHOBJECT m_pDownPathObject; PCERT_ISSUER_ELEMENT m_pUpIssuerElement;
//
// Additional status and revocation info (only applicable to self signed
// certificates or top certificates without any issuers)
//
BOOL m_fHasAdditionalStatus; CERT_TRUST_STATUS m_AdditionalStatus; BOOL m_fHasRevocationInfo; CERT_REVOCATION_INFO m_RevocationInfo; CERT_REVOCATION_CRL_INFO m_RevocationCrlInfo;
//
// Issuer Chain Path Objects. The list of issuers of this
// certificate object along with information about those issuers
// relevant to this subject.
//
PCCERTISSUERLIST m_pIssuerList;
//
// Supplemental error information is localization formatted and appended.
// Each error line should be terminated with a L'\n'.
//
LPWSTR m_pwszExtendedErrorInfo;
//
// Following flag is set when we have completed the initialization and
// addition of all issuers to this object.
//
BOOL m_fCompleted; };
//
// CCertIssuerList. List of issuer certificate objects along with related
// issuer information. This is used by the certificate object to cache
// its possible set of issuers
//
// Currently in a self signed certificate object, the issuer elements will
// have CTL issuer data set and pIssuer may be NULL if unable to find
// the CTL signer
typedef struct _CTL_ISSUER_DATA { PCSSCTLOBJECT pSSCtlObject; // AddRef'ed
PCERT_TRUST_LIST_INFO pTrustListInfo; } CTL_ISSUER_DATA, *PCTL_ISSUER_DATA;
struct _CERT_ISSUER_ELEMENT { DWORD dwPass1Quality; DWORD dwPass1DuplicateKeyDepth; CERT_TRUST_STATUS SubjectStatus; BOOL fCtlIssuer; PCCHAINPATHOBJECT pIssuer;
// For a cyclic issuer, the above pIssuer is saved into the following
// before it is updated with the cyclic issuer path object
PCCHAINPATHOBJECT pCyclicSaveIssuer;
PCTL_ISSUER_DATA pCtlIssuerData; struct _CERT_ISSUER_ELEMENT* pPrevElement; struct _CERT_ISSUER_ELEMENT* pNextElement; BOOL fHasRevocationInfo; CERT_REVOCATION_INFO RevocationInfo; CERT_REVOCATION_CRL_INFO RevocationCrlInfo; };
class CCertIssuerList { public:
//
// Construction
//
CCertIssuerList ( IN PCCHAINPATHOBJECT pSubject );
~CCertIssuerList ();
//
// Issuer management
//
inline BOOL IsEmpty ();
BOOL AddIssuer( IN PCCHAINCALLCONTEXT pCallContext, IN OPTIONAL HCERTSTORE hAdditionalStore, IN PCCERTOBJECT pIssuer );
BOOL AddCtlIssuer( IN PCCHAINCALLCONTEXT pCallContext, IN OPTIONAL HCERTSTORE hAdditionalStore, IN PCSSCTLOBJECT pSSCtlObject, IN PCERT_TRUST_LIST_INFO pTrustListInfo );
//
// Element management
//
BOOL CreateElement( IN PCCHAINCALLCONTEXT pCallContext, IN BOOL fCtlIssuer, IN OPTIONAL PCCHAINPATHOBJECT pIssuer, IN OPTIONAL HCERTSTORE hAdditionalStore, IN OPTIONAL PCSSCTLOBJECT pSSCtlObject, IN OPTIONAL PCERT_TRUST_LIST_INFO pTrustListInfo, OUT PCERT_ISSUER_ELEMENT* ppElement );
VOID DeleteElement ( IN PCERT_ISSUER_ELEMENT pElement );
inline VOID AddElement ( IN PCERT_ISSUER_ELEMENT pElement );
inline VOID RemoveElement ( IN PCERT_ISSUER_ELEMENT pElement );
BOOL CheckForDuplicateElement ( IN BYTE rgbHash [ CHAINHASHLEN ], IN BOOL fCtlIssuer );
//
// Enumerate the issuers
//
inline PCERT_ISSUER_ELEMENT NextElement ( IN PCERT_ISSUER_ELEMENT pElement );
private:
//
// Subject chain path object
//
PCCHAINPATHOBJECT m_pSubject;
//
// Issuer List
//
PCERT_ISSUER_ELEMENT m_pHead;
};
//
// CCertObjectCache.
//
// Cache of issuer certificate object references indexed by the following keys:
// Certificate Hash
// Certificate Object Identifier
// Subject Name
// Key Identifier
// Public Key Hash
//
// Cache of end certificate object references indexed by the following keys:
// End Certificate Hash
//
// Only the end certificate is LRU maintained.
//
#define DEFAULT_CERT_OBJECT_CACHE_BUCKETS 127
#define DEFAULT_MAX_INDEX_ENTRIES 256
class CCertObjectCache { public:
//
// Construction
//
CCertObjectCache ( IN DWORD MaxIndexEntries, OUT BOOL& rfResult );
~CCertObjectCache ();
//
// Certificate Object Management
//
// Increments engine's touch count
VOID AddIssuerObject ( IN PCCHAINCALLCONTEXT pCallContext, IN PCCERTOBJECT pCertObject );
VOID AddEndObject ( IN PCCHAINCALLCONTEXT pCallContext, IN PCCERTOBJECT pCertObject );
//
// Access the indexes
//
inline HLRUCACHE HashIndex ();
inline HLRUCACHE IdentifierIndex ();
inline HLRUCACHE SubjectNameIndex ();
inline HLRUCACHE KeyIdIndex ();
inline HLRUCACHE PublicKeyHashIndex ();
inline HLRUCACHE EndHashIndex ();
//
// Certificate Object Searching
//
PCCERTOBJECT FindIssuerObject ( IN HLRUCACHE hIndex, IN PCRYPT_DATA_BLOB pIdentifier );
PCCERTOBJECT FindIssuerObjectByHash ( IN BYTE rgbCertHash[ CHAINHASHLEN ] );
PCCERTOBJECT FindEndObjectByHash ( IN BYTE rgbCertHash[ CHAINHASHLEN ] );
//
// Certificate Object Enumeration
//
PCCERTOBJECT NextMatchingIssuerObject ( IN HLRUENTRY hObjectEntry, IN PCCERTOBJECT pCertObject );
//
// Cache flushing
//
inline VOID FlushObjects (IN PCCHAINCALLCONTEXT pCallContext);
private:
//
// Certificate Hash Index
//
HLRUCACHE m_hHashIndex;
//
// Certificate Object Identifier Index
//
HLRUCACHE m_hIdentifierIndex;
//
// Subject Name Index
//
HLRUCACHE m_hSubjectNameIndex;
//
// Key Identifier Index
//
HLRUCACHE m_hKeyIdIndex;
//
// Public Key Hash Index
//
HLRUCACHE m_hPublicKeyHashIndex;
//
// End Certificate Hash Index
//
HLRUCACHE m_hEndHashIndex;
//
// Private methods
//
};
typedef struct _XCERT_DP_ENTRY XCERT_DP_ENTRY, *PXCERT_DP_ENTRY; typedef struct _XCERT_DP_LINK XCERT_DP_LINK, *PXCERT_DP_LINK;
//
// Cross Certificate Distribution Point Entry
//
struct _XCERT_DP_ENTRY { // Seconds between syncs
DWORD dwSyncDeltaTime;
// List of NULL terminated Urls. A successfully retrieved Url
// pointer is moved to the beginning of the list.
DWORD cUrl; LPWSTR *rgpwszUrl;
// Time of last sync
FILETIME LastSyncTime;
// If dwOfflineCnt == 0, NextSyncTime = LastSyncTime + dwSyncDeltaTime.
// Otherwise, NextSyncTime = CurrentTime +
// rgdwChainOfflineUrlDeltaSeconds[dwOfflineCnt - 1]
FILETIME NextSyncTime;
// Following is incremented when unable to do an online Url retrieval.
// A successful Url retrieval resets.
DWORD dwOfflineCnt;
// Following is incremented for each new scan through the DP entries
DWORD dwResyncIndex;
// Following is set when this entry has already been checked
BOOL fChecked; PXCERT_DP_LINK pChildCrossCertDPLink; LONG lRefCnt; HCERTSTORE hUrlStore; PXCERT_DP_ENTRY pNext; PXCERT_DP_ENTRY pPrev; };
//
// Cross Certificate Distribution Point Link
//
struct _XCERT_DP_LINK { PXCERT_DP_ENTRY pCrossCertDPEntry; PXCERT_DP_LINK pNext; PXCERT_DP_LINK pPrev; };
//
// AuthRoot Auto Update Info
//
#define AUTH_ROOT_KEY_MATCH_IDX 0
#define AUTH_ROOT_NAME_MATCH_IDX 1
#define AUTH_ROOT_MATCH_CNT 2
#define AUTH_ROOT_MATCH_CACHE_BUCKETS 61
typedef struct _AUTH_ROOT_AUTO_UPDATE_INFO { // Seconds between syncs
DWORD dwSyncDeltaTime;
// Registry Flags value
DWORD dwFlags;
// URL to the directory containing the AuthRoots
LPWSTR pwszRootDirUrl;
// URL to the CAB containing the CTL containing the complete list of roots
// in the AuthRoot store
LPWSTR pwszCabUrl;
// URL to the SequenceNumber file corresponding to the latest list of
// roots in the AuthRoot store
LPWSTR pwszSeqUrl;
// Time of last sync
FILETIME LastSyncTime;
// NextSyncTime = LastSyncTime + dwSyncDeltaTime.
FILETIME NextSyncTime;
// If nonNull, a validated AuthRoot CTL.
PCCTL_CONTEXT pCtl;
// Cache of CTL entries via their key and name match hashes. The
// Cache entry value is the PCTL_ENTRY pointer.
HLRUCACHE rghMatchCache[AUTH_ROOT_MATCH_CNT];
} AUTH_ROOT_AUTO_UPDATE_INFO, *PAUTH_ROOT_AUTO_UPDATE_INFO;
// 7 days
#define AUTH_ROOT_AUTO_UPDATE_SYNC_DELTA_TIME (60 * 60 * 24 * 7)
#define AUTH_ROOT_AUTO_UPDATE_ROOT_DIR_URL L"http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en"
typedef struct _CHAIN_CONFIG { BOOL fDisableMandatoryBasicConstraints;
BOOL fDisableAIAUrlRetrieval; DWORD dwMaxAIAUrlCountInCert; DWORD dwMaxAIAUrlRetrievalCountPerChain; DWORD dwMaxAIAUrlRetrievalByteCount; DWORD dwMaxAIAUrlRetrievalCertCount; } CHAIN_CONFIG;
//
// CCertChainEngine. The chaining engine satisfies requests for chain contexts
// given some set of parameters. In order to make the building of these
// contexts efficient, the chain engine caches trust and chain information
// for certificates
//
class CCertChainEngine { public:
//
// Construction
//
CCertChainEngine ( IN PCERT_CHAIN_ENGINE_CONFIG pConfig, IN BOOL fDefaultEngine, OUT BOOL& rfResult );
~CCertChainEngine ();
//
// Chain Engine Locking
//
inline VOID LockEngine (); inline VOID UnlockEngine ();
//
// Chain Engine reference counting
//
inline VOID AddRef (); inline VOID Release ();
//
// Cache access
//
inline PCCERTOBJECTCACHE CertObjectCache (); inline PCSSCTLOBJECTCACHE SSCtlObjectCache ();
//
// Store access
//
inline HCERTSTORE RootStore (); inline HCERTSTORE RealRootStore (); inline HCERTSTORE TrustStore (); inline HCERTSTORE OtherStore (); inline HCERTSTORE CAStore (); inline HCERTSTORE DisallowedStore ();
//
// Open the HKLM or HKCU "trust" store. Caller must close.
//
inline HCERTSTORE OpenTrustStore ();
//
// Engine's Url retrieval timeout
//
inline DWORD UrlRetrievalTimeout (); inline BOOL HasDefaultUrlRetrievalTimeout ();
//
// Engine's Flags
//
inline DWORD Flags ();
//
// DisableMandatoryBasicConstraints flag
//
inline BOOL DisableMandatoryBasicConstraints ();
//
// Engine Touching
//
inline DWORD TouchEngineCount (); inline DWORD IncrementTouchEngineCount ();
//
// Chain Context Retrieval
//
BOOL GetChainContext ( IN PCCERT_CONTEXT pCertContext, IN LPFILETIME pTime, IN HCERTSTORE hAdditionalStore, IN OPTIONAL PCERT_CHAIN_PARA pChainPara, IN DWORD dwFlags, IN LPVOID pvReserved, OUT PCCERT_CHAIN_CONTEXT* ppChainContext );
BOOL CreateChainContextFromPathGraph ( IN PCCHAINCALLCONTEXT pCallContext, IN PCCERT_CONTEXT pCertContext, IN HCERTSTORE hAdditionalStore, OUT PCCERT_CHAIN_CONTEXT* ppChainContext );
BOOL IsPotentialKeyRolloverRoot ( IN PCCERT_CONTEXT pRootCertContext );
// Leaves Engine's lock to do URL fetching
BOOL GetIssuerUrlStore( IN PCCHAINCALLCONTEXT pCallContext, IN PCCERT_CONTEXT pSubjectCertContext, IN DWORD dwRetrievalFlags, OUT HCERTSTORE *phIssuerUrlStore );
// Engine isn't locked on entry. Only called if online.
HCERTSTORE GetNewerIssuerUrlStore( IN PCCHAINCALLCONTEXT pCallContext, IN PCCERT_CONTEXT pSubjectCertContext, IN PCCERT_CONTEXT pIssuerCertContext );
//
// Resync the engine
//
BOOL Resync (IN PCCHAINCALLCONTEXT pCallContext, BOOL fForce);
//
// Cross Certificate Methods implemented in xcert.cpp
//
void InsertCrossCertDistPointEntry( IN OUT PXCERT_DP_ENTRY pEntry ); void RemoveCrossCertDistPointEntry( IN OUT PXCERT_DP_ENTRY pEntry );
void RepositionOnlineCrossCertDistPointEntry( IN OUT PXCERT_DP_ENTRY pEntry, IN LPFILETIME pLastSyncTime ); void RepositionOfflineCrossCertDistPointEntry( IN OUT PXCERT_DP_ENTRY pEntry, IN LPFILETIME pCurrentTime ); void RepositionNewSyncDeltaTimeCrossCertDistPointEntry( IN OUT PXCERT_DP_ENTRY pEntry, IN DWORD dwSyncDeltaTime );
PXCERT_DP_ENTRY CreateCrossCertDistPointEntry( IN DWORD dwSyncDeltaTime, IN DWORD cUrl, IN LPWSTR *rgpwszUrl ); void AddRefCrossCertDistPointEntry( IN OUT PXCERT_DP_ENTRY pEntry ); BOOL ReleaseCrossCertDistPointEntry( IN OUT PXCERT_DP_ENTRY pEntry );
BOOL GetCrossCertDistPointsForStore( IN HCERTSTORE hStore, IN BOOL fOnlyLMSystemStore, IN OUT PXCERT_DP_LINK *ppLinkHead );
void RemoveCrossCertDistPointOrphanEntry( IN PXCERT_DP_ENTRY pOrphanEntry ); void FreeCrossCertDistPoints( IN OUT PXCERT_DP_LINK *ppLinkHead );
BOOL RetrieveCrossCertUrl( IN PCCHAINCALLCONTEXT pCallContext, IN OUT PXCERT_DP_ENTRY pEntry, IN DWORD dwRetrievalFlags, IN OUT BOOL *pfTimeValid ); BOOL UpdateCrossCerts( IN PCCHAINCALLCONTEXT pCallContext );
//
// AuthRoot Auto Update CTL Methods
//
inline PAUTH_ROOT_AUTO_UPDATE_INFO AuthRootAutoUpdateInfo();
BOOL RetrieveAuthRootAutoUpdateObjectByUrlW( IN PCCHAINCALLCONTEXT pCallContext, IN DWORD dwSuccessEventID, IN DWORD dwFailEventID, IN LPCWSTR pwszUrl, IN LPCSTR pszObjectOid, IN DWORD dwRetrievalFlags, IN DWORD dwTimeout, // 0 => use default
OUT LPVOID* ppvObject, IN OPTIONAL PCRYPT_RETRIEVE_AUX_INFO pAuxInfo );
BOOL GetAuthRootAutoUpdateCtl( IN PCCHAINCALLCONTEXT pCallContext, OUT PCCTL_CONTEXT *ppCtl );
VOID FindAuthRootAutoUpdateMatchingCtlEntries( IN CRYPT_DATA_BLOB rgMatchHash[AUTH_ROOT_MATCH_CNT], IN OUT PCCTL_CONTEXT *ppCtl, OUT DWORD *pcCtlEntry, OUT PCTL_ENTRY **prgpCtlEntry );
BOOL GetAuthRootAutoUpdateCert( IN PCCHAINCALLCONTEXT pCallContext, IN PCTL_ENTRY pCtlEntry, IN OUT HCERTSTORE hStore );
private:
//
// Reference count
//
LONG m_cRefs;
//
// Engine Lock
//
CRITICAL_SECTION m_Lock; BOOL m_fInitializedLock;
//
// Root store ( Certs )
//
HCERTSTORE m_hRealRootStore; HCERTSTORE m_hRootStore;
//
// Trust Store Collection ( CTLs )
//
HCERTSTORE m_hTrustStore;
//
// Other store collection ( Certs and CRLs )
//
HCERTSTORE m_hOtherStore; HCERTSTORE m_hCAStore;
//
// Disallowed Store (disallowed, untrusted end certificates)
//
HCERTSTORE m_hDisallowedStore;
//
// Engine Store ( Collection of Root, Trust and Other )
//
HCERTSTORE m_hEngineStore;
//
// Engine Store Change Notification Event
//
HANDLE m_hEngineStoreChangeEvent;
//
// Engine flags
//
DWORD m_dwFlags;
//
// Retrieval timeout
//
DWORD m_dwUrlRetrievalTimeout; BOOL m_fDefaultUrlRetrievalTimeout;
//
// Certificate Object Cache
//
PCCERTOBJECTCACHE m_pCertObjectCache;
//
// Self Signed Certificate Trust List Object Cache
//
PCSSCTLOBJECTCACHE m_pSSCtlObjectCache;
//
// Engine Touching
//
DWORD m_dwTouchEngineCount;
//
// Cross Certificate
//
// List of all distribution point entries. Ordered according to
// the entrys' NextSyncTime.
PXCERT_DP_ENTRY m_pCrossCertDPEntry;
// List of engine's distribution point links
PXCERT_DP_LINK m_pCrossCertDPLink;
// Collection of cross cert stores
HCERTSTORE m_hCrossCertStore;
// Following index is advanced for each new scan to find cross cert
// distribution points to resync
DWORD m_dwCrossCertDPResyncIndex;
//
// AuthRoot Auto Update Info. Created first time we have a partial chain
// or a untrusted root and auto update has been enabled.
//
PAUTH_ROOT_AUTO_UPDATE_INFO m_pAuthRootAutoUpdateInfo;
//
// Chain configuration parameters updatable via HKLM registry
//
CHAIN_CONFIG m_Config; };
//+===========================================================================
// CCertObject inline methods
//============================================================================
//+---------------------------------------------------------------------------
//
// Member: CCertObject::ObjectType, public
//
// Synopsis: return the object type
//
//----------------------------------------------------------------------------
inline DWORD CCertObject::ObjectType () { return( m_dwObjectType ); } //+---------------------------------------------------------------------------
//
// Member: CCertObject::AddRef, public
//
// Synopsis: add a reference to the certificate object
//
//----------------------------------------------------------------------------
inline VOID CCertObject::AddRef () { InterlockedIncrement( &m_cRefs ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::Release, public
//
// Synopsis: remove a reference from the certificate object
//
//----------------------------------------------------------------------------
inline VOID CCertObject::Release () { if ( InterlockedDecrement( &m_cRefs ) == 0 ) { delete this; } }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::ChainEngine, public
//
// Synopsis: return the chain engine object
//
//----------------------------------------------------------------------------
inline PCCERTCHAINENGINE CCertObject::ChainEngine () { return( m_pChainEngine ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::IssuerMatchFlags, public
//
// Synopsis: return the issuer match flags
//
//----------------------------------------------------------------------------
inline DWORD CCertObject::IssuerMatchFlags () { return( m_dwIssuerMatchFlags ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::CachedMatchFlags, public
//
// Synopsis: return the cached match flags
//
//----------------------------------------------------------------------------
inline DWORD CCertObject::CachedMatchFlags () { return( m_dwCachedMatchFlags ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::IssuerStatusFlags, public
//
// Synopsis: return the issuer status flags
//
//----------------------------------------------------------------------------
inline DWORD CCertObject::IssuerStatusFlags () { return( m_dwIssuerStatusFlags ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::OrIssuerStatusFlags, public
//
// Synopsis: 'or' bits into the issuer status flags.
//
//----------------------------------------------------------------------------
inline VOID CCertObject::OrIssuerStatusFlags( IN DWORD dwFlags ) { m_dwIssuerStatusFlags |= dwFlags; }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::OrCachedMatchFlags, public
//
// Synopsis: 'or' bits into the cached match flags
//
//
//----------------------------------------------------------------------------
inline VOID CCertObject::OrCachedMatchFlags( IN DWORD dwFlags ) { m_dwCachedMatchFlags |= dwFlags; }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::InfoFlags, public
//
// Synopsis: return the misc info flags
//
//----------------------------------------------------------------------------
inline DWORD CCertObject::InfoFlags () { return( m_dwInfoFlags ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::NextCtlCacheEntry, public
//
// Synopsis: return the next entry, if pEntry == NULL the first entry
// is returned
//
//----------------------------------------------------------------------------
inline PCERT_OBJECT_CTL_CACHE_ENTRY CCertObject::NextCtlCacheEntry( IN PCERT_OBJECT_CTL_CACHE_ENTRY pEntry ) { if (NULL == pEntry) return m_pCtlCacheHead; else return pEntry->pNext; }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::InsertCtlCacheEntry, public
//
// Synopsis: insert an entry into the Ctl cache
//
//----------------------------------------------------------------------------
inline VOID CCertObject::InsertCtlCacheEntry( IN PCERT_OBJECT_CTL_CACHE_ENTRY pEntry ) { pEntry->pNext = m_pCtlCacheHead; m_pCtlCacheHead = pEntry; }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::CertContext, public
//
// Synopsis: return the certificate context
//
//----------------------------------------------------------------------------
inline PCCERT_CONTEXT CCertObject::CertContext () { return( m_pCertContext ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::PoliciesInfo, public
//
// Synopsis: return pointer to the policies and usage info
//
//----------------------------------------------------------------------------
inline PCHAIN_POLICIES_INFO CCertObject::PoliciesInfo () { return( &m_PoliciesInfo ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::BasicConstraintsInfo, public
//
// Synopsis: return the basic constraints info pointer
//
//----------------------------------------------------------------------------
inline PCERT_BASIC_CONSTRAINTS2_INFO CCertObject::BasicConstraintsInfo () { return( m_pBasicConstraintsInfo ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::KeyUsage, public
//
// Synopsis: return the key usage pointer
//
//----------------------------------------------------------------------------
inline PCRYPT_BIT_BLOB CCertObject::KeyUsage () { return( m_pKeyUsage ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::IssuerNameConstraintsInfo, public
//
// Synopsis: return the issuer name constraints info pointer
//
//----------------------------------------------------------------------------
inline PCERT_NAME_CONSTRAINTS_INFO CCertObject::IssuerNameConstraintsInfo () { return( m_pIssuerNameConstraintsInfo ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::AuthorityKeyIdentifier, public
//
// Synopsis: return the issuer authority key identifier information
//
//----------------------------------------------------------------------------
inline PCERT_AUTHORITY_KEY_ID_INFO CCertObject::AuthorityKeyIdentifier () { return( m_pAuthKeyIdentifier ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::CertHash, public
//
// Synopsis: return the certificate hash
//
//----------------------------------------------------------------------------
inline LPBYTE CCertObject::CertHash () { return( m_rgbCertHash ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::KeyIdentifierSize, public
//
// Synopsis: return the key identifier blob size
//
//----------------------------------------------------------------------------
inline DWORD CCertObject::KeyIdentifierSize () { return( m_cbKeyIdentifier ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::KeyIdentifier, public
//
// Synopsis: return the key identifier
//
//----------------------------------------------------------------------------
inline LPBYTE CCertObject::KeyIdentifier () { return( m_pbKeyIdentifier ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::PublicKeyHash, public
//
// Synopsis: return the cert's public key hash
//
//----------------------------------------------------------------------------
inline LPBYTE CCertObject::PublicKeyHash () { return( m_rgbPublicKeyHash ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::IssuerPublicKeyHash, public
//
// Synopsis: return the public key hash of the cert's issuer
//
//----------------------------------------------------------------------------
inline LPBYTE CCertObject::IssuerPublicKeyHash () { return( m_rgbIssuerPublicKeyHash ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::HashIndexEntry, public
//
// Synopsis: return the hash index entry
//
//----------------------------------------------------------------------------
inline HLRUENTRY CCertObject::HashIndexEntry () { return( m_hHashEntry ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::IdentifierIndexEntry, public
//
// Synopsis: return the identifier index entry
//
//----------------------------------------------------------------------------
inline HLRUENTRY CCertObject::IdentifierIndexEntry () { return( m_hIdentifierEntry ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::SubjectNameIndexEntry, public
//
// Synopsis: return the subject name index entry
//
//----------------------------------------------------------------------------
inline HLRUENTRY CCertObject::SubjectNameIndexEntry () { return( m_hSubjectNameEntry ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::KeyIdIndexEntry, public
//
// Synopsis: return the key identifier index entry
//
//----------------------------------------------------------------------------
inline HLRUENTRY CCertObject::KeyIdIndexEntry () { return( m_hKeyIdEntry ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::PublicKeyHashIndexEntry, public
//
// Synopsis: return the public key hash index entry
//
//----------------------------------------------------------------------------
inline HLRUENTRY CCertObject::PublicKeyHashIndexEntry () { return( m_hPublicKeyHashEntry ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObject::EndHashIndexEntry, public
//
// Synopsis: return the hash index entry
//
//----------------------------------------------------------------------------
inline HLRUENTRY CCertObject::EndHashIndexEntry () { return( m_hEndHashEntry ); }
//+---------------------------------------------------------------------------
//
// Member: CChainPathObject::CertObject, public
//
// Synopsis: returns the cert object
//
//----------------------------------------------------------------------------
inline PCCERTOBJECT CChainPathObject::CertObject () { return( m_pCertObject ); }
//+---------------------------------------------------------------------------
//
// Member: CChainPathObject::Pass1Quality, public
//
// Synopsis: return the quality value determined during the first pass
//
//----------------------------------------------------------------------------
inline DWORD CChainPathObject::Pass1Quality () { return( m_dwPass1Quality ); }
//+---------------------------------------------------------------------------
//
// Member: CChainPathObject::SetPass1Quality, public
//
// Synopsis: set the first pass quality value
//
//----------------------------------------------------------------------------
inline VOID CChainPathObject::SetPass1Quality (IN DWORD dwQuality) { m_dwPass1Quality = dwQuality; }
//+---------------------------------------------------------------------------
//
// Member: CChainPathObject::Pass1DuplicateKeyDepth, public
//
// Synopsis: return the duplicate key depth determined during the first pass
//
//----------------------------------------------------------------------------
inline DWORD CChainPathObject::Pass1DuplicateKeyDepth () { return( m_dwPass1DuplicateKeyDepth ); }
//+---------------------------------------------------------------------------
//
// Member: CChainPathObject::SetPass1DuplicateKeyDepth, public
//
// Synopsis: set the first pass duplicate key depth
//
//----------------------------------------------------------------------------
inline VOID CChainPathObject::SetPass1DuplicateKeyDepth (IN DWORD dwDepth) { m_dwPass1DuplicateKeyDepth = dwDepth; }
//+---------------------------------------------------------------------------
//
// Member: CChainPathObject::IsCompleted, public
//
// Synopsis: returns TRUE if we have completed object initialization and
// the addition of all issuers. FALSE normally indicates a
// cyclic issuer.
//
//----------------------------------------------------------------------------
inline BOOL CChainPathObject::IsCompleted () { return m_fCompleted; }
//+---------------------------------------------------------------------------
//
// Member: CChainPathObject::HasAdditionalStatus, public
//
// Synopsis: returns HasAdditionalStatus flag value
//
//----------------------------------------------------------------------------
inline BOOL CChainPathObject::HasAdditionalStatus () { return( m_fHasAdditionalStatus ); }
//+---------------------------------------------------------------------------
//
// Member: CChainPathObject::DownPathObject, public
//
// Synopsis: returns this object's down path object
//
//----------------------------------------------------------------------------
inline PCCHAINPATHOBJECT CChainPathObject::DownPathObject () { return( m_pDownPathObject ); }
//+---------------------------------------------------------------------------
//
// Member: CChainPathObject::UpIssuerElement, public
//
// Synopsis: returns this object's up issuer element.
//
//----------------------------------------------------------------------------
inline PCERT_ISSUER_ELEMENT CChainPathObject::UpIssuerElement () { return( m_pUpIssuerElement ); }
//+---------------------------------------------------------------------------
//
// Member: CCertIssuerList::IsEmpty, public
//
// Synopsis: is the issuer list empty
//
//----------------------------------------------------------------------------
inline BOOL CCertIssuerList::IsEmpty () { return( m_pHead == NULL ); }
//+---------------------------------------------------------------------------
//
// Member: CCertIssuerList::AddElement, public
//
// Synopsis: add an element to the list
//
//----------------------------------------------------------------------------
inline VOID CCertIssuerList::AddElement (IN PCERT_ISSUER_ELEMENT pElement) { pElement->pNextElement = m_pHead; pElement->pPrevElement = NULL;
if ( m_pHead != NULL ) { m_pHead->pPrevElement = pElement; }
m_pHead = pElement; }
//+---------------------------------------------------------------------------
//
// Member: CCertIssuerList::RemoveElement, public
//
// Synopsis: remove an element from the list
//
//----------------------------------------------------------------------------
inline VOID CCertIssuerList::RemoveElement (IN PCERT_ISSUER_ELEMENT pElement) { if ( pElement->pPrevElement != NULL ) { pElement->pPrevElement->pNextElement = pElement->pNextElement; }
if ( pElement->pNextElement != NULL ) { pElement->pNextElement->pPrevElement = pElement->pPrevElement; }
if ( pElement == m_pHead ) { m_pHead = pElement->pNextElement; }
#if DBG
pElement->pPrevElement = NULL; pElement->pNextElement = NULL; #endif
}
//+---------------------------------------------------------------------------
//
// Member: CCertIssuerList::NextElement, public
//
// Synopsis: return the next element, if pElement == NULL the first element
// is returned
//
//----------------------------------------------------------------------------
inline PCERT_ISSUER_ELEMENT CCertIssuerList::NextElement (IN PCERT_ISSUER_ELEMENT pElement) { if ( pElement == NULL ) { return( m_pHead ); }
return( pElement->pNextElement ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObjectCache::HashIndex, public
//
// Synopsis: return the hash index
//
//----------------------------------------------------------------------------
inline HLRUCACHE CCertObjectCache::HashIndex () { return( m_hHashIndex ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObjectCache::IdentifierIndex, public
//
// Synopsis: return the identifier index
//
//----------------------------------------------------------------------------
inline HLRUCACHE CCertObjectCache::IdentifierIndex () { return( m_hIdentifierIndex ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObjectCache::SubjectNameIndex, public
//
// Synopsis: return the subject name index
//
//----------------------------------------------------------------------------
inline HLRUCACHE CCertObjectCache::SubjectNameIndex () { return( m_hSubjectNameIndex ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObjectCache::KeyIdIndex, public
//
// Synopsis: return the key identifier index
//
//----------------------------------------------------------------------------
inline HLRUCACHE CCertObjectCache::KeyIdIndex () { return( m_hKeyIdIndex ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObjectCache::PublicKeyHashIndex, public
//
// Synopsis: return the hash index
//
//----------------------------------------------------------------------------
inline HLRUCACHE CCertObjectCache::PublicKeyHashIndex () { return( m_hPublicKeyHashIndex ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObjectCache::EndHashIndex, public
//
// Synopsis: return the end hash index
//
//----------------------------------------------------------------------------
inline HLRUCACHE CCertObjectCache::EndHashIndex () { return( m_hEndHashIndex ); }
//+---------------------------------------------------------------------------
//
// Member: CCertObjectCache::FlushObjects, public
//
// Synopsis: flush the cache of issuer and end objects
//
//----------------------------------------------------------------------------
inline VOID CCertObjectCache::FlushObjects (IN PCCHAINCALLCONTEXT pCallContext) { I_CryptFlushLruCache( m_hHashIndex, 0, pCallContext ); I_CryptFlushLruCache( m_hEndHashIndex, 0, pCallContext );
}
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::LockEngine, public
//
// Synopsis: acquire the engine lock
//
//----------------------------------------------------------------------------
inline VOID CCertChainEngine::LockEngine () { EnterCriticalSection( &m_Lock ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::UnlockEngine, public
//
// Synopsis: release the engine lock
//
//----------------------------------------------------------------------------
inline VOID CCertChainEngine::UnlockEngine () { LeaveCriticalSection( &m_Lock ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::AddRef, public
//
// Synopsis: increment the reference count
//
//----------------------------------------------------------------------------
inline VOID CCertChainEngine::AddRef () { InterlockedIncrement( &m_cRefs ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::Release, public
//
// Synopsis: decrement the reference count
//
//----------------------------------------------------------------------------
inline VOID CCertChainEngine::Release () { if ( InterlockedDecrement( &m_cRefs ) == 0 ) { delete this; } }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::CertObjectCache, public
//
// Synopsis: return the certificate object cache
//
//----------------------------------------------------------------------------
inline PCCERTOBJECTCACHE CCertChainEngine::CertObjectCache () { return( m_pCertObjectCache ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::SSCtlObjectCache, public
//
// Synopsis: return the self signed certificate trust list object cache
//
//----------------------------------------------------------------------------
inline PCSSCTLOBJECTCACHE CCertChainEngine::SSCtlObjectCache () { return( m_pSSCtlObjectCache ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::RootStore, public
//
// Synopsis: return the configured root store
//
//----------------------------------------------------------------------------
inline HCERTSTORE CCertChainEngine::RootStore () { return( m_hRootStore ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::RealRootStore, public
//
// Synopsis: return the real root store
//
//----------------------------------------------------------------------------
inline HCERTSTORE CCertChainEngine::RealRootStore () { return( m_hRealRootStore ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::TrustStore, public
//
// Synopsis: return the configured trust store
//
//----------------------------------------------------------------------------
inline HCERTSTORE CCertChainEngine::TrustStore () { return( m_hTrustStore ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::OtherStore, public
//
// Synopsis: return the configured other store
//
//----------------------------------------------------------------------------
inline HCERTSTORE CCertChainEngine::OtherStore () { return( m_hOtherStore ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::CAStore, public
//
// Synopsis: return the opened CA store, NOTE: this could be NULL!
//
//----------------------------------------------------------------------------
inline HCERTSTORE CCertChainEngine::CAStore () { return( m_hCAStore ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::DisallowedStore, public
//
// Synopsis: return the opened Disallowed store, NOTE: this could be NULL!
//
//----------------------------------------------------------------------------
inline HCERTSTORE CCertChainEngine::DisallowedStore () { return( m_hDisallowedStore ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::OpenTrustStore, public
//
// Synopsis: open's the engine's HKLM or HKCU "trust" store.
// Caller must close.
//
//----------------------------------------------------------------------------
inline HCERTSTORE CCertChainEngine::OpenTrustStore () { DWORD dwStoreFlags;
if ( m_dwFlags & CERT_CHAIN_USE_LOCAL_MACHINE_STORE ) { dwStoreFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE; } else { dwStoreFlags = CERT_SYSTEM_STORE_CURRENT_USER; }
return CertOpenStore( CERT_STORE_PROV_SYSTEM_W, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, dwStoreFlags | CERT_STORE_SHARE_CONTEXT_FLAG | CERT_STORE_SHARE_STORE_FLAG | CERT_STORE_MAXIMUM_ALLOWED_FLAG, L"trust" ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::UrlRetrievalTimeout, public
//
// Synopsis: return the engine's UrlRetrievalTimeout
//
//----------------------------------------------------------------------------
inline DWORD CCertChainEngine::UrlRetrievalTimeout () { return( m_dwUrlRetrievalTimeout ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::HasDefaultUrlRetrievalTimeout, public
//
// Synopsis: returns TRUE if the engine is using the default timeout
//
//----------------------------------------------------------------------------
inline BOOL CCertChainEngine::HasDefaultUrlRetrievalTimeout () { return( m_fDefaultUrlRetrievalTimeout ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::Flags, public
//
// Synopsis: return the engine's flags
//
//----------------------------------------------------------------------------
inline DWORD CCertChainEngine::Flags () { return( m_dwFlags ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::DisableMandatoryBasicConstraints, public
//
// Synopsis: return the engine's flags
//
//----------------------------------------------------------------------------
inline BOOL CCertChainEngine::DisableMandatoryBasicConstraints () { return( m_Config.fDisableMandatoryBasicConstraints ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::TouchEngineCount, public
//
// Synopsis: return the engine's touch count
//
//----------------------------------------------------------------------------
inline DWORD CCertChainEngine::TouchEngineCount () { return( m_dwTouchEngineCount ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::IncrementTouchEngineCount, public
//
// Synopsis: increment and return the engine's touch count
//
//----------------------------------------------------------------------------
inline DWORD CCertChainEngine::IncrementTouchEngineCount () { return( ++m_dwTouchEngineCount ); }
//+---------------------------------------------------------------------------
//
// Member: CCertChainEngine::AuthRootAutoUpdateInfo, public
//
// Synopsis: returns pointer to the engine's AuthRoot Auto Update Info
//
//----------------------------------------------------------------------------
inline PAUTH_ROOT_AUTO_UPDATE_INFO CCertChainEngine::AuthRootAutoUpdateInfo() { return m_pAuthRootAutoUpdateInfo; }
//+===========================================================================
// CCertObject helper functions
//============================================================================
BOOL WINAPI ChainCreateCertObject ( IN DWORD dwObjectType, IN PCCHAINCALLCONTEXT pCallContext, IN PCCERT_CONTEXT pCertContext, IN OPTIONAL LPBYTE pbCertHash, OUT PCCERTOBJECT *ppCertObject );
BOOL WINAPI ChainFillCertObjectCtlCacheEnumFn( IN LPVOID pvParameter, IN PCSSCTLOBJECT pSSCtlObject ); VOID WINAPI ChainFreeCertObjectCtlCache( IN PCERT_OBJECT_CTL_CACHE_ENTRY pCtlCacheHead );
LPVOID WINAPI ChainAllocAndDecodeObject( IN LPCSTR lpszStructType, IN const BYTE *pbEncoded, IN DWORD cbEncoded );
VOID WINAPI ChainGetIssuerMatchInfo ( IN PCCERT_CONTEXT pCertContext, OUT DWORD *pdwIssuerMatchFlags, OUT PCERT_AUTHORITY_KEY_ID_INFO* ppAuthKeyIdentifier );
BOOL WINAPI ChainConvertAuthKeyIdentifierFromV2ToV1 ( IN PCERT_AUTHORITY_KEY_ID2_INFO pAuthKeyIdentifier2, OUT PCERT_AUTHORITY_KEY_ID_INFO* ppAuthKeyIdentifier ); VOID WINAPI ChainFreeAuthorityKeyIdentifier ( IN PCERT_AUTHORITY_KEY_ID_INFO pAuthKeyIdInfo );
VOID WINAPI ChainProcessSpecialOrDuplicateOIDsInUsage ( IN OUT PCERT_ENHKEY_USAGE *ppUsage, IN OUT DWORD *pdwFlags );
VOID WINAPI ChainConvertPoliciesToUsage ( IN PCERT_POLICIES_INFO pPolicy, IN OUT DWORD *pdwFlags, OUT PCERT_ENHKEY_USAGE *ppUsage );
VOID WINAPI ChainRemoveDuplicatePolicyMappings ( IN OUT PCERT_POLICY_MAPPINGS_INFO pInfo );
VOID WINAPI ChainGetPoliciesInfo ( IN PCCERT_CONTEXT pCertContext, IN OUT PCHAIN_POLICIES_INFO pPoliciesInfo ); VOID WINAPI ChainFreePoliciesInfo ( IN OUT PCHAIN_POLICIES_INFO pPoliciesInfo );
BOOL WINAPI ChainGetBasicConstraintsInfo ( IN PCCERT_CONTEXT pCertContext, OUT PCERT_BASIC_CONSTRAINTS2_INFO *ppInfo );
VOID WINAPI ChainFreeBasicConstraintsInfo ( IN OUT PCERT_BASIC_CONSTRAINTS2_INFO pInfo );
BOOL WINAPI ChainGetKeyUsage ( IN PCCERT_CONTEXT pCertContext, OUT PCRYPT_BIT_BLOB *ppKeyUsage );
VOID WINAPI ChainFreeKeyUsage ( IN OUT PCRYPT_BIT_BLOB pKeyUsage );
VOID WINAPI ChainGetSelfSignedStatus ( IN PCCHAINCALLCONTEXT pCallContext, IN PCCERTOBJECT pCertObject, IN OUT DWORD *pdwIssuerStatusFlags ); VOID WINAPI ChainGetRootStoreStatus ( IN HCERTSTORE hRoot, IN HCERTSTORE hRealRoot, IN BYTE rgbCertHash[ CHAINHASHLEN ], IN OUT DWORD *pdwIssuerStatusFlags );
//+===========================================================================
// CCertObjectCache helper functions
//============================================================================
BOOL WINAPI ChainCreateCertificateObjectCache ( IN DWORD MaxIndexEntries, OUT PCCERTOBJECTCACHE* ppCertObjectCache );
VOID WINAPI ChainFreeCertificateObjectCache ( IN PCCERTOBJECTCACHE pCertObjectCache );
//
// Issuer Certificate Object Cache Primary Index Entry Removal Notification
//
// This should remove the relevant entries
// from the other indexes and release the reference on the certificate object
// maintained by the primary index.
//
VOID WINAPI CertObjectCacheOnRemovalFromPrimaryIndex ( IN LPVOID pv, IN LPVOID pvRemovalContext );
//
// End Certificate Object Cache Entry Removal Notification
//
VOID WINAPI CertObjectCacheOnRemovalFromEndHashIndex ( IN LPVOID pv, IN LPVOID pvRemovalContext );
//
// Certificate Object Cache Identifier Hashing Functions
//
DWORD WINAPI CertObjectCacheHashMd5Identifier ( IN PCRYPT_DATA_BLOB pIdentifier );
DWORD WINAPI CertObjectCacheHashNameIdentifier ( IN PCRYPT_DATA_BLOB pIdentifier );
VOID WINAPI ChainCreateCertificateObjectIdentifier ( IN PCERT_NAME_BLOB pIssuer, IN PCRYPT_INTEGER_BLOB pSerialNumber, OUT CERT_OBJECT_IDENTIFIER ObjectIdentifier );
//+===========================================================================
// CChainPathObject helper functions
//============================================================================
BOOL WINAPI ChainCreatePathObject ( IN PCCHAINCALLCONTEXT pCallContext, IN PCCERTOBJECT pCertObject, IN OPTIONAL HCERTSTORE hAdditionalStore, OUT PCCHAINPATHOBJECT *ppPathObject ); BOOL WINAPI ChainCreateCyclicPathObject ( IN PCCHAINCALLCONTEXT pCallContext, IN PCCHAINPATHOBJECT pPathObject, OUT PCCHAINPATHOBJECT *ppCyclicPathObject ); VOID WINAPI ChainDeleteCyclicPathObject ( IN PCCHAINCALLCONTEXT pCallContext, IN OUT PCCHAINPATHOBJECT pCyclicPathObject );
LPSTR WINAPI ChainAllocAndCopyOID ( IN LPSTR pszSrcOID ); VOID WINAPI ChainFreeOID ( IN OUT LPSTR pszOID );
BOOL WINAPI ChainAllocAndCopyUsage ( IN PCERT_ENHKEY_USAGE pSrcUsage, OUT PCERT_ENHKEY_USAGE *ppDstUsage ); VOID WINAPI ChainFreeUsage ( IN OUT PCERT_ENHKEY_USAGE pUsage );
BOOL WINAPI ChainIsOIDInUsage ( IN LPSTR pszOID, IN PCERT_ENHKEY_USAGE pUsage );
VOID WINAPI ChainIntersectUsages ( IN PCERT_ENHKEY_USAGE pCertUsage, IN OUT PCERT_ENHKEY_USAGE pRestrictedUsage );
VOID WINAPI ChainFreeAndClearRestrictedUsageInfo( IN OUT PCHAIN_RESTRICTED_USAGE_INFO pInfo );
BOOL WINAPI ChainCalculateRestrictedUsage ( IN PCERT_ENHKEY_USAGE pCertUsage, IN OPTIONAL PCERT_POLICY_MAPPINGS_INFO pMappings, IN OUT PCERT_ENHKEY_USAGE *ppRestrictedUsage, IN OUT PCERT_ENHKEY_USAGE *ppMappedUsage, IN OUT LPDWORD *ppdwMappedIndex );
VOID WINAPI ChainGetUsageStatus ( IN PCERT_ENHKEY_USAGE pRequestedUsage, IN PCERT_ENHKEY_USAGE pAvailableUsage, IN DWORD dwMatchType, IN OUT PCERT_TRUST_STATUS pStatus );
VOID WINAPI ChainOrInStatusBits ( IN PCERT_TRUST_STATUS pDestStatus, IN PCERT_TRUST_STATUS pSourceStatus );
BOOL WINAPI ChainGetMatchInfoStatus ( IN PCCERTOBJECT pIssuerObject, IN PCCERTOBJECT pSubjectObject, IN OUT DWORD *pdwInfoStatus ); DWORD WINAPI ChainGetMatchInfoStatusForNoIssuer ( IN DWORD dwIssuerMatchFlags );
BOOL WINAPI ChainIsValidPubKeyMatchForIssuer ( IN PCCERTOBJECT pIssuer, IN PCCERTOBJECT pSubject );
// Leaves Engine's lock to do signature verification
BOOL WINAPI ChainGetSubjectStatus ( IN PCCHAINCALLCONTEXT pCallContext, IN PCCHAINPATHOBJECT pIssuerPathObject, IN PCCHAINPATHOBJECT pSubjectPathObject, IN OUT PCERT_TRUST_STATUS pStatus );
VOID WINAPI ChainUpdateSummaryStatusByTrustStatus( IN OUT PCERT_TRUST_STATUS pSummaryStatus, IN PCERT_TRUST_STATUS pTrustStatus );
BOOL WINAPI ChainIsKeyRolloverSubject( IN PCCHAINPATHOBJECT pIssuerPathObject, IN PCCHAINPATHOBJECT pSubjectPathObject );
//+===========================================================================
// Format and append extended error information helper functions
//============================================================================
BOOL WINAPI ChainAllocAndEncodeObject( IN LPCSTR lpszStructType, IN const void *pvStructInfo, OUT BYTE **ppbEncoded, OUT DWORD *pcbEncoded );
VOID WINAPI ChainAppendExtendedErrorInfo( IN OUT LPWSTR *ppwszExtErrorInfo, IN LPWSTR pwszAppend, IN DWORD cchAppend // Includes NULL terminator
);
VOID WINAPI ChainFormatAndAppendExtendedErrorInfo( IN OUT LPWSTR *ppwszExtErrorInfo, IN UINT nFormatID, ... );
//+===========================================================================
// Name Constraint helper functions
//============================================================================
VOID WINAPI ChainRemoveLeadingAndTrailingWhiteSpace( IN LPWSTR pwszIn, OUT LPWSTR *ppwszOut, OUT DWORD *pcchOut );
BOOL WINAPI ChainIsRightStringInString( IN LPCWSTR pwszRight, IN DWORD cchRight, IN LPCWSTR pwszString, IN DWORD cchString );
BOOL WINAPI ChainIsSpecialAtCharacterMatch( IN LPCWSTR pwszRight, IN DWORD cchRight, IN LPCWSTR pwszString, IN DWORD cchString );
// pAltNameEntry->pOtherName->Value.cbData is set to the following when
// Value.pbData is updated to point to a CERT_NAME_VALUE fixup
#define CHAIN_OTHER_NAME_FIXUP_STRING_LENGTH 0xFFFFFFFF
// pAltNameEntry->pOtherName->Value.cbData less than or equal to the
// following length indicates an empty value. In a NameConstraint, it
// matches any Value.
#define CHAIN_OTHER_NAME_MAX_EMPTY_LENGTH 2
// Returns one of the following values:
// +1 - The encoded value is a string
// 0 - The encoded value is empty (takes precedence over being a string)
// -1 - The encoded value isn't a string
int WINAPI ChainIsEmptyOrStringEncodedValue( IN PCRYPT_OBJID_BLOB pEncodedValue );
BOOL WINAPI ChainFixupNameConstraintsOtherNameValue( IN OUT PCRYPT_OBJID_BLOB pOtherValue ); BOOL WINAPI ChainAllocDecodeAndFixupNameConstraintsDirectoryName( IN PCERT_NAME_BLOB pDirName, OUT PCERT_NAME_INFO *ppNameInfo ); BOOL WINAPI ChainFixupNameConstraintsAltNameEntry( IN BOOL fSubjectConstraint, IN OUT PCERT_ALT_NAME_ENTRY pEntry ); VOID WINAPI ChainFreeNameConstraintsAltNameEntryFixup( IN BOOL fSubjectConstraint, IN OUT PCERT_ALT_NAME_ENTRY pEntry );
LPWSTR WINAPI ChainFormatNameConstraintsAltNameEntryFixup( IN PCERT_ALT_NAME_ENTRY pEntry );
VOID WINAPI ChainFormatAndAppendNameConstraintsAltNameEntryFixup( IN OUT LPWSTR *ppwszExtErrorInfo, IN PCERT_ALT_NAME_ENTRY pEntry, IN UINT nFormatID, IN OPTIONAL DWORD dwSubtreeIndex = 0 // 0 => no subtree parameter
);
BOOL WINAPI ChainGetIssuerNameConstraintsInfo ( IN PCCERT_CONTEXT pCertContext, IN OUT PCERT_NAME_CONSTRAINTS_INFO *ppInfo ); VOID WINAPI ChainFreeIssuerNameConstraintsInfo ( IN OUT PCERT_NAME_CONSTRAINTS_INFO pInfo );
VOID WINAPI ChainGetSubjectNameConstraintsInfo ( IN PCCERT_CONTEXT pCertContext, IN OUT PCHAIN_SUBJECT_NAME_CONSTRAINTS_INFO pSubjectInfo ); VOID WINAPI ChainFreeSubjectNameConstraintsInfo ( IN OUT PCHAIN_SUBJECT_NAME_CONSTRAINTS_INFO pSubjectInfo );
BOOL WINAPI ChainCompareNameConstraintsDirectoryName( IN PCERT_NAME_INFO pSubjectInfo, IN PCERT_NAME_INFO pSubtreeInfo ); BOOL WINAPI ChainCompareNameConstraintsIPAddress( IN PCRYPT_DATA_BLOB pSubjectIPAddress, IN PCRYPT_DATA_BLOB pSubtreeIPAddress ); BOOL WINAPI ChainCompareNameConstraintsOtherNameValue( IN LPCSTR pszOtherNameOID, IN PCRYPT_OBJID_BLOB pSubjectValue, IN PCRYPT_OBJID_BLOB pSubtreeValue ); DWORD WINAPI ChainCalculateNameConstraintsSubtreeErrorStatusForAltNameEntry( IN PCERT_ALT_NAME_ENTRY pSubjectEntry, IN BOOL fExcludedSubtree, IN DWORD cSubtree, IN PCERT_GENERAL_SUBTREE pSubtree, IN OUT LPWSTR *ppwszExtErrorInfo ); DWORD WINAPI ChainCalculateNameConstraintsErrorStatusForAltNameEntry( IN PCERT_ALT_NAME_ENTRY pSubjectEntry, IN PCERT_NAME_CONSTRAINTS_INFO pNameConstraintsInfo, IN OUT LPWSTR *ppwszExtErrorInfo );
//+===========================================================================
// CCertIssuerList helper functions
//============================================================================
BOOL WINAPI ChainCreateIssuerList ( IN PCCHAINPATHOBJECT pSubject, OUT PCCERTISSUERLIST* ppIssuerList ); VOID WINAPI ChainFreeIssuerList ( IN PCCERTISSUERLIST pIssuerList );
VOID WINAPI ChainFreeCtlIssuerData ( IN PCTL_ISSUER_DATA pCtlIssuerData );
//+===========================================================================
// INTERNAL_CERT_CHAIN_CONTEXT helper functions
//============================================================================
VOID WINAPI ChainAddRefInternalChainContext ( IN PINTERNAL_CERT_CHAIN_CONTEXT pChainContext ); VOID WINAPI ChainReleaseInternalChainContext ( IN PINTERNAL_CERT_CHAIN_CONTEXT pChainContext ); VOID WINAPI ChainFreeInternalChainContext ( IN PINTERNAL_CERT_CHAIN_CONTEXT pContext );
VOID ChainUpdateEndEntityCertContext( IN OUT PINTERNAL_CERT_CHAIN_CONTEXT pChainContext, IN OUT PCCERT_CONTEXT pEndCertContext );
//+===========================================================================
// CERT_REVOCATION_INFO helper functions
//============================================================================
VOID WINAPI ChainUpdateRevocationInfo ( IN PCERT_REVOCATION_STATUS pRevStatus, IN OUT PCERT_REVOCATION_INFO pRevocationInfo, IN OUT PCERT_TRUST_STATUS pTrustStatus );
//+===========================================================================
// CCertChainEngine helper functions
//============================================================================
BOOL WINAPI ChainCreateWorldStore ( IN HCERTSTORE hRoot, IN HCERTSTORE hCA, IN DWORD cAdditionalStore, IN HCERTSTORE* rghAdditionalStore, IN DWORD dwStoreFlags, OUT HCERTSTORE* phWorld ); BOOL WINAPI ChainCreateEngineStore ( IN HCERTSTORE hRootStore, IN HCERTSTORE hTrustStore, IN HCERTSTORE hOtherStore, IN BOOL fDefaultEngine, IN DWORD dwFlags, OUT HCERTSTORE* phEngineStore, OUT HANDLE* phEngineStoreChangeEvent );
BOOL WINAPI ChainIsProperRestrictedRoot ( IN HCERTSTORE hRealRoot, IN HCERTSTORE hRestrictedRoot );
BOOL WINAPI ChainCreateCollectionIncludingCtlCertificates ( IN HCERTSTORE hStore, OUT HCERTSTORE* phCollection );
//+===========================================================================
// URL helper functions
//============================================================================
//
// Cryptnet Thunk Helper API
//
typedef BOOL (WINAPI *PFN_GETOBJECTURL) ( IN LPCSTR pszUrlOid, IN LPVOID pvPara, IN DWORD dwFlags, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN OPTIONAL LPVOID pvReserved );
BOOL WINAPI ChainGetObjectUrl ( IN LPCSTR pszUrlOid, IN LPVOID pvPara, IN DWORD dwFlags, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN OPTIONAL LPVOID pvReserved );
typedef BOOL (WINAPI *PFN_RETRIEVEOBJECTBYURLW) ( IN LPCWSTR pszUrl, IN LPCSTR pszObjectOid, IN DWORD dwRetrievalFlags, IN DWORD dwTimeout, OUT LPVOID* ppvObject, IN HCRYPTASYNC hAsyncRetrieve, IN PCRYPT_CREDENTIALS pCredentials, IN LPVOID pvVerify, IN OPTIONAL PCRYPT_RETRIEVE_AUX_INFO pAuxInfo );
BOOL WINAPI ChainRetrieveObjectByUrlW ( IN LPCWSTR pszUrl, IN LPCSTR pszObjectOid, IN DWORD dwRetrievalFlags, IN DWORD dwTimeout, OUT LPVOID* ppvObject, IN HCRYPTASYNC hAsyncRetrieve, IN PCRYPT_CREDENTIALS pCredentials, IN LPVOID pvVerify, IN OPTIONAL PCRYPT_RETRIEVE_AUX_INFO pAuxInfo );
BOOL WINAPI ChainIsConnected();
BOOL WINAPI ChainGetHostNameFromUrl ( IN LPWSTR pwszUrl, IN DWORD cchHostName, OUT LPWSTR pwszHostName );
HMODULE WINAPI ChainGetCryptnetModule ();
//
// URL helper
//
//
// Given the number of unsuccessful attempts to retrieve the Url, returns
// the number of seconds to wait before the next attempt.
//
DWORD WINAPI ChainGetOfflineUrlDeltaSeconds ( IN DWORD dwOfflineCnt );
//+===========================================================================
// Debug helper functions
//============================================================================
DWORD WINAPI ChainGetDebugFlags();
VOID WINAPI ChainOutputDebugStringA( LPCSTR lpOutputString );
//+===========================================================================
// AuthRoot Auto Update helper functions (chain.cpp)
//============================================================================
PAUTH_ROOT_AUTO_UPDATE_INFO WINAPI CreateAuthRootAutoUpdateInfo();
VOID WINAPI FreeAuthRootAutoUpdateInfo( IN OUT PAUTH_ROOT_AUTO_UPDATE_INFO pInfo );
BOOL WINAPI CreateAuthRootAutoUpdateMatchCaches( IN PCCTL_CONTEXT pCtl, IN OUT HLRUCACHE rghMatchCache[AUTH_ROOT_MATCH_CNT] );
VOID WINAPI FreeAuthRootAutoUpdateMatchCaches( IN OUT HLRUCACHE rghMatchCache[AUTH_ROOT_MATCH_CNT] );
#define SHA1_HASH_LEN 20
#define SHA1_HASH_NAME_LEN (2 * SHA1_HASH_LEN)
LPWSTR WINAPI FormatAuthRootAutoUpdateCertUrl( IN BYTE rgbSha1Hash[SHA1_HASH_LEN], IN PAUTH_ROOT_AUTO_UPDATE_INFO pInfo );
BOOL WINAPI ChainGetAuthRootAutoUpdateStatus ( IN PCCHAINCALLCONTEXT pCallContext, IN PCCERTOBJECT pCertObject, IN OUT DWORD *pdwIssuerStatusFlags );
//+===========================================================================
// AuthRoot Auto Update helper functions (extract.cpp)
//============================================================================
PCCTL_CONTEXT WINAPI ExtractAuthRootAutoUpdateCtlFromCab ( IN PCRYPT_BLOB_ARRAY pcbaCab );
#endif
|