ReactOS 0.4.15-dev-7788-g1ad9096
chain.c File Reference
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "wininet.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "crypt32_private.h"
Include dependency graph for chain.c:

Go to the source code of this file.

Classes

struct  _CertificateChainEngine
 
struct  _CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT
 
struct  _CertificateChain
 
struct  _CERT_CHAIN_PARA_NO_EXTRA_FIELDS
 

Macros

#define NONAMELESSUNION
 
#define CERT_CHAIN_PARA_HAS_EXTRA_FIELDS
 
#define CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS
 
#define DEFAULT_CYCLE_MODULUS   7
 
#define trace_usage_bit(bits, bit)    if ((bits) & (bit)) TRACE_(chain)("%s\n", #bit)
 
#define trace_cert_type_bit(bits, bit)    if ((bits) & (bit)) TRACE_(chain)("%s\n", #bit)
 
#define CHAIN_QUALITY_SIGNATURE_VALID   0x16
 
#define CHAIN_QUALITY_TIME_VALID   8
 
#define CHAIN_QUALITY_COMPLETE_CHAIN   4
 
#define CHAIN_QUALITY_BASIC_CONSTRAINTS   2
 
#define CHAIN_QUALITY_TRUSTED_ROOT   1
 
#define CHAIN_QUALITY_HIGHEST
 
#define IS_TRUST_ERROR_SET(TrustStatus, bits)    (TrustStatus)->dwErrorStatus & (bits)
 

Typedefs

typedef struct _CertificateChainEngine CertificateChainEngine
 
typedef struct _CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT
 
typedef struct _CertificateChain CertificateChain
 
typedef struct _CERT_CHAIN_PARA_NO_EXTRA_FIELDS CERT_CHAIN_PARA_NO_EXTRA_FIELDS
 
typedef BOOL(WINAPICertVerifyCertificateChainPolicyFunc) (LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (crypt)
 
 WINE_DECLARE_DEBUG_CHANNEL (chain)
 
static void CRYPT_AddStoresToCollection (HCERTSTORE collection, DWORD cStores, HCERTSTORE *stores)
 
static void CRYPT_CloseStores (DWORD cStores, HCERTSTORE *stores)
 
static PCCERT_CONTEXT CRYPT_FindCertInStore (HCERTSTORE store, PCCERT_CONTEXT cert)
 
static BOOL CRYPT_CheckRestrictedRoot (HCERTSTORE store)
 
HCERTCHAINENGINE CRYPT_CreateChainEngine (HCERTSTORE root, DWORD system_store, const CERT_CHAIN_ENGINE_CONFIG *config)
 
static CertificateChainEngineget_chain_engine (HCERTCHAINENGINE handle, BOOL allow_default)
 
static void free_chain_engine (CertificateChainEngine *engine)
 
BOOL WINAPI CertCreateCertificateChainEngine (PCERT_CHAIN_ENGINE_CONFIG pConfig, HCERTCHAINENGINE *phChainEngine)
 
void WINAPI CertFreeCertificateChainEngine (HCERTCHAINENGINE hChainEngine)
 
void default_chain_engine_free (void)
 
DWORD CRYPT_IsCertificateSelfSigned (const CERT_CONTEXT *cert)
 
static void CRYPT_FreeChainElement (PCERT_CHAIN_ELEMENT element)
 
static void CRYPT_CheckSimpleChainForCycles (PCERT_SIMPLE_CHAIN chain)
 
static BOOL CRYPT_IsSimpleChainCyclic (const CERT_SIMPLE_CHAIN *chain)
 
static void CRYPT_CombineTrustStatus (CERT_TRUST_STATUS *chainStatus, const CERT_TRUST_STATUS *elementStatus)
 
static BOOL CRYPT_AddCertToSimpleChain (const CertificateChainEngine *engine, PCERT_SIMPLE_CHAIN chain, PCCERT_CONTEXT cert, DWORD subjectInfoStatus)
 
static void CRYPT_FreeSimpleChain (PCERT_SIMPLE_CHAIN chain)
 
static void CRYPT_CheckTrustedStatus (HCERTSTORE hRoot, PCERT_CHAIN_ELEMENT rootElement)
 
static void CRYPT_CheckRootCert (HCERTSTORE hRoot, PCERT_CHAIN_ELEMENT rootElement)
 
static BOOL CRYPT_DecodeBasicConstraints (PCCERT_CONTEXT cert, CERT_BASIC_CONSTRAINTS2_INFO *constraints, BOOL defaultIfNotSpecified)
 
static BOOL CRYPT_CheckBasicConstraintsForCA (CertificateChainEngine *engine, PCCERT_CONTEXT cert, CERT_BASIC_CONSTRAINTS2_INFO *chainConstraints, DWORD remainingCAs, BOOL isRoot, BOOL *pathLengthConstraintViolated)
 
static BOOL domain_name_matches (LPCWSTR constraint, LPCWSTR name)
 
static BOOL url_matches (LPCWSTR constraint, LPCWSTR name, DWORD *trustErrorStatus)
 
static BOOL rfc822_name_matches (LPCWSTR constraint, LPCWSTR name, DWORD *trustErrorStatus)
 
static BOOL dns_name_matches (LPCWSTR constraint, LPCWSTR name, DWORD *trustErrorStatus)
 
static BOOL ip_address_matches (const CRYPT_DATA_BLOB *constraint, const CRYPT_DATA_BLOB *name, DWORD *trustErrorStatus)
 
static BOOL directory_name_matches (const CERT_NAME_BLOB *constraint, const CERT_NAME_BLOB *name)
 
static BOOL alt_name_matches (const CERT_ALT_NAME_ENTRY *name, const CERT_ALT_NAME_ENTRY *constraint, DWORD *trustErrorStatus, BOOL *present)
 
static BOOL alt_name_matches_excluded_name (const CERT_ALT_NAME_ENTRY *name, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
 
static BOOL alt_name_matches_permitted_name (const CERT_ALT_NAME_ENTRY *name, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus, BOOL *present)
 
static PCERT_EXTENSION get_subject_alt_name_ext (const CERT_INFO *cert)
 
static void compare_alt_name_with_constraints (const CERT_EXTENSION *altNameExt, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
 
static BOOL rfc822_attr_matches_excluded_name (const CERT_RDN_ATTR *attr, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
 
static BOOL rfc822_attr_matches_permitted_name (const CERT_RDN_ATTR *attr, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus, BOOL *present)
 
static void compare_subject_with_email_constraints (const CERT_NAME_BLOB *subjectName, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
 
static BOOL CRYPT_IsEmptyName (const CERT_NAME_BLOB *name)
 
static void compare_subject_with_constraints (const CERT_NAME_BLOB *subjectName, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
 
static void CRYPT_CheckNameConstraints (const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, const CERT_INFO *cert, DWORD *trustErrorStatus)
 
static CERT_NAME_CONSTRAINTS_INFOCRYPT_GetNameConstraints (CERT_INFO *cert)
 
static BOOL CRYPT_IsValidNameConstraint (const CERT_NAME_CONSTRAINTS_INFO *info)
 
static void CRYPT_CheckChainNameConstraints (PCERT_SIMPLE_CHAIN chain)
 
static CERT_POLICIES_INFOCRYPT_GetPolicies (PCCERT_CONTEXT cert)
 
static void CRYPT_CheckPolicies (const CERT_POLICIES_INFO *policies, CERT_INFO *cert, DWORD *errorStatus)
 
static void CRYPT_CheckChainPolicies (PCERT_SIMPLE_CHAIN chain)
 
static LPWSTR name_value_to_str (const CERT_NAME_BLOB *name)
 
static void dump_alt_name_entry (const CERT_ALT_NAME_ENTRY *entry)
 
static void dump_alt_name (LPCSTR type, const CERT_EXTENSION *ext)
 
static void dump_basic_constraints (const CERT_EXTENSION *ext)
 
static void dump_basic_constraints2 (const CERT_EXTENSION *ext)
 
static void dump_key_usage (const CERT_EXTENSION *ext)
 
static void dump_general_subtree (const CERT_GENERAL_SUBTREE *subtree)
 
static void dump_name_constraints (const CERT_EXTENSION *ext)
 
static void dump_cert_policies (const CERT_EXTENSION *ext)
 
static void dump_enhanced_key_usage (const CERT_EXTENSION *ext)
 
static void dump_netscape_cert_type (const CERT_EXTENSION *ext)
 
static void dump_extension (const CERT_EXTENSION *ext)
 
static LPCSTR filetime_to_str (const FILETIME *time)
 
static void dump_element (PCCERT_CONTEXT cert)
 
static BOOL CRYPT_KeyUsageValid (CertificateChainEngine *engine, PCCERT_CONTEXT cert, BOOL isRoot, BOOL isCA, DWORD index)
 
static BOOL CRYPT_CriticalExtensionsSupported (PCCERT_CONTEXT cert)
 
static BOOL CRYPT_IsCertVersionValid (PCCERT_CONTEXT cert)
 
static void CRYPT_CheckSimpleChain (CertificateChainEngine *engine, PCERT_SIMPLE_CHAIN chain, LPFILETIME time)
 
static PCCERT_CONTEXT CRYPT_FindIssuer (const CertificateChainEngine *engine, const CERT_CONTEXT *cert, HCERTSTORE store, DWORD type, void *para, DWORD flags, PCCERT_CONTEXT prev_issuer)
 
static PCCERT_CONTEXT CRYPT_GetIssuer (const CertificateChainEngine *engine, HCERTSTORE store, PCCERT_CONTEXT subject, PCCERT_CONTEXT prevIssuer, DWORD flags, DWORD *infoStatus)
 
static BOOL CRYPT_BuildSimpleChain (const CertificateChainEngine *engine, HCERTSTORE world, DWORD flags, PCERT_SIMPLE_CHAIN chain)
 
static LPCSTR debugstr_filetime (LPFILETIME pTime)
 
static BOOL CRYPT_GetSimpleChainForCert (CertificateChainEngine *engine, HCERTSTORE world, PCCERT_CONTEXT cert, LPFILETIME pTime, DWORD flags, PCERT_SIMPLE_CHAIN *ppChain)
 
static BOOL CRYPT_BuildCandidateChainFromCert (CertificateChainEngine *engine, PCCERT_CONTEXT cert, LPFILETIME pTime, HCERTSTORE hAdditionalStore, DWORD flags, CertificateChain **ppChain)
 
static PCERT_SIMPLE_CHAIN CRYPT_CopySimpleChainToElement (const CERT_SIMPLE_CHAIN *chain, DWORD iElement)
 
static void CRYPT_FreeLowerQualityChains (CertificateChain *chain)
 
static void CRYPT_FreeChainContext (CertificateChain *chain)
 
static CertificateChainCRYPT_CopyChainToElement (CertificateChain *chain, DWORD iChain, DWORD iElement)
 
static CertificateChainCRYPT_BuildAlternateContextFromChain (CertificateChainEngine *engine, LPFILETIME pTime, HCERTSTORE hAdditionalStore, DWORD flags, CertificateChain *chain)
 
static DWORD CRYPT_ChainQuality (const CertificateChain *chain)
 
static CertificateChainCRYPT_ChooseHighestQualityChain (CertificateChain *chain)
 
static BOOL CRYPT_AddAlternateChainToChain (CertificateChain *chain, const CertificateChain *alternate)
 
static PCERT_CHAIN_ELEMENT CRYPT_FindIthElementInChain (const CERT_CHAIN_CONTEXT *chain, DWORD i)
 
static void CRYPT_VerifyChainRevocation (PCERT_CHAIN_CONTEXT chain, LPFILETIME pTime, HCERTSTORE hAdditionalStore, const CERT_CHAIN_PARA *pChainPara, DWORD chainFlags)
 
static void CRYPT_CheckUsages (PCERT_CHAIN_CONTEXT chain, const CERT_CHAIN_PARA *pChainPara)
 
static void dump_usage_match (LPCSTR name, const CERT_USAGE_MATCH *usageMatch)
 
static void dump_chain_para (const CERT_CHAIN_PARA *pChainPara)
 
BOOL WINAPI CertGetCertificateChain (HCERTCHAINENGINE hChainEngine, PCCERT_CONTEXT pCertContext, LPFILETIME pTime, HCERTSTORE hAdditionalStore, PCERT_CHAIN_PARA pChainPara, DWORD dwFlags, LPVOID pvReserved, PCCERT_CHAIN_CONTEXT *ppChainContext)
 
PCCERT_CHAIN_CONTEXT WINAPI CertDuplicateCertificateChain (PCCERT_CHAIN_CONTEXT pChainContext)
 
VOID WINAPI CertFreeCertificateChain (PCCERT_CHAIN_CONTEXT pChainContext)
 
PCCERT_CHAIN_CONTEXT WINAPI CertFindChainInStore (HCERTSTORE store, DWORD certEncodingType, DWORD findFlags, DWORD findType, const void *findPara, PCCERT_CHAIN_CONTEXT prevChainContext)
 
static void find_element_with_error (PCCERT_CHAIN_CONTEXT chain, DWORD error, LONG *iChain, LONG *iElement)
 
static BOOL WINAPI verify_base_policy (LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
 
static void dump_authenticode_extra_chain_policy_para (AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA *extraPara)
 
static BOOL WINAPI verify_authenticode_policy (LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
 
static BOOL WINAPI verify_basic_constraints_policy (LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
 
static BOOL match_dns_to_subject_alt_name (const CERT_EXTENSION *ext, LPCWSTR server_name)
 
static BOOL find_matching_domain_component (const CERT_NAME_INFO *name, LPCWSTR component)
 
static BOOL match_domain_component (LPCWSTR allowed_component, DWORD allowed_len, LPCWSTR server_component, DWORD server_len, BOOL allow_wildcards, BOOL *see_wildcard)
 
static BOOL match_common_name (LPCWSTR server_name, const CERT_RDN_ATTR *nameAttr)
 
static BOOL match_dns_to_subject_dn (PCCERT_CONTEXT cert, LPCWSTR server_name)
 
static void dump_ssl_extra_chain_policy_para (HTTPSPolicyCallbackData *sslPara)
 
static BOOL WINAPI verify_ssl_policy (LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
 
static BOOL WINAPI verify_ms_root_policy (LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
 
static void dump_policy_para (PCERT_CHAIN_POLICY_PARA para)
 
BOOL WINAPI CertVerifyCertificateChainPolicy (LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
 

Variables

static const WCHAR rootW [] = { 'R','o','o','t',0 }
 
static CertificateChainEnginedefault_cu_engine
 
static CertificateChainEnginedefault_lm_engine
 
static BYTE msTestPubKey1 []
 
static BYTE msTestPubKey2 []
 
static BYTE msPubKey1 []
 
static BYTE msPubKey2 []
 
static BYTE msPubKey3 []
 

Macro Definition Documentation

◆ CERT_CHAIN_PARA_HAS_EXTRA_FIELDS

#define CERT_CHAIN_PARA_HAS_EXTRA_FIELDS

Definition at line 23 of file chain.c.

◆ CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS

#define CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS

Definition at line 24 of file chain.c.

◆ CHAIN_QUALITY_BASIC_CONSTRAINTS

#define CHAIN_QUALITY_BASIC_CONSTRAINTS   2

Definition at line 2517 of file chain.c.

◆ CHAIN_QUALITY_COMPLETE_CHAIN

#define CHAIN_QUALITY_COMPLETE_CHAIN   4

Definition at line 2516 of file chain.c.

◆ CHAIN_QUALITY_HIGHEST

#define CHAIN_QUALITY_HIGHEST
Value:
#define CHAIN_QUALITY_SIGNATURE_VALID
Definition: chain.c:2514
#define CHAIN_QUALITY_TRUSTED_ROOT
Definition: chain.c:2518
#define CHAIN_QUALITY_TIME_VALID
Definition: chain.c:2515
#define CHAIN_QUALITY_BASIC_CONSTRAINTS
Definition: chain.c:2517
#define CHAIN_QUALITY_COMPLETE_CHAIN
Definition: chain.c:2516

Definition at line 2520 of file chain.c.

◆ CHAIN_QUALITY_SIGNATURE_VALID

#define CHAIN_QUALITY_SIGNATURE_VALID   0x16

Definition at line 2514 of file chain.c.

◆ CHAIN_QUALITY_TIME_VALID

#define CHAIN_QUALITY_TIME_VALID   8

Definition at line 2515 of file chain.c.

◆ CHAIN_QUALITY_TRUSTED_ROOT

#define CHAIN_QUALITY_TRUSTED_ROOT   1

Definition at line 2518 of file chain.c.

◆ DEFAULT_CYCLE_MODULUS

#define DEFAULT_CYCLE_MODULUS   7

Definition at line 34 of file chain.c.

◆ IS_TRUST_ERROR_SET

#define IS_TRUST_ERROR_SET (   TrustStatus,
  bits 
)     (TrustStatus)->dwErrorStatus & (bits)

Definition at line 2525 of file chain.c.

◆ NONAMELESSUNION

#define NONAMELESSUNION

Definition at line 20 of file chain.c.

◆ trace_cert_type_bit

#define trace_cert_type_bit (   bits,
  bit 
)     if ((bits) & (bit)) TRACE_(chain)("%s\n", #bit)

◆ trace_usage_bit

#define trace_usage_bit (   bits,
  bit 
)     if ((bits) & (bit)) TRACE_(chain)("%s\n", #bit)

Typedef Documentation

◆ CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT

◆ CERT_CHAIN_PARA_NO_EXTRA_FIELDS

◆ CertificateChain

◆ CertificateChainEngine

◆ CertVerifyCertificateChainPolicyFunc

typedef BOOL(WINAPI * CertVerifyCertificateChainPolicyFunc) (LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)

Definition at line 3702 of file chain.c.

Function Documentation

◆ alt_name_matches()

static BOOL alt_name_matches ( const CERT_ALT_NAME_ENTRY name,
const CERT_ALT_NAME_ENTRY constraint,
DWORD trustErrorStatus,
BOOL present 
)
static

Definition at line 886 of file chain.c.

888{
889 BOOL match = FALSE;
890
891 if (name->dwAltNameChoice == constraint->dwAltNameChoice)
892 {
893 if (present)
894 *present = TRUE;
895 switch (constraint->dwAltNameChoice)
896 {
898 match = rfc822_name_matches(constraint->u.pwszURL,
899 name->u.pwszURL, trustErrorStatus);
900 break;
902 match = dns_name_matches(constraint->u.pwszURL,
903 name->u.pwszURL, trustErrorStatus);
904 break;
906 match = url_matches(constraint->u.pwszURL,
907 name->u.pwszURL, trustErrorStatus);
908 break;
910 match = ip_address_matches(&constraint->u.IPAddress,
911 &name->u.IPAddress, trustErrorStatus);
912 break;
915 &name->u.DirectoryName);
916 break;
917 default:
918 ERR("name choice %d unsupported in this context\n",
919 constraint->dwAltNameChoice);
920 *trustErrorStatus |=
922 }
923 }
924 else if (present)
925 *present = FALSE;
926 return match;
927}
#define ERR(fmt,...)
Definition: debug.h:110
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static BOOL url_matches(LPCWSTR constraint, LPCWSTR name, DWORD *trustErrorStatus)
Definition: chain.c:682
static BOOL ip_address_matches(const CRYPT_DATA_BLOB *constraint, const CRYPT_DATA_BLOB *name, DWORD *trustErrorStatus)
Definition: chain.c:820
static BOOL dns_name_matches(LPCWSTR constraint, LPCWSTR name, DWORD *trustErrorStatus)
Definition: chain.c:775
static BOOL rfc822_name_matches(LPCWSTR constraint, LPCWSTR name, DWORD *trustErrorStatus)
Definition: chain.c:751
static BOOL directory_name_matches(const CERT_NAME_BLOB *constraint, const CERT_NAME_BLOB *name)
Definition: chain.c:864
unsigned int BOOL
Definition: ntddk_ex.h:94
LPWSTR pwszURL
Definition: wincrypt.h:339
DWORD dwAltNameChoice
Definition: wincrypt.h:333
CRYPT_DATA_BLOB IPAddress
Definition: wincrypt.h:340
CERT_NAME_BLOB DirectoryName
Definition: wincrypt.h:338
Definition: match.c:28
Definition: name.c:39
#define CERT_ALT_NAME_URL
Definition: wincrypt.h:351
#define CERT_ALT_NAME_DIRECTORY_NAME
Definition: wincrypt.h:349
#define CERT_ALT_NAME_IP_ADDRESS
Definition: wincrypt.h:352
#define CERT_ALT_NAME_RFC822_NAME
Definition: wincrypt.h:346
#define CERT_ALT_NAME_DNS_NAME
Definition: wincrypt.h:347
#define CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT
Definition: wincrypt.h:882

Referenced by alt_name_matches_excluded_name(), and alt_name_matches_permitted_name().

◆ alt_name_matches_excluded_name()

static BOOL alt_name_matches_excluded_name ( const CERT_ALT_NAME_ENTRY name,
const CERT_NAME_CONSTRAINTS_INFO nameConstraints,
DWORD trustErrorStatus 
)
static

Definition at line 929 of file chain.c.

931{
932 DWORD i;
933 BOOL match = FALSE;
934
935 for (i = 0; !match && i < nameConstraints->cExcludedSubtree; i++)
937 &nameConstraints->rgExcludedSubtree[i].Base, trustErrorStatus, NULL);
938 return match;
939}
#define NULL
Definition: types.h:112
static BOOL alt_name_matches(const CERT_ALT_NAME_ENTRY *name, const CERT_ALT_NAME_ENTRY *constraint, DWORD *trustErrorStatus, BOOL *present)
Definition: chain.c:886
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
CERT_ALT_NAME_ENTRY Base
Definition: wincrypt.h:571
PCERT_GENERAL_SUBTREE rgExcludedSubtree
Definition: wincrypt.h:581

Referenced by compare_alt_name_with_constraints().

◆ alt_name_matches_permitted_name()

static BOOL alt_name_matches_permitted_name ( const CERT_ALT_NAME_ENTRY name,
const CERT_NAME_CONSTRAINTS_INFO nameConstraints,
DWORD trustErrorStatus,
BOOL present 
)
static

Definition at line 941 of file chain.c.

944{
945 DWORD i;
946 BOOL match = FALSE;
947
948 for (i = 0; !match && i < nameConstraints->cPermittedSubtree; i++)
950 &nameConstraints->rgPermittedSubtree[i].Base, trustErrorStatus,
951 present);
952 return match;
953}
PCERT_GENERAL_SUBTREE rgPermittedSubtree
Definition: wincrypt.h:579

Referenced by compare_alt_name_with_constraints().

◆ CertCreateCertificateChainEngine()

BOOL WINAPI CertCreateCertificateChainEngine ( PCERT_CHAIN_ENGINE_CONFIG  pConfig,
HCERTCHAINENGINE phChainEngine 
)

Definition at line 225 of file chain.c.

227{
228 BOOL ret;
229
230 TRACE("(%p, %p)\n", pConfig, phChainEngine);
231
233 && pConfig->cbSize != sizeof(CERT_CHAIN_ENGINE_CONFIG))
234 {
236 return FALSE;
237 }
239 if (!ret)
240 {
242 return FALSE;
243 }
244
246 return *phChainEngine != NULL;
247}
#define E_INVALIDARG
Definition: ddrawi.h:101
static BOOL CRYPT_CheckRestrictedRoot(HCERTSTORE store)
Definition: chain.c:89
HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, DWORD system_store, const CERT_CHAIN_ENGINE_CONFIG *config)
Definition: chain.c:115
#define SetLastError(x)
Definition: compat.h:752
#define TRACE(s)
Definition: solgame.cpp:4
HCERTSTORE hRestrictedRoot
Definition: wincrypt.h:3626
int ret
_Out_ HCERTCHAINENGINE * phChainEngine
Definition: wincrypt.h:4825
#define CERT_SYSTEM_STORE_CURRENT_USER
Definition: wincrypt.h:2324

Referenced by CRYPTDLG_MakeEngine(), and save_pfx().

◆ CertDuplicateCertificateChain()

PCCERT_CHAIN_CONTEXT WINAPI CertDuplicateCertificateChain ( PCCERT_CHAIN_CONTEXT  pChainContext)

Definition at line 2948 of file chain.c.

2950{
2951 CertificateChain *chain = (CertificateChain*)pChainContext;
2952
2953 TRACE("(%p)\n", pChainContext);
2954
2955 if (chain)
2957 return pChainContext;
2958}
#define InterlockedIncrement
Definition: armddk.h:53
struct sock * chain
Definition: tcpcore.h:1

Referenced by CRYPTDLG_CopyChain(), and InternetGetSecurityInfoByURLW().

◆ CertFindChainInStore()

PCCERT_CHAIN_CONTEXT WINAPI CertFindChainInStore ( HCERTSTORE  store,
DWORD  certEncodingType,
DWORD  findFlags,
DWORD  findType,
const void findPara,
PCCERT_CHAIN_CONTEXT  prevChainContext 
)

Definition at line 2973 of file chain.c.

2976{
2977 FIXME("(%p, %08x, %08x, %d, %p, %p): stub\n", store, certEncodingType,
2978 findFlags, findType, findPara, prevChainContext);
2979 return NULL;
2980}
#define FIXME(fmt,...)
Definition: debug.h:111

◆ CertFreeCertificateChain()

VOID WINAPI CertFreeCertificateChain ( PCCERT_CHAIN_CONTEXT  pChainContext)

Definition at line 2960 of file chain.c.

2961{
2962 CertificateChain *chain = (CertificateChain*)pChainContext;
2963
2964 TRACE("(%p)\n", pChainContext);
2965
2966 if (chain)
2967 {
2968 if (InterlockedDecrement(&chain->ref) == 0)
2970 }
2971}
#define InterlockedDecrement
Definition: armddk.h:52
static void CRYPT_FreeChainContext(CertificateChain *chain)
Definition: chain.c:2362

Referenced by _test_security_info(), CertGetCertificateChain(), CertTrustFinalPolicy(), check_and_store_certs(), CRYPT_FreeLowerQualityChains(), InitFunctionPtrs(), netconn_verify_cert(), save_cert_as_cms(), save_pfx(), server_release(), and SoftpubCleanup().

◆ CertFreeCertificateChainEngine()

void WINAPI CertFreeCertificateChainEngine ( HCERTCHAINENGINE  hChainEngine)

Definition at line 249 of file chain.c.

250{
251 TRACE("(%p)\n", hChainEngine);
253}
static CertificateChainEngine * get_chain_engine(HCERTCHAINENGINE handle, BOOL allow_default)
Definition: chain.c:166
static void free_chain_engine(CertificateChainEngine *engine)
Definition: chain.c:201

Referenced by CertTrustFinalPolicy(), check_and_store_certs(), get_chain_engine(), and save_pfx().

◆ CertGetCertificateChain()

BOOL WINAPI CertGetCertificateChain ( HCERTCHAINENGINE  hChainEngine,
PCCERT_CONTEXT  pCertContext,
LPFILETIME  pTime,
HCERTSTORE  hAdditionalStore,
PCERT_CHAIN_PARA  pChainPara,
DWORD  dwFlags,
LPVOID  pvReserved,
PCCERT_CHAIN_CONTEXT ppChainContext 
)

Definition at line 2879 of file chain.c.

2883{
2884 CertificateChainEngine *engine;
2885 BOOL ret;
2887
2888 TRACE("(%p, %p, %s, %p, %p, %08x, %p, %p)\n", hChainEngine, pCertContext,
2891
2892 engine = get_chain_engine(hChainEngine, TRUE);
2893 if (!engine)
2894 return FALSE;
2895
2896 if (ppChainContext)
2898 if (!pChainPara)
2899 {
2901 return FALSE;
2902 }
2904 {
2906 return FALSE;
2907 }
2908
2909 if (TRACE_ON(chain))
2911 /* FIXME: what about HCCE_LOCAL_MACHINE? */
2914 if (ret)
2915 {
2916 CertificateChain *alternate = NULL;
2917 PCERT_CHAIN_CONTEXT pChain;
2918
2919 do {
2920 alternate = CRYPT_BuildAlternateContextFromChain(engine,
2922
2923 /* Alternate contexts are added as "lower quality" contexts of
2924 * chain, to avoid loops in alternate chain creation.
2925 * The highest-quality chain is chosen at the end.
2926 */
2927 if (alternate)
2929 } while (ret && alternate);
2933 pChain = (PCERT_CHAIN_CONTEXT)chain;
2937 TRACE_(chain)("error status: %08x\n",
2938 pChain->TrustStatus.dwErrorStatus);
2939 if (ppChainContext)
2940 *ppChainContext = pChain;
2941 else
2943 }
2944 TRACE("returning %d\n", ret);
2945 return ret;
2946}
static BOOL CRYPT_BuildCandidateChainFromCert(CertificateChainEngine *engine, PCCERT_CONTEXT cert, LPFILETIME pTime, HCERTSTORE hAdditionalStore, DWORD flags, CertificateChain **ppChain)
Definition: chain.c:2251
static BOOL CRYPT_AddAlternateChainToChain(CertificateChain *chain, const CertificateChain *alternate)
Definition: chain.c:2586
static void CRYPT_VerifyChainRevocation(PCERT_CHAIN_CONTEXT chain, LPFILETIME pTime, HCERTSTORE hAdditionalStore, const CERT_CHAIN_PARA *pChainPara, DWORD chainFlags)
Definition: chain.c:2632
VOID WINAPI CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext)
Definition: chain.c:2960
static void CRYPT_FreeLowerQualityChains(CertificateChain *chain)
Definition: chain.c:2351
static void CRYPT_CheckUsages(PCERT_CHAIN_CONTEXT chain, const CERT_CHAIN_PARA *pChainPara)
Definition: chain.c:2745
static LPCSTR debugstr_filetime(LPFILETIME pTime)
Definition: chain.c:2213
static CertificateChain * CRYPT_BuildAlternateContextFromChain(CertificateChainEngine *engine, LPFILETIME pTime, HCERTSTORE hAdditionalStore, DWORD flags, CertificateChain *chain)
Definition: chain.c:2442
static CertificateChain * CRYPT_ChooseHighestQualityChain(CertificateChain *chain)
Definition: chain.c:2554
static void dump_chain_para(const CERT_CHAIN_PARA *pChainPara)
Definition: chain.c:2864
#define TRACE_(x)
Definition: compat.h:76
#define TRACE_ON(x)
Definition: compat.h:75
static LPCSTR DWORD void * pvReserved
Definition: str.c:196
CERT_TRUST_STATUS TrustStatus
Definition: wincrypt.h:939
PCERT_INFO pCertInfo
Definition: wincrypt.h:482
CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm
Definition: wincrypt.h:243
#define CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS
Definition: wincrypt.h:1064
_In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_opt_ HCERTSTORE _In_ PCERT_CHAIN_PARA pChainPara
Definition: wincrypt.h:4839
_In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_opt_ HCERTSTORE _In_ PCERT_CHAIN_PARA _In_ DWORD _Reserved_ LPVOID _Out_ PCCERT_CHAIN_CONTEXT * ppChainContext
Definition: wincrypt.h:4842
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ PCCERT_CONTEXT _In_opt_ LPFILETIME pTime
Definition: wincrypt.h:4837
_In_ PCCERT_CONTEXT pCertContext
Definition: wincrypt.h:4836
struct _CERT_CHAIN_CONTEXT * PCERT_CHAIN_CONTEXT
Definition: wincrypt.h:934
_In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_opt_ HCERTSTORE hAdditionalStore
Definition: wincrypt.h:4838
#define ERROR_INVALID_DATA
Definition: winerror.h:116

Referenced by CertTrustFinalPolicy(), check_and_store_certs(), netconn_verify_cert(), save_cert_as_cms(), save_pfx(), testGetCertChain(), and WINTRUST_CreateChainForSigner().

◆ CertVerifyCertificateChainPolicy()

BOOL WINAPI CertVerifyCertificateChainPolicy ( LPCSTR  szPolicyOID,
PCCERT_CHAIN_CONTEXT  pChainContext,
PCERT_CHAIN_POLICY_PARA  pPolicyPara,
PCERT_CHAIN_POLICY_STATUS  pPolicyStatus 
)

Definition at line 3716 of file chain.c.

3719{
3720 static HCRYPTOIDFUNCSET set = NULL;
3721 BOOL ret = FALSE;
3723 HCRYPTOIDFUNCADDR hFunc = NULL;
3724
3725 TRACE("(%s, %p, %p, %p)\n", debugstr_a(szPolicyOID), pChainContext,
3726 pPolicyPara, pPolicyStatus);
3727 if (TRACE_ON(chain))
3728 dump_policy_para(pPolicyPara);
3729
3730 if (IS_INTOID(szPolicyOID))
3731 {
3732 switch (LOWORD(szPolicyOID))
3733 {
3735 verifyPolicy = verify_base_policy;
3736 break;
3738 verifyPolicy = verify_authenticode_policy;
3739 break;
3741 verifyPolicy = verify_ssl_policy;
3742 break;
3744 verifyPolicy = verify_basic_constraints_policy;
3745 break;
3747 verifyPolicy = verify_ms_root_policy;
3748 break;
3749 default:
3750 FIXME("unimplemented for %d\n", LOWORD(szPolicyOID));
3751 }
3752 }
3753 if (!verifyPolicy)
3754 {
3755 if (!set)
3759 (void **)&verifyPolicy, &hFunc);
3760 }
3761 if (verifyPolicy)
3762 ret = verifyPolicy(szPolicyOID, pChainContext, pPolicyPara,
3763 pPolicyStatus);
3764 if (hFunc)
3766 TRACE("returning %d (%08x)\n", ret, pPolicyStatus->dwError);
3767 return ret;
3768}
Definition: _set.h:50
#define IS_INTOID(x)
static BOOL WINAPI verify_ms_root_policy(LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
Definition: chain.c:3665
static BOOL WINAPI verify_ssl_policy(LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
Definition: chain.c:3458
static BOOL WINAPI verify_basic_constraints_policy(LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
Definition: chain.c:3130
static void dump_policy_para(PCERT_CHAIN_POLICY_PARA para)
Definition: chain.c:3706
static BOOL WINAPI verify_base_policy(LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
Definition: chain.c:2998
static BOOL WINAPI verify_authenticode_policy(LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
Definition: chain.c:3089
BOOL(WINAPI * CertVerifyCertificateChainPolicyFunc)(LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
Definition: chain.c:3702
HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, DWORD dwFlags)
Definition: oid.c:114
BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr)
Definition: oid.c:387
BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, DWORD dwFlags)
Definition: oid.c:468
#define debugstr_a
Definition: kernel32.h:31
#define LOWORD(l)
Definition: pedump.c:82
#define CERT_CHAIN_POLICY_MICROSOFT_ROOT
Definition: wincrypt.h:968
#define CERT_CHAIN_POLICY_BASE
Definition: wincrypt.h:962
#define CERT_CHAIN_POLICY_BASIC_CONSTRAINTS
Definition: wincrypt.h:966
#define X509_ASN_ENCODING
Definition: wincrypt.h:2297
#define CERT_CHAIN_POLICY_AUTHENTICODE
Definition: wincrypt.h:963
#define CERT_CHAIN_POLICY_SSL
Definition: wincrypt.h:965
#define CRYPT_OID_VERIFY_CERTIFICATE_CHAIN_POLICY_FUNC
Definition: wincrypt.h:2506

Referenced by netconn_verify_cert(), SoftpubAuthenticode(), and WINTRUST_DefaultPolicy().

◆ compare_alt_name_with_constraints()

static void compare_alt_name_with_constraints ( const CERT_EXTENSION altNameExt,
const CERT_NAME_CONSTRAINTS_INFO nameConstraints,
DWORD trustErrorStatus 
)
static

Definition at line 967 of file chain.c.

969{
970 CERT_ALT_NAME_INFO *subjectAltName;
971 DWORD size;
972
974 altNameExt->Value.pbData, altNameExt->Value.cbData,
976 &subjectAltName, &size))
977 {
978 DWORD i;
979
980 for (i = 0; i < subjectAltName->cAltEntry; i++)
981 {
982 BOOL nameFormPresent;
983
984 /* A name constraint only applies if the name form is present.
985 * From RFC 5280, section 4.2.1.10:
986 * "Restrictions apply only when the specified name form is
987 * present. If no name of the type is in the certificate,
988 * the certificate is acceptable."
989 */
991 &subjectAltName->rgAltEntry[i], nameConstraints,
992 trustErrorStatus))
993 {
994 TRACE_(chain)("subject alternate name form %d excluded\n",
995 subjectAltName->rgAltEntry[i].dwAltNameChoice);
996 *trustErrorStatus |=
998 }
999 nameFormPresent = FALSE;
1001 &subjectAltName->rgAltEntry[i], nameConstraints,
1002 trustErrorStatus, &nameFormPresent) && nameFormPresent)
1003 {
1004 TRACE_(chain)("subject alternate name form %d not permitted\n",
1005 subjectAltName->rgAltEntry[i].dwAltNameChoice);
1006 *trustErrorStatus |=
1008 }
1009 }
1010 LocalFree(subjectAltName);
1011 }
1012 else
1013 *trustErrorStatus |=
1015}
BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
Definition: decode.c:6286
static BOOL alt_name_matches_excluded_name(const CERT_ALT_NAME_ENTRY *name, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
Definition: chain.c:929
static BOOL alt_name_matches_permitted_name(const CERT_ALT_NAME_ENTRY *name, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus, BOOL *present)
Definition: chain.c:941
GLsizeiptr size
Definition: glext.h:5919
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
PCERT_ALT_NAME_ENTRY rgAltEntry
Definition: wincrypt.h:357
CRYPT_OBJID_BLOB Value
Definition: wincrypt.h:232
BYTE * pbData
Definition: wincrypt.h:103
#define CRYPT_DECODE_NOCOPY_FLAG
Definition: wincrypt.h:3450
#define CERT_TRUST_INVALID_EXTENSION
Definition: wincrypt.h:878
#define CRYPT_DECODE_ALLOC_FLAG
Definition: wincrypt.h:3454
#define CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT
Definition: wincrypt.h:884
#define CERT_TRUST_INVALID_NAME_CONSTRAINTS
Definition: wincrypt.h:881
#define CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT
Definition: wincrypt.h:885
#define X509_ALTERNATE_NAME
Definition: wincrypt.h:3377

Referenced by CRYPT_CheckNameConstraints().

◆ compare_subject_with_constraints()

static void compare_subject_with_constraints ( const CERT_NAME_BLOB subjectName,
const CERT_NAME_CONSTRAINTS_INFO nameConstraints,
DWORD trustErrorStatus 
)
static

Definition at line 1126 of file chain.c.

1128{
1129 BOOL hasEmailConstraint = FALSE;
1130 DWORD i;
1131
1132 /* In general, a subject distinguished name only matches a directory name
1133 * constraint. However, an exception exists for email addresses.
1134 * From RFC 5280, section 4.2.1.6:
1135 * "Legacy implementations exist where an electronic mail address is
1136 * embedded in the subject distinguished name as an emailAddress
1137 * attribute [RFC2985]."
1138 * If an email address constraint exists, check that constraint separately.
1139 */
1140 for (i = 0; !hasEmailConstraint && i < nameConstraints->cExcludedSubtree;
1141 i++)
1142 if (nameConstraints->rgExcludedSubtree[i].Base.dwAltNameChoice ==
1144 hasEmailConstraint = TRUE;
1145 for (i = 0; !hasEmailConstraint && i < nameConstraints->cPermittedSubtree;
1146 i++)
1147 if (nameConstraints->rgPermittedSubtree[i].Base.dwAltNameChoice ==
1149 hasEmailConstraint = TRUE;
1150 if (hasEmailConstraint)
1152 trustErrorStatus);
1153 for (i = 0; i < nameConstraints->cExcludedSubtree; i++)
1154 {
1155 CERT_ALT_NAME_ENTRY *constraint =
1156 &nameConstraints->rgExcludedSubtree[i].Base;
1157
1158 if (constraint->dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME &&
1160 {
1161 TRACE_(chain)("subject name is excluded\n");
1162 *trustErrorStatus |=
1164 }
1165 }
1166 /* RFC 5280, section 4.2.1.10:
1167 * "Restrictions apply only when the specified name form is present.
1168 * If no name of the type is in the certificate, the certificate is
1169 * acceptable."
1170 * An empty name can't have the name form present, so don't check it.
1171 */
1172 if (nameConstraints->cPermittedSubtree && !CRYPT_IsEmptyName(subjectName))
1173 {
1174 BOOL match = FALSE, hasDirectoryConstraint = FALSE;
1175
1176 for (i = 0; !match && i < nameConstraints->cPermittedSubtree; i++)
1177 {
1178 CERT_ALT_NAME_ENTRY *constraint =
1179 &nameConstraints->rgPermittedSubtree[i].Base;
1180
1182 {
1183 hasDirectoryConstraint = TRUE;
1185 subjectName);
1186 }
1187 }
1188 if (hasDirectoryConstraint && !match)
1189 {
1190 TRACE_(chain)("subject name is not permitted\n");
1192 }
1193 }
1194}
static BOOL CRYPT_IsEmptyName(const CERT_NAME_BLOB *name)
Definition: chain.c:1110
static void compare_subject_with_email_constraints(const CERT_NAME_BLOB *subjectName, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
Definition: chain.c:1057
static BYTE subjectName[]
Definition: cert.c:63
Definition: wincrypt.h:332

Referenced by CRYPT_CheckNameConstraints().

◆ compare_subject_with_email_constraints()

static void compare_subject_with_email_constraints ( const CERT_NAME_BLOB subjectName,
const CERT_NAME_CONSTRAINTS_INFO nameConstraints,
DWORD trustErrorStatus 
)
static

Definition at line 1057 of file chain.c.

1060{
1062 DWORD size;
1063
1065 subjectName->pbData, subjectName->cbData,
1067 {
1068 DWORD i, j;
1069
1070 for (i = 0; i < name->cRDN; i++)
1071 for (j = 0; j < name->rgRDN[i].cRDNAttr; j++)
1072 if (!strcmp(name->rgRDN[i].rgRDNAttr[j].pszObjId,
1074 {
1075 BOOL nameFormPresent;
1076
1077 /* A name constraint only applies if the name form is
1078 * present. From RFC 5280, section 4.2.1.10:
1079 * "Restrictions apply only when the specified name form is
1080 * present. If no name of the type is in the certificate,
1081 * the certificate is acceptable."
1082 */
1084 &name->rgRDN[i].rgRDNAttr[j], nameConstraints,
1085 trustErrorStatus))
1086 {
1087 TRACE_(chain)(
1088 "email address in subject name is excluded\n");
1089 *trustErrorStatus |=
1091 }
1092 nameFormPresent = FALSE;
1094 &name->rgRDN[i].rgRDNAttr[j], nameConstraints,
1095 trustErrorStatus, &nameFormPresent) && nameFormPresent)
1096 {
1097 TRACE_(chain)(
1098 "email address in subject name is not permitted\n");
1099 *trustErrorStatus |=
1101 }
1102 }
1103 LocalFree(name);
1104 }
1105 else
1106 *trustErrorStatus |=
1108}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static BOOL rfc822_attr_matches_excluded_name(const CERT_RDN_ATTR *attr, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
Definition: chain.c:1017
static BOOL rfc822_attr_matches_permitted_name(const CERT_RDN_ATTR *attr, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus, BOOL *present)
Definition: chain.c:1035
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define X509_UNICODE_NAME
Definition: wincrypt.h:3385
#define szOID_RSA_emailAddr
Definition: wincrypt.h:3035

Referenced by compare_subject_with_constraints().

◆ CRYPT_AddAlternateChainToChain()

static BOOL CRYPT_AddAlternateChainToChain ( CertificateChain chain,
const CertificateChain alternate 
)
static

Definition at line 2586 of file chain.c.

2588{
2589 BOOL ret;
2590
2591 if (chain->context.cLowerQualityChainContext)
2592 chain->context.rgpLowerQualityChainContext =
2593 CryptMemRealloc(chain->context.rgpLowerQualityChainContext,
2594 (chain->context.cLowerQualityChainContext + 1) *
2595 sizeof(PCCERT_CHAIN_CONTEXT));
2596 else
2597 chain->context.rgpLowerQualityChainContext =
2599 if (chain->context.rgpLowerQualityChainContext)
2600 {
2601 chain->context.rgpLowerQualityChainContext[
2602 chain->context.cLowerQualityChainContext++] =
2603 (PCCERT_CHAIN_CONTEXT)alternate;
2604 ret = TRUE;
2605 }
2606 else
2607 ret = FALSE;
2608 return ret;
2609}
LPVOID WINAPI CryptMemAlloc(ULONG cbSize)
Definition: main.c:131
LPVOID WINAPI CryptMemRealloc(LPVOID pv, ULONG cbSize)
Definition: main.c:136
const CERT_CHAIN_CONTEXT * PCCERT_CHAIN_CONTEXT
Definition: wincrypt.h:935

Referenced by CertGetCertificateChain().

◆ CRYPT_AddCertToSimpleChain()

static BOOL CRYPT_AddCertToSimpleChain ( const CertificateChainEngine engine,
PCERT_SIMPLE_CHAIN  chain,
PCCERT_CONTEXT  cert,
DWORD  subjectInfoStatus 
)
static

Definition at line 427 of file chain.c.

429{
430 BOOL ret = FALSE;
432
433 if (element)
434 {
435 if (!chain->cElement)
436 chain->rgpElement = CryptMemAlloc(sizeof(PCERT_CHAIN_ELEMENT));
437 else
438 chain->rgpElement = CryptMemRealloc(chain->rgpElement,
439 (chain->cElement + 1) * sizeof(PCERT_CHAIN_ELEMENT));
440 if (chain->rgpElement)
441 {
442 chain->rgpElement[chain->cElement++] = element;
443 memset(element, 0, sizeof(CERT_CHAIN_ELEMENT));
444 element->cbSize = sizeof(CERT_CHAIN_ELEMENT);
446 if (chain->cElement > 1)
447 chain->rgpElement[chain->cElement - 2]->TrustStatus.dwInfoStatus
448 = subjectInfoStatus;
449 /* FIXME: initialize the rest of element */
450 if (!(chain->cElement % engine->CycleDetectionModulus))
451 {
453 /* Reinitialize the element pointer in case the chain is
454 * cyclic, in which case the chain is truncated.
455 */
456 element = chain->rgpElement[chain->cElement - 1];
457 }
458 CRYPT_CombineTrustStatus(&chain->TrustStatus,
459 &element->TrustStatus);
460 ret = TRUE;
461 }
462 else
464 }
465 return ret;
466}
PCCERT_CONTEXT WINAPI CertDuplicateCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:360
static void CRYPT_CheckSimpleChainForCycles(PCERT_SIMPLE_CHAIN chain)
Definition: chain.c:383
static void CRYPT_CombineTrustStatus(CERT_TRUST_STATUS *chainStatus, const CERT_TRUST_STATUS *elementStatus)
Definition: chain.c:416
VOID WINAPI CryptMemFree(LPVOID pv)
Definition: main.c:141
static BYTE cert[]
Definition: msg.c:1437
#define memset(x, y, z)
Definition: compat.h:39
DWORD CycleDetectionModulus
Definition: chain.c:49
struct _CERT_CHAIN_ELEMENT CERT_CHAIN_ELEMENT

Referenced by CRYPT_BuildAlternateContextFromChain(), CRYPT_BuildSimpleChain(), and CRYPT_GetSimpleChainForCert().

◆ CRYPT_AddStoresToCollection()

static void CRYPT_AddStoresToCollection ( HCERTSTORE  collection,
DWORD  cStores,
HCERTSTORE stores 
)
inlinestatic

Definition at line 52 of file chain.c.

54{
55 DWORD i;
56
57 for (i = 0; i < cStores; i++)
59}
BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
static ICollection collection
Definition: typelib.c:184

Referenced by CRYPT_CreateChainEngine().

◆ CRYPT_BuildAlternateContextFromChain()

static CertificateChain * CRYPT_BuildAlternateContextFromChain ( CertificateChainEngine engine,
LPFILETIME  pTime,
HCERTSTORE  hAdditionalStore,
DWORD  flags,
CertificateChain chain 
)
static

Definition at line 2442 of file chain.c.

2445{
2446 CertificateChain *alternate;
2447
2448 TRACE("(%p, %s, %p, %p)\n", engine, debugstr_filetime(pTime),
2450
2451 /* Always start with the last "lower quality" chain to ensure a consistent
2452 * order of alternate creation:
2453 */
2454 if (chain->context.cLowerQualityChainContext)
2455 chain = (CertificateChain*)chain->context.rgpLowerQualityChainContext[
2456 chain->context.cLowerQualityChainContext - 1];
2457 /* A chain with only one element can't have any alternates */
2458 if (chain->context.cChain <= 1 && chain->context.rgpChain[0]->cElement <= 1)
2459 alternate = NULL;
2460 else
2461 {
2462 DWORD i, j, infoStatus;
2463 PCCERT_CONTEXT alternateIssuer = NULL;
2464
2465 alternate = NULL;
2466 for (i = 0; !alternateIssuer && i < chain->context.cChain; i++)
2467 for (j = 0; !alternateIssuer &&
2468 j < chain->context.rgpChain[i]->cElement - 1; j++)
2469 {
2470 PCCERT_CONTEXT subject =
2471 chain->context.rgpChain[i]->rgpElement[j]->pCertContext;
2473 chain->context.rgpChain[i]->rgpElement[j + 1]->pCertContext);
2474
2475 alternateIssuer = CRYPT_GetIssuer(engine, prevIssuer->hCertStore,
2476 subject, prevIssuer, flags, &infoStatus);
2477 }
2478 if (alternateIssuer)
2479 {
2480 i--;
2481 j--;
2482 alternate = CRYPT_CopyChainToElement(chain, i, j);
2483 if (alternate)
2484 {
2486 alternate->context.rgpChain[i], alternateIssuer, infoStatus);
2487
2488 /* CRYPT_AddCertToSimpleChain add-ref's the issuer, so free it
2489 * to close the enumeration that found it
2490 */
2491 CertFreeCertificateContext(alternateIssuer);
2492 if (ret)
2493 {
2494 ret = CRYPT_BuildSimpleChain(engine, alternate->world,
2495 flags, alternate->context.rgpChain[i]);
2496 if (ret)
2498 alternate->context.rgpChain[i], pTime);
2500 &alternate->context.rgpChain[i]->TrustStatus);
2501 }
2502 if (!ret)
2503 {
2504 CRYPT_FreeChainContext(alternate);
2505 alternate = NULL;
2506 }
2507 }
2508 }
2509 }
2510 TRACE("%p\n", alternate);
2511 return alternate;
2512}
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
static BOOL CRYPT_AddCertToSimpleChain(const CertificateChainEngine *engine, PCERT_SIMPLE_CHAIN chain, PCCERT_CONTEXT cert, DWORD subjectInfoStatus)
Definition: chain.c:427
static CertificateChain * CRYPT_CopyChainToElement(CertificateChain *chain, DWORD iChain, DWORD iElement)
Definition: chain.c:2377
static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine, PCERT_SIMPLE_CHAIN chain, LPFILETIME time)
Definition: chain.c:1879
static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, HCERTSTORE store, PCCERT_CONTEXT subject, PCCERT_CONTEXT prevIssuer, DWORD flags, DWORD *infoStatus)
Definition: chain.c:2056
static BOOL CRYPT_BuildSimpleChain(const CertificateChainEngine *engine, HCERTSTORE world, DWORD flags, PCERT_SIMPLE_CHAIN chain)
Definition: chain.c:2181
GLbitfield flags
Definition: glext.h:7161
if(dx< 0)
Definition: linetemp.h:194
PCERT_SIMPLE_CHAIN * rgpChain
Definition: wincrypt.h:941
HCERTSTORE hCertStore
Definition: wincrypt.h:483
CERT_TRUST_STATUS TrustStatus
Definition: wincrypt.h:926
CERT_CHAIN_CONTEXT context
Definition: chain.c:263
HCERTSTORE world
Definition: chain.c:264

Referenced by CertGetCertificateChain().

◆ CRYPT_BuildCandidateChainFromCert()

static BOOL CRYPT_BuildCandidateChainFromCert ( CertificateChainEngine engine,
PCCERT_CONTEXT  cert,
LPFILETIME  pTime,
HCERTSTORE  hAdditionalStore,
DWORD  flags,
CertificateChain **  ppChain 
)
static

Definition at line 2251 of file chain.c.

2254{
2255 PCERT_SIMPLE_CHAIN simpleChain = NULL;
2256 HCERTSTORE world;
2257 BOOL ret;
2258
2261 CertAddStoreToCollection(world, engine->hWorld, 0, 0);
2262 if (hAdditionalStore)
2264 /* FIXME: only simple chains are supported for now, as CTLs aren't
2265 * supported yet.
2266 */
2267 if ((ret = CRYPT_GetSimpleChainForCert(engine, world, cert, pTime, flags, &simpleChain)))
2268 {
2270
2271 if (chain)
2272 {
2273 chain->ref = 1;
2274 chain->world = world;
2275 chain->context.cbSize = sizeof(CERT_CHAIN_CONTEXT);
2276 chain->context.TrustStatus = simpleChain->TrustStatus;
2277 chain->context.cChain = 1;
2278 chain->context.rgpChain = CryptMemAlloc(sizeof(PCERT_SIMPLE_CHAIN));
2279 chain->context.rgpChain[0] = simpleChain;
2280 chain->context.cLowerQualityChainContext = 0;
2281 chain->context.rgpLowerQualityChainContext = NULL;
2282 chain->context.fHasRevocationFreshnessTime = FALSE;
2283 chain->context.dwRevocationFreshnessTime = 0;
2284 }
2285 else
2286 {
2287 CRYPT_FreeSimpleChain(simpleChain);
2288 ret = FALSE;
2289 }
2290 *ppChain = chain;
2291 }
2292 return ret;
2293}
static void CRYPT_FreeSimpleChain(PCERT_SIMPLE_CHAIN chain)
Definition: chain.c:468
static BOOL CRYPT_GetSimpleChainForCert(CertificateChainEngine *engine, HCERTSTORE world, PCCERT_CONTEXT cert, LPFILETIME pTime, DWORD flags, PCERT_SIMPLE_CHAIN *ppChain)
Definition: chain.c:2220
HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const void *pvPara)
Definition: store.c:815
HCERTSTORE hWorld
Definition: chain.c:45
#define CERT_STORE_PROV_COLLECTION
Definition: wincrypt.h:2261
#define CERT_STORE_CREATE_NEW_FLAG
Definition: wincrypt.h:2464
struct _CERT_CHAIN_CONTEXT CERT_CHAIN_CONTEXT
Definition: wincrypt.h:934

Referenced by CertGetCertificateChain().

◆ CRYPT_BuildSimpleChain()

static BOOL CRYPT_BuildSimpleChain ( const CertificateChainEngine engine,
HCERTSTORE  world,
DWORD  flags,
PCERT_SIMPLE_CHAIN  chain 
)
static

Definition at line 2181 of file chain.c.

2183{
2184 BOOL ret = TRUE;
2185 PCCERT_CONTEXT cert = chain->rgpElement[chain->cElement - 1]->pCertContext;
2186
2187 while (ret && !CRYPT_IsSimpleChainCyclic(chain) &&
2189 {
2191 &chain->rgpElement[chain->cElement - 1]->TrustStatus.dwInfoStatus);
2192
2193 if (issuer)
2194 {
2196 chain->rgpElement[chain->cElement - 1]->TrustStatus.dwInfoStatus);
2197 /* CRYPT_AddCertToSimpleChain add-ref's the issuer, so free it to
2198 * close the enumeration that found it
2199 */
2201 cert = issuer;
2202 }
2203 else
2204 {
2205 TRACE_(chain)("Couldn't find issuer, halting chain creation\n");
2206 chain->TrustStatus.dwErrorStatus |= CERT_TRUST_IS_PARTIAL_CHAIN;
2207 break;
2208 }
2209 }
2210 return ret;
2211}
static BOOL CRYPT_IsSimpleChainCyclic(const CERT_SIMPLE_CHAIN *chain)
Definition: chain.c:407
DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert)
Definition: chain.c:268
static WCHAR issuer[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1905
#define CERT_TRUST_IS_PARTIAL_CHAIN
Definition: wincrypt.h:891

Referenced by CRYPT_BuildAlternateContextFromChain(), and CRYPT_GetSimpleChainForCert().

◆ CRYPT_ChainQuality()

static DWORD CRYPT_ChainQuality ( const CertificateChain chain)
static

Definition at line 2528 of file chain.c.

2529{
2531
2532 if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus,
2534 quality &= ~CHAIN_QUALITY_TRUSTED_ROOT;
2535 if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus,
2537 quality &= ~CHAIN_QUALITY_BASIC_CONSTRAINTS;
2538 if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus,
2540 quality &= ~CHAIN_QUALITY_COMPLETE_CHAIN;
2541 if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus,
2543 quality &= ~CHAIN_QUALITY_TIME_VALID;
2544 if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus,
2546 quality &= ~CHAIN_QUALITY_SIGNATURE_VALID;
2547 return quality;
2548}
#define CHAIN_QUALITY_HIGHEST
Definition: chain.c:2520
#define IS_TRUST_ERROR_SET(TrustStatus, bits)
Definition: chain.c:2525
int quality
Definition: jpeglib.h:992
#define CERT_TRUST_INVALID_BASIC_CONSTRAINTS
Definition: wincrypt.h:880
#define CERT_TRUST_IS_NOT_TIME_NESTED
Definition: wincrypt.h:871
#define CERT_TRUST_IS_NOT_SIGNATURE_VALID
Definition: wincrypt.h:873
#define CERT_TRUST_IS_UNTRUSTED_ROOT
Definition: wincrypt.h:875
#define CERT_TRUST_IS_NOT_TIME_VALID
Definition: wincrypt.h:870

Referenced by CRYPT_ChooseHighestQualityChain().

◆ CRYPT_CheckBasicConstraintsForCA()

static BOOL CRYPT_CheckBasicConstraintsForCA ( CertificateChainEngine engine,
PCCERT_CONTEXT  cert,
CERT_BASIC_CONSTRAINTS2_INFO chainConstraints,
DWORD  remainingCAs,
BOOL  isRoot,
BOOL pathLengthConstraintViolated 
)
static

Definition at line 580 of file chain.c.

583{
584 BOOL validBasicConstraints, implicitCA = FALSE;
586
587 if (isRoot)
588 implicitCA = TRUE;
589 else if (cert->pCertInfo->dwVersion == CERT_V1 ||
590 cert->pCertInfo->dwVersion == CERT_V2)
591 {
592 BYTE hash[20];
593 DWORD size = sizeof(hash);
594
596 hash, &size))
597 {
598 CRYPT_HASH_BLOB blob = { sizeof(hash), hash };
600 engine->hWorld, cert->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH,
601 &blob, NULL);
602
603 if (localCert)
604 {
606 implicitCA = TRUE;
607 }
608 }
609 }
610 if ((validBasicConstraints = CRYPT_DecodeBasicConstraints(cert,
611 &constraints, implicitCA)))
612 {
613 chainConstraints->fCA = constraints.fCA;
614 if (!constraints.fCA)
615 {
616 TRACE_(chain)("chain element %d can't be a CA\n", remainingCAs + 1);
617 validBasicConstraints = FALSE;
618 }
619 else if (constraints.fPathLenConstraint)
620 {
621 /* If the element has path length constraints, they apply to the
622 * entire remaining chain.
623 */
624 if (!chainConstraints->fPathLenConstraint ||
625 constraints.dwPathLenConstraint <
626 chainConstraints->dwPathLenConstraint)
627 {
628 TRACE_(chain)("setting path length constraint to %d\n",
629 chainConstraints->dwPathLenConstraint);
630 chainConstraints->fPathLenConstraint = TRUE;
631 chainConstraints->dwPathLenConstraint =
632 constraints.dwPathLenConstraint;
633 }
634 }
635 }
636 if (chainConstraints->fPathLenConstraint &&
637 remainingCAs > chainConstraints->dwPathLenConstraint)
638 {
639 TRACE_(chain)("remaining CAs %d exceed max path length %d\n",
640 remainingCAs, chainConstraints->dwPathLenConstraint);
641 validBasicConstraints = FALSE;
642 *pathLengthConstraintViolated = TRUE;
643 }
644 return validBasicConstraints;
645}
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType, const void *pvPara, PCCERT_CONTEXT pPrevCertContext)
Definition: cert.c:1765
BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, void *pvData, DWORD *pcbData)
Definition: cert.c:551
static BOOL CRYPT_DecodeBasicConstraints(PCCERT_CONTEXT cert, CERT_BASIC_CONSTRAINTS2_INFO *constraints, BOOL defaultIfNotSpecified)
Definition: chain.c:513
Definition: image.c:134
Definition: _hash_fun.h:40
#define CERT_V1
Definition: wincrypt.h:2656
#define CERT_HASH_PROP_ID
Definition: wincrypt.h:2688
#define CERT_FIND_SHA1_HASH
Definition: wincrypt.h:2865
#define CERT_V2
Definition: wincrypt.h:2657
unsigned char BYTE
Definition: xxhash.c:193

Referenced by CRYPT_CheckSimpleChain().

◆ CRYPT_CheckChainNameConstraints()

static void CRYPT_CheckChainNameConstraints ( PCERT_SIMPLE_CHAIN  chain)
static

Definition at line 1279 of file chain.c.

1280{
1281 int i, j;
1282
1283 /* Microsoft's implementation appears to violate RFC 3280: according to
1284 * MSDN, the various CERT_TRUST_*_NAME_CONSTRAINT errors are set if a CA's
1285 * name constraint is violated in the end cert. According to RFC 3280,
1286 * the constraints should be checked against every subsequent certificate
1287 * in the chain, not just the end cert.
1288 * Microsoft's implementation also sets the name constraint errors on the
1289 * certs whose constraints were violated, not on the certs that violated
1290 * them.
1291 * In order to be error-compatible with Microsoft's implementation, while
1292 * still adhering to RFC 3280, I use a O(n ^ 2) algorithm to check name
1293 * constraints.
1294 */
1295 for (i = chain->cElement - 1; i > 0; i--)
1296 {
1297 CERT_NAME_CONSTRAINTS_INFO *nameConstraints;
1298
1299 if ((nameConstraints = CRYPT_GetNameConstraints(
1300 chain->rgpElement[i]->pCertContext->pCertInfo)))
1301 {
1302 if (!CRYPT_IsValidNameConstraint(nameConstraints))
1303 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1305 else
1306 {
1307 for (j = i - 1; j >= 0; j--)
1308 {
1309 DWORD errorStatus = 0;
1310
1311 /* According to RFC 3280, self-signed certs don't have name
1312 * constraints checked unless they're the end cert.
1313 */
1314 if (j == 0 || !CRYPT_IsCertificateSelfSigned(
1315 chain->rgpElement[j]->pCertContext))
1316 {
1317 CRYPT_CheckNameConstraints(nameConstraints,
1318 chain->rgpElement[j]->pCertContext->pCertInfo,
1319 &errorStatus);
1320 if (errorStatus)
1321 {
1322 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1323 errorStatus;
1324 CRYPT_CombineTrustStatus(&chain->TrustStatus,
1325 &chain->rgpElement[i]->TrustStatus);
1326 }
1327 else
1328 chain->rgpElement[i]->TrustStatus.dwInfoStatus |=
1330 }
1331 }
1332 }
1333 LocalFree(nameConstraints);
1334 }
1335 }
1336}
static BOOL CRYPT_IsValidNameConstraint(const CERT_NAME_CONSTRAINTS_INFO *info)
Definition: chain.c:1234
static void CRYPT_CheckNameConstraints(const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, const CERT_INFO *cert, DWORD *trustErrorStatus)
Definition: chain.c:1196
static CERT_NAME_CONSTRAINTS_INFO * CRYPT_GetNameConstraints(CERT_INFO *cert)
Definition: chain.c:1215
#define CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS
Definition: wincrypt.h:903

Referenced by CRYPT_CheckSimpleChain().

◆ CRYPT_CheckChainPolicies()

static void CRYPT_CheckChainPolicies ( PCERT_SIMPLE_CHAIN  chain)
static

Definition at line 1381 of file chain.c.

1382{
1383 int i, j;
1384
1385 for (i = chain->cElement - 1; i > 0; i--)
1386 {
1387 CERT_POLICIES_INFO *policies;
1388
1389 if ((policies = CRYPT_GetPolicies(chain->rgpElement[i]->pCertContext)))
1390 {
1391 for (j = i - 1; j >= 0; j--)
1392 {
1393 DWORD errorStatus = 0;
1394
1395 CRYPT_CheckPolicies(policies,
1396 chain->rgpElement[j]->pCertContext->pCertInfo, &errorStatus);
1397 if (errorStatus)
1398 {
1399 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1400 errorStatus;
1401 CRYPT_CombineTrustStatus(&chain->TrustStatus,
1402 &chain->rgpElement[i]->TrustStatus);
1403 }
1404 }
1405 LocalFree(policies);
1406 }
1407 }
1408}
static void CRYPT_CheckPolicies(const CERT_POLICIES_INFO *policies, CERT_INFO *cert, DWORD *errorStatus)
Definition: chain.c:1357
static CERT_POLICIES_INFO * CRYPT_GetPolicies(PCCERT_CONTEXT cert)
Definition: chain.c:1339

Referenced by CRYPT_CheckSimpleChain().

◆ CRYPT_CheckNameConstraints()

static void CRYPT_CheckNameConstraints ( const CERT_NAME_CONSTRAINTS_INFO nameConstraints,
const CERT_INFO cert,
DWORD trustErrorStatus 
)
static

Definition at line 1196 of file chain.c.

1199{
1201
1202 if (ext)
1203 compare_alt_name_with_constraints(ext, nameConstraints,
1204 trustErrorStatus);
1205 /* Name constraints apply to the subject alternative name as well as the
1206 * subject name. From RFC 5280, section 4.2.1.10:
1207 * "Restrictions apply to the subject distinguished name and apply to
1208 * subject alternative names."
1209 */
1210 compare_subject_with_constraints(&cert->Subject, nameConstraints,
1211 trustErrorStatus);
1212}
static void compare_alt_name_with_constraints(const CERT_EXTENSION *altNameExt, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
Definition: chain.c:967
static void compare_subject_with_constraints(const CERT_NAME_BLOB *subjectName, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
Definition: chain.c:1126
static PCERT_EXTENSION get_subject_alt_name_ext(const CERT_INFO *cert)
Definition: chain.c:955
static const WCHAR *const ext[]
Definition: module.c:53

Referenced by CRYPT_CheckChainNameConstraints().

◆ CRYPT_CheckPolicies()

static void CRYPT_CheckPolicies ( const CERT_POLICIES_INFO policies,
CERT_INFO cert,
DWORD errorStatus 
)
static

Definition at line 1357 of file chain.c.

1359{
1360 DWORD i;
1361
1362 for (i = 0; i < policies->cPolicyInfo; i++)
1363 {
1364 /* For now, the only accepted policy identifier is the anyPolicy
1365 * identifier.
1366 * FIXME: the policy identifiers should be compared against the
1367 * cert's certificate policies extension, subject to the policy
1368 * mappings extension, and the policy constraints extension.
1369 * See RFC 5280, sections 4.2.1.4, 4.2.1.5, and 4.2.1.11.
1370 */
1373 {
1374 FIXME("unsupported policy %s\n",
1377 }
1378 }
1379}
CERT_POLICY_INFO * rgPolicyInfo
Definition: wincrypt.h:400
LPSTR pszPolicyIdentifier
Definition: wincrypt.h:393
#define CERT_TRUST_INVALID_POLICY_CONSTRAINTS
Definition: wincrypt.h:879
#define szOID_ANY_CERT_POLICY
Definition: wincrypt.h:3198

Referenced by CRYPT_CheckChainPolicies().

◆ CRYPT_CheckRestrictedRoot()

static BOOL CRYPT_CheckRestrictedRoot ( HCERTSTORE  store)
static

Definition at line 89 of file chain.c.

90{
91 BOOL ret = TRUE;
92
93 if (store)
94 {
97
98 do {
100 if (cert)
101 {
102 if (!(check = CRYPT_FindCertInStore(rootStore, cert)))
103 ret = FALSE;
104 else
106 }
107 } while (ret && cert);
108 if (cert)
110 CertCloseStore(rootStore, 0);
111 }
112 return ret;
113}
static PCCERT_CONTEXT CRYPT_FindCertInStore(HCERTSTORE store, PCCERT_CONTEXT cert)
Definition: chain.c:72
static const WCHAR rootW[]
Definition: chain.c:69
PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrev)
Definition: store.c:928
BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
Definition: store.c:1127
HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, LPCWSTR szSubSystemProtocol)
Definition: store.c:916
#define check(expected, result)
Definition: dplayx.c:32

Referenced by CertCreateCertificateChainEngine().

◆ CRYPT_CheckRootCert()

static void CRYPT_CheckRootCert ( HCERTSTORE  hRoot,
PCERT_CHAIN_ELEMENT  rootElement 
)
static

Definition at line 491 of file chain.c.

493{
494 PCCERT_CONTEXT root = rootElement->pCertContext;
495
496 if (!CryptVerifyCertificateSignatureEx(0, root->dwCertEncodingType,
499 {
500 TRACE_(chain)("Last certificate's signature is invalid\n");
501 rootElement->TrustStatus.dwErrorStatus |=
503 }
504 CRYPT_CheckTrustedStatus(hRoot, rootElement);
505}
BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, DWORD dwSubjectType, void *pvSubject, DWORD dwIssuerType, void *pvIssuer, DWORD dwFlags, void *pvReserved)
Definition: cert.c:2717
static void CRYPT_CheckTrustedStatus(HCERTSTORE hRoot, PCERT_CHAIN_ELEMENT rootElement)
Definition: chain.c:478
static HTREEITEM hRoot
Definition: treeview.c:381
PCCERT_CONTEXT pCertContext
Definition: wincrypt.h:916
CERT_TRUST_STATUS TrustStatus
Definition: wincrypt.h:917
#define CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT
Definition: wincrypt.h:3474
#define CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT
Definition: wincrypt.h:3469

Referenced by CRYPT_CheckSimpleChain().

◆ CRYPT_CheckSimpleChain()

static void CRYPT_CheckSimpleChain ( CertificateChainEngine engine,
PCERT_SIMPLE_CHAIN  chain,
LPFILETIME  time 
)
static

Definition at line 1879 of file chain.c.

1881{
1882 PCERT_CHAIN_ELEMENT rootElement = chain->rgpElement[chain->cElement - 1];
1883 int i;
1884 BOOL pathLengthConstraintViolated = FALSE;
1885 CERT_BASIC_CONSTRAINTS2_INFO constraints = { FALSE, FALSE, 0 };
1886 DWORD status;
1887
1888 TRACE_(chain)("checking chain with %d elements for time %s\n",
1889 chain->cElement, filetime_to_str(time));
1890 for (i = chain->cElement - 1; i >= 0; i--)
1891 {
1892 BOOL isRoot;
1893
1894 if (TRACE_ON(chain))
1895 dump_element(chain->rgpElement[i]->pCertContext);
1896 if (i == chain->cElement - 1)
1898 chain->rgpElement[i]->pCertContext);
1899 else
1900 isRoot = FALSE;
1901 if (!CRYPT_IsCertVersionValid(chain->rgpElement[i]->pCertContext))
1902 {
1903 /* MS appears to accept certs whose versions don't match their
1904 * contents, so there isn't an appropriate error code.
1905 */
1906 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1908 }
1910 chain->rgpElement[i]->pCertContext->pCertInfo) != 0)
1911 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1913 if (i != 0)
1914 {
1915 /* Check the signature of the cert this issued */
1918 (void *)chain->rgpElement[i - 1]->pCertContext,
1920 (void *)chain->rgpElement[i]->pCertContext, 0, NULL))
1921 chain->rgpElement[i - 1]->TrustStatus.dwErrorStatus |=
1923 /* Once a path length constraint has been violated, every remaining
1924 * CA cert's basic constraints is considered invalid.
1925 */
1926 if (pathLengthConstraintViolated)
1927 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1929 else if (!CRYPT_CheckBasicConstraintsForCA(engine,
1930 chain->rgpElement[i]->pCertContext, &constraints, i - 1, isRoot,
1931 &pathLengthConstraintViolated))
1932 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1934 else if (constraints.fPathLenConstraint &&
1935 constraints.dwPathLenConstraint)
1936 {
1937 /* This one's valid - decrement max length */
1938 constraints.dwPathLenConstraint--;
1939 }
1940 }
1941 else
1942 {
1943 /* Check whether end cert has a basic constraints extension */
1945 chain->rgpElement[i]->pCertContext, &constraints, FALSE))
1946 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1948 }
1949 if (!CRYPT_KeyUsageValid(engine, chain->rgpElement[i]->pCertContext,
1950 isRoot, constraints.fCA, i))
1951 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1954 {
1955 /* If the chain is cyclic, then the path length constraints
1956 * are violated, because the chain is infinitely long.
1957 */
1958 pathLengthConstraintViolated = TRUE;
1959 chain->TrustStatus.dwErrorStatus |=
1962 }
1963 /* Check whether every critical extension is supported */
1965 chain->rgpElement[i]->pCertContext))
1966 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1969 CRYPT_CombineTrustStatus(&chain->TrustStatus,
1970 &chain->rgpElement[i]->TrustStatus);
1971 }
1975 {
1976 rootElement->TrustStatus.dwInfoStatus |= status;
1977 CRYPT_CheckRootCert(engine->hRoot, rootElement);
1978 }
1979 CRYPT_CombineTrustStatus(&chain->TrustStatus, &rootElement->TrustStatus);
1980}
LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify, PCERT_INFO pCertInfo)
Definition: cert.c:2158
static void CRYPT_CheckChainPolicies(PCERT_SIMPLE_CHAIN chain)
Definition: chain.c:1381
static void CRYPT_CheckChainNameConstraints(PCERT_SIMPLE_CHAIN chain)
Definition: chain.c:1279
static BOOL CRYPT_KeyUsageValid(CertificateChainEngine *engine, PCCERT_CONTEXT cert, BOOL isRoot, BOOL isCA, DWORD index)
Definition: chain.c:1723
static BOOL CRYPT_IsCertVersionValid(PCCERT_CONTEXT cert)
Definition: chain.c:1840
static BOOL CRYPT_CheckBasicConstraintsForCA(CertificateChainEngine *engine, PCCERT_CONTEXT cert, CERT_BASIC_CONSTRAINTS2_INFO *chainConstraints, DWORD remainingCAs, BOOL isRoot, BOOL *pathLengthConstraintViolated)
Definition: chain.c:580
static BOOL CRYPT_CriticalExtensionsSupported(PCCERT_CONTEXT cert)
Definition: chain.c:1802
static LPCSTR filetime_to_str(const FILETIME *time)
Definition: chain.c:1675
static void CRYPT_CheckRootCert(HCERTSTORE hRoot, PCERT_CHAIN_ELEMENT rootElement)
Definition: chain.c:491
static void dump_element(PCCERT_CONTEXT cert)
Definition: chain.c:1689
__u16 time
Definition: mkdosfs.c:8
HCERTSTORE hRoot
Definition: chain.c:44
Definition: ps.c:97
#define CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT
Definition: wincrypt.h:889
#define CERT_TRUST_IS_NOT_VALID_FOR_USAGE
Definition: wincrypt.h:874

Referenced by CRYPT_BuildAlternateContextFromChain(), and CRYPT_GetSimpleChainForCert().

◆ CRYPT_CheckSimpleChainForCycles()

static void CRYPT_CheckSimpleChainForCycles ( PCERT_SIMPLE_CHAIN  chain)
static

Definition at line 383 of file chain.c.

384{
385 DWORD i, j, cyclicCertIndex = 0;
386
387 /* O(n^2) - I don't think there's a faster way */
388 for (i = 0; !cyclicCertIndex && i < chain->cElement; i++)
389 for (j = i + 1; !cyclicCertIndex && j < chain->cElement; j++)
391 chain->rgpElement[i]->pCertContext->pCertInfo,
392 chain->rgpElement[j]->pCertContext->pCertInfo))
393 cyclicCertIndex = j;
394 if (cyclicCertIndex)
395 {
396 chain->rgpElement[cyclicCertIndex]->TrustStatus.dwErrorStatus
398 /* Release remaining certs */
399 for (i = cyclicCertIndex + 1; i < chain->cElement; i++)
400 CRYPT_FreeChainElement(chain->rgpElement[i]);
401 /* Truncate chain */
402 chain->cElement = cyclicCertIndex + 1;
403 }
404}
BOOL WINAPI CertCompareCertificate(DWORD dwCertEncodingType, PCERT_INFO pCertId1, PCERT_INFO pCertId2)
Definition: cert.c:1166
static void CRYPT_FreeChainElement(PCERT_CHAIN_ELEMENT element)
Definition: chain.c:377
#define CERT_TRUST_IS_CYCLIC
Definition: wincrypt.h:877

Referenced by CRYPT_AddCertToSimpleChain().

◆ CRYPT_CheckTrustedStatus()

static void CRYPT_CheckTrustedStatus ( HCERTSTORE  hRoot,
PCERT_CHAIN_ELEMENT  rootElement 
)
static

Definition at line 478 of file chain.c.

480{
482 rootElement->pCertContext);
483
484 if (!trustedRoot)
485 rootElement->TrustStatus.dwErrorStatus |=
487 else
488 CertFreeCertificateContext(trustedRoot);
489}

Referenced by CRYPT_CheckRootCert().

◆ CRYPT_CheckUsages()

static void CRYPT_CheckUsages ( PCERT_CHAIN_CONTEXT  chain,
const CERT_CHAIN_PARA pChainPara 
)
static

Definition at line 2745 of file chain.c.

2747{
2748 if (pChainPara->cbSize >= sizeof(CERT_CHAIN_PARA_NO_EXTRA_FIELDS) &&
2749 pChainPara->RequestedUsage.Usage.cUsageIdentifier)
2750 {
2751 PCCERT_CONTEXT endCert;
2753 BOOL validForUsage;
2754
2755 /* A chain, if created, always includes the end certificate */
2756 endCert = chain->rgpChain[0]->rgpElement[0]->pCertContext;
2757 /* The extended key usage extension specifies how a certificate's
2758 * public key may be used. From RFC 5280, section 4.2.1.12:
2759 * "This extension indicates one or more purposes for which the
2760 * certified public key may be used, in addition to or in place of the
2761 * basic purposes indicated in the key usage extension."
2762 * If the extension is present, it only satisfies the requested usage
2763 * if that usage is included in the extension:
2764 * "If the extension is present, then the certificate MUST only be used
2765 * for one of the purposes indicated."
2766 * There is also the special anyExtendedKeyUsage OID, but it doesn't
2767 * have to be respected:
2768 * "Applications that require the presence of a particular purpose
2769 * MAY reject certificates that include the anyExtendedKeyUsage OID
2770 * but not the particular OID expected for the application."
2771 * For now, I'm being more conservative and ignoring the presence of
2772 * the anyExtendedKeyUsage OID.
2773 */
2775 endCert->pCertInfo->cExtension, endCert->pCertInfo->rgExtension)))
2776 {
2777 const CERT_ENHKEY_USAGE *requestedUsage =
2778 &pChainPara->RequestedUsage.Usage;
2780 DWORD size;
2781
2783 X509_ENHANCED_KEY_USAGE, ext->Value.pbData, ext->Value.cbData,
2785 {
2786 if (pChainPara->RequestedUsage.dwType == USAGE_MATCH_TYPE_AND)
2787 {
2788 DWORD i, j;
2789
2790 /* For AND matches, all usages must be present */
2791 validForUsage = TRUE;
2792 for (i = 0; validForUsage &&
2793 i < requestedUsage->cUsageIdentifier; i++)
2794 {
2795 BOOL match = FALSE;
2796
2797 for (j = 0; !match && j < usage->cUsageIdentifier; j++)
2798 match = !strcmp(usage->rgpszUsageIdentifier[j],
2799 requestedUsage->rgpszUsageIdentifier[i]);
2800 if (!match)
2801 validForUsage = FALSE;
2802 }
2803 }
2804 else
2805 {
2806 DWORD i, j;
2807
2808 /* For OR matches, any matching usage suffices */
2809 validForUsage = FALSE;
2810 for (i = 0; !validForUsage &&
2811 i < requestedUsage->cUsageIdentifier; i++)
2812 {
2813 for (j = 0; !validForUsage &&
2814 j < usage->cUsageIdentifier; j++)
2815 validForUsage =
2816 !strcmp(usage->rgpszUsageIdentifier[j],
2817 requestedUsage->rgpszUsageIdentifier[i]);
2818 }
2819 }
2821 }
2822 else
2823 validForUsage = FALSE;
2824 }
2825 else
2826 {
2827 /* If the extension isn't present, any interpretation is valid:
2828 * "Certificate using applications MAY require that the extended
2829 * key usage extension be present and that a particular purpose
2830 * be indicated in order for the certificate to be acceptable to
2831 * that application."
2832 * Not all web sites include the extended key usage extension, so
2833 * accept chains without it.
2834 */
2835 TRACE_(chain)("requested usage from certificate with no usages\n");
2836 validForUsage = TRUE;
2837 }
2838 if (!validForUsage)
2839 {
2840 chain->TrustStatus.dwErrorStatus |=
2842 chain->rgpChain[0]->rgpElement[0]->TrustStatus.dwErrorStatus |=
2844 }
2845 }
2846 if (pChainPara->cbSize >= sizeof(CERT_CHAIN_PARA) &&
2847 pChainPara->RequestedIssuancePolicy.Usage.cUsageIdentifier)
2848 FIXME("unimplemented for RequestedIssuancePolicy\n");
2849}
PCERT_EXTENSION WINAPI CertFindExtension(LPCSTR pszObjId, DWORD cExtensions, CERT_EXTENSION rgExtensions[])
Definition: cert.c:2028
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
PCERT_EXTENSION rgExtension
Definition: wincrypt.h:252
DWORD cExtension
Definition: wincrypt.h:251
DWORD cUsageIdentifier
Definition: wincrypt.h:719
LPSTR * rgpszUsageIdentifier
Definition: wincrypt.h:720
#define USAGE_MATCH_TYPE_AND
Definition: wincrypt.h:1043
#define szOID_ENHANCED_KEY_USAGE
Definition: wincrypt.h:3202
#define X509_ENHANCED_KEY_USAGE
Definition: wincrypt.h:3403

Referenced by CertGetCertificateChain().

◆ CRYPT_ChooseHighestQualityChain()

static CertificateChain * CRYPT_ChooseHighestQualityChain ( CertificateChain chain)
static

Definition at line 2554 of file chain.c.

2556{
2557 DWORD i;
2558
2559 /* There are always only two chains being considered: chain, and an
2560 * alternate at chain->rgpLowerQualityChainContext[i]. If the alternate
2561 * has a higher quality than chain, the alternate gets assigned the lower
2562 * quality contexts, with chain taking the alternate's place among the
2563 * lower quality contexts.
2564 */
2565 for (i = 0; i < chain->context.cLowerQualityChainContext; i++)
2566 {
2567 CertificateChain *alternate =
2568 (CertificateChain*)chain->context.rgpLowerQualityChainContext[i];
2569
2571 {
2573 chain->context.cLowerQualityChainContext;
2575 chain->context.rgpLowerQualityChainContext;
2578 chain->context.cLowerQualityChainContext = 0;
2579 chain->context.rgpLowerQualityChainContext = NULL;
2580 chain = alternate;
2581 }
2582 }
2583 return chain;
2584}
static DWORD CRYPT_ChainQuality(const CertificateChain *chain)
Definition: chain.c:2528
DWORD cLowerQualityChainContext
Definition: wincrypt.h:942
PCCERT_CHAIN_CONTEXT * rgpLowerQualityChainContext
Definition: wincrypt.h:943

Referenced by CertGetCertificateChain().

◆ CRYPT_CloseStores()

static void CRYPT_CloseStores ( DWORD  cStores,
HCERTSTORE stores 
)
inlinestatic

Definition at line 61 of file chain.c.

62{
63 DWORD i;
64
65 for (i = 0; i < cStores; i++)
66 CertCloseStore(stores[i], 0);
67}

Referenced by CRYPT_CreateChainEngine().

◆ CRYPT_CombineTrustStatus()

static void CRYPT_CombineTrustStatus ( CERT_TRUST_STATUS chainStatus,
const CERT_TRUST_STATUS elementStatus 
)
inlinestatic

Definition at line 416 of file chain.c.

418{
419 /* Any error that applies to an element also applies to a chain.. */
420 chainStatus->dwErrorStatus |= elementStatus->dwErrorStatus;
421 /* but the bottom nibble of an element's info status doesn't apply to the
422 * chain.
423 */
424 chainStatus->dwInfoStatus |= (elementStatus->dwInfoStatus & 0xfffffff0);
425}

Referenced by CRYPT_AddCertToSimpleChain(), CRYPT_BuildAlternateContextFromChain(), CRYPT_CheckChainNameConstraints(), CRYPT_CheckChainPolicies(), and CRYPT_CheckSimpleChain().

◆ CRYPT_CopyChainToElement()

static CertificateChain * CRYPT_CopyChainToElement ( CertificateChain chain,
DWORD  iChain,
DWORD  iElement 
)
static

Definition at line 2377 of file chain.c.

2379{
2381
2382 if (copy)
2383 {
2384 copy->ref = 1;
2385 copy->world = CertDuplicateStore(chain->world);
2386 copy->context.cbSize = sizeof(CERT_CHAIN_CONTEXT);
2387 /* Leave the trust status of the copied chain unset, it'll get
2388 * rechecked after the new chain is done.
2389 */
2390 memset(&copy->context.TrustStatus, 0, sizeof(CERT_TRUST_STATUS));
2391 copy->context.cLowerQualityChainContext = 0;
2392 copy->context.rgpLowerQualityChainContext = NULL;
2393 copy->context.fHasRevocationFreshnessTime = FALSE;
2394 copy->context.dwRevocationFreshnessTime = 0;
2395 copy->context.rgpChain = CryptMemAlloc(
2396 (iChain + 1) * sizeof(PCERT_SIMPLE_CHAIN));
2397 if (copy->context.rgpChain)
2398 {
2399 BOOL ret = TRUE;
2400 DWORD i;
2401
2402 memset(copy->context.rgpChain, 0,
2403 (iChain + 1) * sizeof(PCERT_SIMPLE_CHAIN));
2404 if (iChain)
2405 {
2406 for (i = 0; ret && iChain && i < iChain - 1; i++)
2407 {
2408 copy->context.rgpChain[i] =
2409 CRYPT_CopySimpleChainToElement(chain->context.rgpChain[i],
2410 chain->context.rgpChain[i]->cElement - 1);
2411 if (!copy->context.rgpChain[i])
2412 ret = FALSE;
2413 }
2414 }
2415 else
2416 i = 0;
2417 if (ret)
2418 {
2419 copy->context.rgpChain[i] =
2420 CRYPT_CopySimpleChainToElement(chain->context.rgpChain[i],
2421 iElement);
2422 if (!copy->context.rgpChain[i])
2423 ret = FALSE;
2424 }
2425 if (!ret)
2426 {
2428 copy = NULL;
2429 }
2430 else
2431 copy->context.cChain = iChain + 1;
2432 }
2433 else
2434 {
2436 copy = NULL;
2437 }
2438 }
2439 return copy;
2440}
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
static PCERT_SIMPLE_CHAIN CRYPT_CopySimpleChainToElement(const CERT_SIMPLE_CHAIN *chain, DWORD iElement)
Definition: chain.c:2296
HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
Definition: store.c:1116

Referenced by CRYPT_BuildAlternateContextFromChain().

◆ CRYPT_CopySimpleChainToElement()

static PCERT_SIMPLE_CHAIN CRYPT_CopySimpleChainToElement ( const CERT_SIMPLE_CHAIN chain,
DWORD  iElement 
)
static

Definition at line 2296 of file chain.c.

2298{
2300
2301 if (copy)
2302 {
2303 memset(copy, 0, sizeof(CERT_SIMPLE_CHAIN));
2304 copy->cbSize = sizeof(CERT_SIMPLE_CHAIN);
2305 copy->rgpElement =
2306 CryptMemAlloc((iElement + 1) * sizeof(PCERT_CHAIN_ELEMENT));
2307 if (copy->rgpElement)
2308 {
2309 DWORD i;
2310 BOOL ret = TRUE;
2311
2312 memset(copy->rgpElement, 0,
2313 (iElement + 1) * sizeof(PCERT_CHAIN_ELEMENT));
2314 for (i = 0; ret && i <= iElement; i++)
2315 {
2318
2319 if (element)
2320 {
2321 *element = *chain->rgpElement[i];
2323 chain->rgpElement[i]->pCertContext);
2324 /* Reset the trust status of the copied element, it'll get
2325 * rechecked after the new chain is done.
2326 */
2327 memset(&element->TrustStatus, 0, sizeof(CERT_TRUST_STATUS));
2328 copy->rgpElement[copy->cElement++] = element;
2329 }
2330 else
2331 ret = FALSE;
2332 }
2333 if (!ret)
2334 {
2335 for (i = 0; i <= iElement; i++)
2336 CryptMemFree(copy->rgpElement[i]);
2337 CryptMemFree(copy->rgpElement);
2339 copy = NULL;
2340 }
2341 }
2342 else
2343 {
2345 copy = NULL;
2346 }
2347 }
2348 return copy;
2349}
struct _CERT_SIMPLE_CHAIN CERT_SIMPLE_CHAIN

Referenced by CRYPT_CopyChainToElement().

◆ CRYPT_CreateChainEngine()

HCERTCHAINENGINE CRYPT_CreateChainEngine ( HCERTSTORE  root,
DWORD  system_store,
const CERT_CHAIN_ENGINE_CONFIG config 
)

Definition at line 115 of file chain.c.

116{
118 HCERTSTORE worldStores[4];
119
120 static const WCHAR caW[] = { 'C','A',0 };
121 static const WCHAR myW[] = { 'M','y',0 };
122 static const WCHAR trustW[] = { 'T','r','u','s','t',0 };
123
124 if(!root) {
125 if(config->cbSize >= sizeof(CERT_CHAIN_ENGINE_CONFIG) && config->hExclusiveRoot)
126 root = CertDuplicateStore(config->hExclusiveRoot);
127 else if (config->hRestrictedRoot)
128 root = CertDuplicateStore(config->hRestrictedRoot);
129 else
130 root = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, rootW);
131 if(!root)
132 return NULL;
133 }
134
135 engine = CryptMemAlloc(sizeof(CertificateChainEngine));
136 if(!engine) {
138 return NULL;
139 }
140
141 engine->ref = 1;
142 engine->hRoot = root;
144 worldStores[0] = CertDuplicateStore(engine->hRoot);
145 worldStores[1] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, caW);
146 worldStores[2] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, myW);
147 worldStores[3] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, trustW);
148
149 CRYPT_AddStoresToCollection(engine->hWorld, ARRAY_SIZE(worldStores), worldStores);
150 CRYPT_AddStoresToCollection(engine->hWorld, config->cAdditionalStore, config->rghAdditionalStore);
151 CRYPT_CloseStores(ARRAY_SIZE(worldStores), worldStores);
152
153 engine->dwFlags = config->dwFlags;
154 engine->dwUrlRetrievalTimeout = config->dwUrlRetrievalTimeout;
155 engine->MaximumCachedCertificates = config->MaximumCachedCertificates;
156 if(config->CycleDetectionModulus)
157 engine->CycleDetectionModulus = config->CycleDetectionModulus;
158 else
160
161 return engine;
162}
#define ARRAY_SIZE(A)
Definition: main.h:33
struct _root root
static void CRYPT_CloseStores(DWORD cStores, HCERTSTORE *stores)
Definition: chain.c:61
#define DEFAULT_CYCLE_MODULUS
Definition: chain.c:34
static void CRYPT_AddStoresToCollection(HCERTSTORE collection, DWORD cStores, HCERTSTORE *stores)
Definition: chain.c:52
DWORD MaximumCachedCertificates
Definition: chain.c:48
DWORD dwUrlRetrievalTimeout
Definition: chain.c:47
#define CERT_STORE_PROV_SYSTEM_W
Definition: wincrypt.h:2259
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by CertCreateCertificateChainEngine(), check_and_store_certs(), and get_chain_engine().

◆ CRYPT_CriticalExtensionsSupported()

static BOOL CRYPT_CriticalExtensionsSupported ( PCCERT_CONTEXT  cert)
static

Definition at line 1802 of file chain.c.

1803{
1804 BOOL ret = TRUE;
1805 DWORD i;
1806
1807 for (i = 0; ret && i < cert->pCertInfo->cExtension; i++)
1808 {
1809 if (cert->pCertInfo->rgExtension[i].fCritical)
1810 {
1811 LPCSTR oid = cert->pCertInfo->rgExtension[i].pszObjId;
1812
1814 ret = TRUE;
1815 else if (!strcmp(oid, szOID_BASIC_CONSTRAINTS2))
1816 ret = TRUE;
1817 else if (!strcmp(oid, szOID_NAME_CONSTRAINTS))
1818 ret = TRUE;
1819 else if (!strcmp(oid, szOID_KEY_USAGE))
1820 ret = TRUE;
1821 else if (!strcmp(oid, szOID_SUBJECT_ALT_NAME))
1822 ret = TRUE;
1823 else if (!strcmp(oid, szOID_SUBJECT_ALT_NAME2))
1824 ret = TRUE;
1825 else if (!strcmp(oid, szOID_CERT_POLICIES))
1826 ret = TRUE;
1827 else if (!strcmp(oid, szOID_ENHANCED_KEY_USAGE))
1828 ret = TRUE;
1829 else
1830 {
1831 FIXME("unsupported critical extension %s\n",
1832 debugstr_a(oid));
1833 ret = FALSE;
1834 }
1835 }
1836 }
1837 return ret;
1838}
#define szOID_BASIC_CONSTRAINTS2
Definition: wincrypt.h:3189
#define szOID_NAME_CONSTRAINTS
Definition: wincrypt.h:3195
#define szOID_KEY_USAGE
Definition: wincrypt.h:3185
#define szOID_BASIC_CONSTRAINTS
Definition: wincrypt.h:3183
#define szOID_SUBJECT_ALT_NAME
Definition: wincrypt.h:3180
#define szOID_CERT_POLICIES
Definition: wincrypt.h:3197
#define szOID_SUBJECT_ALT_NAME2
Definition: wincrypt.h:3187
const char * LPCSTR
Definition: xmlstorage.h:183

Referenced by CRYPT_CheckSimpleChain().

◆ CRYPT_DecodeBasicConstraints()

static BOOL CRYPT_DecodeBasicConstraints ( PCCERT_CONTEXT  cert,
CERT_BASIC_CONSTRAINTS2_INFO constraints,
BOOL  defaultIfNotSpecified 
)
static

Definition at line 513 of file chain.c.

515{
516 BOOL ret = TRUE;
518 cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
519
520 constraints->fPathLenConstraint = FALSE;
521 if (ext)
522 {
524 DWORD size = 0;
525
527 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG,
528 NULL, &info, &size);
529 if (ret)
530 {
531 if (info->SubjectType.cbData == 1)
532 constraints->fCA =
533 info->SubjectType.pbData[0] & CERT_CA_SUBJECT_FLAG;
535 }
536 }
537 else
538 {
540 cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
541 if (ext)
542 {
544
546 szOID_BASIC_CONSTRAINTS2, ext->Value.pbData, ext->Value.cbData,
547 0, NULL, constraints, &size);
548 }
549 else
550 constraints->fCA = defaultIfNotSpecified;
551 }
552 return ret;
553}
#define CERT_CA_SUBJECT_FLAG
Definition: wincrypt.h:378
struct _CERT_BASIC_CONSTRAINTS2_INFO CERT_BASIC_CONSTRAINTS2_INFO

Referenced by CRYPT_CheckBasicConstraintsForCA(), and CRYPT_CheckSimpleChain().

◆ CRYPT_FindCertInStore()

static PCCERT_CONTEXT CRYPT_FindCertInStore ( HCERTSTORE  store,
PCCERT_CONTEXT  cert 
)
static

Definition at line 72 of file chain.c.

74{
75 PCCERT_CONTEXT matching = NULL;
76 BYTE hash[20];
77 DWORD size = sizeof(hash);
78
80 {
81 CRYPT_HASH_BLOB blob = { sizeof(hash), hash };
82
83 matching = CertFindCertificateInStore(store, cert->dwCertEncodingType,
85 }
86 return matching;
87}

Referenced by CRYPT_CheckRestrictedRoot(), and CRYPT_CheckTrustedStatus().

◆ CRYPT_FindIssuer()

static PCCERT_CONTEXT CRYPT_FindIssuer ( const CertificateChainEngine engine,
const CERT_CONTEXT cert,
HCERTSTORE  store,
DWORD  type,
void para,
DWORD  flags,
PCCERT_CONTEXT  prev_issuer 
)
static

Definition at line 1982 of file chain.c.

1984{
1985 CRYPT_URL_ARRAY *urls;
1987 DWORD size;
1988 BOOL res;
1989
1990 issuer = CertFindCertificateInStore(store, cert->dwCertEncodingType, 0, type, para, prev_issuer);
1991 if(issuer) {
1992 TRACE("Found in store %p\n", issuer);
1993 return issuer;
1994 }
1995
1996 /* FIXME: For alternate issuers, we don't search world store nor try to retrieve issuer from URL.
1997 * This needs more tests.
1998 */
1999 if(prev_issuer)
2000 return NULL;
2001
2002 if(engine->hWorld) {
2003 issuer = CertFindCertificateInStore(engine->hWorld, cert->dwCertEncodingType, 0, type, para, NULL);
2004 if(issuer) {
2005 TRACE("Found in world %p\n", issuer);
2006 return issuer;
2007 }
2008 }
2009
2011 if(!res)
2012 return NULL;
2013
2014 urls = HeapAlloc(GetProcessHeap(), 0, size);
2015 if(!urls)
2016 return NULL;
2017
2019 if(res)
2020 {
2021 CERT_CONTEXT *new_cert;
2022 HCERTSTORE new_store;
2023 unsigned i;
2024
2025 for(i=0; i < urls->cUrl; i++)
2026 {
2027 TRACE("Trying URL %s\n", debugstr_w(urls->rgwszUrl[i]));
2028
2031 0, (void**)&new_cert, NULL, NULL, NULL, NULL);
2032 if(!res)
2033 {
2034 TRACE("CryptRetrieveObjectByUrlW failed: %u\n", GetLastError());
2035 continue;
2036 }
2037
2038 /* FIXME: Use new_cert->hCertStore once cert ref count bug is fixed. */
2041 issuer = CertFindCertificateInStore(new_store, cert->dwCertEncodingType, 0, type, para, NULL);
2043 CertCloseStore(new_store, 0);
2044 if(issuer)
2045 {
2046 TRACE("Found downloaded issuer %p\n", issuer);
2047 break;
2048 }
2049 }
2050 }
2051
2052 HeapFree(GetProcessHeap(), 0, urls);
2053 return issuer;
2054}
BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid, DWORD dwRetrievalFlags, DWORD dwTimeout, LPVOID *ppvObject, HCRYPTASYNC hAsyncRetrieve, PCRYPT_CREDENTIALS pCredentials, LPVOID pvVerify, PCRYPT_RETRIEVE_AUX_INFO pAuxInfo)
BOOL WINAPI CryptGetObjectUrl(LPCSTR pszUrlOid, LPVOID pvPara, DWORD dwFlags, PCRYPT_URL_ARRAY pUrlArray, DWORD *pcbUrlArray, PCRYPT_URL_INFO pUrlInfo, DWORD *pcbUrlInfo, LPVOID pvReserved)
BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppStoreContext)
Definition: cert.c:286
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
#define debugstr_w
Definition: kernel32.h:32
LPWSTR * rgwszUrl
Definition: wincrypt.h:1514
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CONTEXT_OID_CERTIFICATE
Definition: wincrypt.h:1627
#define URL_OID_CERTIFICATE_ISSUER
Definition: wincrypt.h:1524
#define CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL
Definition: wincrypt.h:3618
#define CRYPT_AIA_RETRIEVAL
Definition: wincrypt.h:1645
#define CERT_STORE_PROV_MEMORY
Definition: wincrypt.h:2251
#define CERT_STORE_ADD_NEW
Definition: wincrypt.h:2482
#define CRYPT_CACHE_ONLY_RETRIEVAL
Definition: wincrypt.h:1634

Referenced by CRYPT_GetIssuer().

◆ CRYPT_FindIthElementInChain()

static PCERT_CHAIN_ELEMENT CRYPT_FindIthElementInChain ( const CERT_CHAIN_CONTEXT chain,
DWORD  i 
)
static

Definition at line 2611 of file chain.c.

2613{
2614 DWORD j, iElement;
2616
2617 for (j = 0, iElement = 0; !element && j < chain->cChain; j++)
2618 {
2619 if (iElement + chain->rgpChain[j]->cElement < i)
2620 iElement += chain->rgpChain[j]->cElement;
2621 else
2622 element = chain->rgpChain[j]->rgpElement[i - iElement];
2623 }
2624 return element;
2625}

Referenced by CRYPT_VerifyChainRevocation().

◆ CRYPT_FreeChainContext()

static void CRYPT_FreeChainContext ( CertificateChain chain)
static

Definition at line 2362 of file chain.c.

2363{
2364 DWORD i;
2365
2367 for (i = 0; i < chain->context.cChain; i++)
2368 CRYPT_FreeSimpleChain(chain->context.rgpChain[i]);
2369 CryptMemFree(chain->context.rgpChain);
2370 CertCloseStore(chain->world, 0);
2372}

Referenced by CertFreeCertificateChain(), CRYPT_BuildAlternateContextFromChain(), and CRYPT_CopyChainToElement().

◆ CRYPT_FreeChainElement()

static void CRYPT_FreeChainElement ( PCERT_CHAIN_ELEMENT  element)
static

Definition at line 377 of file chain.c.

378{
379 CertFreeCertificateContext(element->pCertContext);
381}

Referenced by CRYPT_CheckSimpleChainForCycles(), and CRYPT_FreeSimpleChain().

◆ CRYPT_FreeLowerQualityChains()

static void CRYPT_FreeLowerQualityChains ( CertificateChain chain)
static

Definition at line 2351 of file chain.c.

2352{
2353 DWORD i;
2354
2355 for (i = 0; i < chain->context.cLowerQualityChainContext; i++)
2356 CertFreeCertificateChain(chain->context.rgpLowerQualityChainContext[i]);
2357 CryptMemFree(chain->context.rgpLowerQualityChainContext);
2358 chain->context.cLowerQualityChainContext = 0;
2359 chain->context.rgpLowerQualityChainContext = NULL;
2360}

Referenced by CertGetCertificateChain(), and CRYPT_FreeChainContext().

◆ CRYPT_FreeSimpleChain()

static void CRYPT_FreeSimpleChain ( PCERT_SIMPLE_CHAIN  chain)
static

Definition at line 468 of file chain.c.

469{
470 DWORD i;
471
472 for (i = 0; i < chain->cElement; i++)
473 CRYPT_FreeChainElement(chain->rgpElement[i]);
474 CryptMemFree(chain->rgpElement);
476}

Referenced by CRYPT_BuildCandidateChainFromCert(), CRYPT_FreeChainContext(), and CRYPT_GetSimpleChainForCert().

◆ CRYPT_GetIssuer()

static PCCERT_CONTEXT CRYPT_GetIssuer ( const CertificateChainEngine engine,
HCERTSTORE  store,
PCCERT_CONTEXT  subject,
PCCERT_CONTEXT  prevIssuer,
DWORD  flags,
DWORD infoStatus 
)
static

Definition at line 2056 of file chain.c.

2059{
2062 DWORD size;
2063
2064 *infoStatus = 0;
2066 subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
2067 {
2069 BOOL ret;
2070
2072 X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData,
2074 &info, &size);
2075 if (ret)
2076 {
2077 CERT_ID id;
2078
2079 if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
2080 {
2081 id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2082 memcpy(&id.u.IssuerSerialNumber.Issuer, &info->CertIssuer,
2083 sizeof(CERT_NAME_BLOB));
2084 memcpy(&id.u.IssuerSerialNumber.SerialNumber,
2085 &info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB));
2086
2087 issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
2088 if (issuer)
2089 {
2090 TRACE_(chain)("issuer found by issuer/serial number\n");
2092 }
2093 }
2094 else if (info->KeyId.cbData)
2095 {
2096 id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2097
2098 memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
2099 issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
2100 if (issuer)
2101 {
2102 TRACE_(chain)("issuer found by key id\n");
2103 *infoStatus = CERT_TRUST_HAS_KEY_MATCH_ISSUER;
2104 }
2105 }
2106 LocalFree(info);
2107 }
2108 }
2110 subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
2111 {
2113 BOOL ret;
2114
2116 X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
2118 &info, &size);
2119 if (ret)
2120 {
2121 CERT_ID id;
2122
2123 if (info->AuthorityCertIssuer.cAltEntry &&
2124 info->AuthorityCertSerialNumber.cbData)
2125 {
2126 PCERT_ALT_NAME_ENTRY directoryName = NULL;
2127 DWORD i;
2128
2129 for (i = 0; !directoryName &&
2130 i < info->AuthorityCertIssuer.cAltEntry; i++)
2131 if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice
2133 directoryName =
2134 &info->AuthorityCertIssuer.rgAltEntry[i];
2135 if (directoryName)
2136 {
2137 id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2138 memcpy(&id.u.IssuerSerialNumber.Issuer,
2139 &directoryName->u.DirectoryName, sizeof(CERT_NAME_BLOB));
2140 memcpy(&id.u.IssuerSerialNumber.SerialNumber,
2141 &info->AuthorityCertSerialNumber,
2142 sizeof(CRYPT_INTEGER_BLOB));
2143
2144 issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
2145 if (issuer)
2146 {
2147 TRACE_(chain)("issuer found by directory name\n");
2149 }
2150 }
2151 else
2152 FIXME("no supported name type in authority key id2\n");
2153 }
2154 else if (info->KeyId.cbData)
2155 {
2156 id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2157 memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
2158 issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
2159 if (issuer)
2160 {
2161 TRACE_(chain)("issuer found by key id\n");
2162 *infoStatus = CERT_TRUST_HAS_KEY_MATCH_ISSUER;
2163 }
2164 }
2165 LocalFree(info);
2166 }
2167 }
2168 else
2169 {
2170 issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_SUBJECT_NAME,
2171 &subject->pCertInfo->Issuer, flags, prevIssuer);
2172 TRACE_(chain)("issuer found by name\n");
2174 }
2175 return issuer;
2176}
static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, const CERT_CONTEXT *cert, HCERTSTORE store, DWORD type, void *para, DWORD flags, PCCERT_CONTEXT prev_issuer)
Definition: chain.c:1982
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
DWORD dwCertEncodingType
Definition: wincrypt.h:479
CERT_NAME_BLOB Issuer
Definition: wincrypt.h:244
#define CERT_FIND_CERT_ID
Definition: wincrypt.h:2907
#define X509_AUTHORITY_KEY_ID2
Definition: wincrypt.h:3398
#define szOID_AUTHORITY_KEY_IDENTIFIER
Definition: wincrypt.h:3175
#define CERT_ID_ISSUER_SERIAL_NUMBER
Definition: wincrypt.h:3673
#define CERT_ID_KEY_IDENTIFIER
Definition: wincrypt.h:3674
#define CERT_TRUST_HAS_EXACT_MATCH_ISSUER
Definition: wincrypt.h:896
#define CERT_TRUST_HAS_KEY_MATCH_ISSUER
Definition: wincrypt.h:897
#define X509_AUTHORITY_KEY_ID
Definition: wincrypt.h:3374
#define CERT_TRUST_HAS_NAME_MATCH_ISSUER
Definition: wincrypt.h:898
#define CERT_FIND_SUBJECT_NAME
Definition: wincrypt.h:2878
#define szOID_AUTHORITY_KEY_IDENTIFIER2
Definition: wincrypt.h:3200

Referenced by CRYPT_BuildAlternateContextFromChain(), and CRYPT_BuildSimpleChain().

◆ CRYPT_GetNameConstraints()

static CERT_NAME_CONSTRAINTS_INFO * CRYPT_GetNameConstraints ( CERT_INFO cert)
static

Definition at line 1215 of file chain.c.

1216{
1218
1220
1222 cert->rgExtension)))
1223 {
1224 DWORD size;
1225
1227 ext->Value.pbData, ext->Value.cbData,
1229 &size);
1230 }
1231 return info;
1232}
#define X509_NAME_CONSTRAINTS
Definition: wincrypt.h:3425

Referenced by CRYPT_CheckChainNameConstraints().

◆ CRYPT_GetPolicies()

static CERT_POLICIES_INFO * CRYPT_GetPolicies ( PCCERT_CONTEXT  cert)
static

Definition at line 1339 of file chain.c.

1340{
1342 CERT_POLICIES_INFO *policies = NULL;
1343
1344 ext = CertFindExtension(szOID_KEY_USAGE, cert->pCertInfo->cExtension,
1345 cert->pCertInfo->rgExtension);
1346 if (ext)
1347 {
1348 DWORD size;
1349
1351 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
1352 &policies, &size);
1353 }
1354 return policies;
1355}
#define X509_CERT_POLICIES
Definition: wincrypt.h:3381

Referenced by CRYPT_CheckChainPolicies().

◆ CRYPT_GetSimpleChainForCert()

static BOOL CRYPT_GetSimpleChainForCert ( CertificateChainEngine engine,
HCERTSTORE  world,
PCCERT_CONTEXT  cert,
LPFILETIME  pTime,
DWORD  flags,
PCERT_SIMPLE_CHAIN ppChain 
)
static

Definition at line 2220 of file chain.c.

2223{
2224 BOOL ret = FALSE;
2226
2227 TRACE("(%p, %p, %p, %s)\n", engine, world, cert, debugstr_filetime(pTime));
2228
2230 if (chain)
2231 {
2232 memset(chain, 0, sizeof(CERT_SIMPLE_CHAIN));
2233 chain->cbSize = sizeof(CERT_SIMPLE_CHAIN);
2235 if (ret)
2236 {
2237 ret = CRYPT_BuildSimpleChain(engine, world, flags, chain);
2238 if (ret)
2240 }
2241 if (!ret)
2242 {
2244 chain = NULL;
2245 }
2246 *ppChain = chain;
2247 }
2248 return ret;
2249}

Referenced by CRYPT_BuildCandidateChainFromCert().

◆ CRYPT_IsCertificateSelfSigned()

DWORD CRYPT_IsCertificateSelfSigned ( const CERT_CONTEXT cert)

Definition at line 268 of file chain.c.

269{
270 DWORD size, status = 0;
272 BOOL ret;
273
275 cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
276 {
278
279 ret = CryptDecodeObjectEx(cert->dwCertEncodingType,
280 X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
282 &info, &size);
283 if (ret)
284 {
285 if (info->AuthorityCertIssuer.cAltEntry &&
286 info->AuthorityCertSerialNumber.cbData)
287 {
288 PCERT_ALT_NAME_ENTRY directoryName = NULL;
289 DWORD i;
290
291 for (i = 0; !directoryName &&
292 i < info->AuthorityCertIssuer.cAltEntry; i++)
293 if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice
295 directoryName =
296 &info->AuthorityCertIssuer.rgAltEntry[i];
297 if (directoryName)
298 {
299 if (CertCompareCertificateName(cert->dwCertEncodingType, &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer)
300 && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber, &cert->pCertInfo->SerialNumber))
302 }
303 else
304 {
305 FIXME("no supported name type in authority key id2\n");
306 ret = FALSE;
307 }
308 }
309 else if (info->KeyId.cbData)
310 {
313 if (ret && size == info->KeyId.cbData)
314 {
316
317 if (buf)
318 {
320 if (!memcmp(buf, info->KeyId.pbData, size))
323 }
324 }
325 }
327 }
328 }
330 cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
331 {
333
334 ret = CryptDecodeObjectEx(cert->dwCertEncodingType,
335 X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData,
337 &info, &size);
338 if (ret)
339 {
340 if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
341 {
342 if (CertCompareCertificateName(cert->dwCertEncodingType, &info->CertIssuer, &cert->pCertInfo->Issuer)
343 && CertCompareIntegerBlob(&info->CertSerialNumber, &cert->pCertInfo->SerialNumber))
345 }
346 else if (info->KeyId.cbData)
347 {
350 if (ret && size == info->KeyId.cbData)
351 {
353
354 if (buf)
355 {
358 if (!memcmp(buf, info->KeyId.pbData, size))
361 }
362 }
363 }
365 }
366 }
367 else
368 if (CertCompareCertificateName(cert->dwCertEncodingType, &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer))
370
371 if (status)
373
374 return status;
375}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType, PCERT_NAME_BLOB pCertName1, PCERT_NAME_BLOB pCertName2)
Definition: cert.c:1180
BOOL WINAPI CertCompareIntegerBlob(PCRYPT_INTEGER_BLOB pInt1, PCRYPT_INTEGER_BLOB pInt2)
Definition: cert.c:1221
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
unsigned char * LPBYTE
Definition: typedefs.h:53
#define CERT_KEY_IDENTIFIER_PROP_ID
Definition: wincrypt.h:2706
#define CERT_TRUST_IS_SELF_SIGNED
Definition: wincrypt.h:899

Referenced by CertGetIssuerCertificateFromStore(), CRYPT_BuildSimpleChain(), CRYPT_CheckChainNameConstraints(), and CRYPT_CheckSimpleChain().

◆ CRYPT_IsCertVersionValid()

static BOOL CRYPT_IsCertVersionValid ( PCCERT_CONTEXT  cert)
static

Definition at line 1840 of file chain.c.

1841{
1842 BOOL ret = TRUE;
1843
1844 /* Checks whether the contents of the cert match the cert's version. */
1845 switch (cert->pCertInfo->dwVersion)
1846 {
1847 case CERT_V1:
1848 /* A V1 cert may not contain unique identifiers. See RFC 5280,
1849 * section 4.1.2.8:
1850 * "These fields MUST only appear if the version is 2 or 3 (Section
1851 * 4.1.2.1). These fields MUST NOT appear if the version is 1."
1852 */
1853 if (cert->pCertInfo->IssuerUniqueId.cbData ||
1854 cert->pCertInfo->SubjectUniqueId.cbData)
1855 ret = FALSE;
1856 /* A V1 cert may not contain extensions. See RFC 5280, section 4.1.2.9:
1857 * "This field MUST only appear if the version is 3 (Section 4.1.2.1)."
1858 */
1859 if (cert->pCertInfo->cExtension)
1860 ret = FALSE;
1861 break;
1862 case CERT_V2:
1863 /* A V2 cert may not contain extensions. See RFC 5280, section 4.1.2.9:
1864 * "This field MUST only appear if the version is 3 (Section 4.1.2.1)."
1865 */
1866 if (cert->pCertInfo->cExtension)
1867 ret = FALSE;
1868 break;
1869 case CERT_V3:
1870 /* Do nothing, all fields are allowed for V3 certs */
1871 break;
1872 default:
1873 WARN_(chain)("invalid cert version %d\n", cert->pCertInfo->dwVersion);
1874 ret = FALSE;
1875 }
1876 return ret;
1877}
#define WARN_(ch,...)
Definition: debug.h:157
#define CERT_V3
Definition: wincrypt.h:2658

Referenced by CRYPT_CheckSimpleChain().

◆ CRYPT_IsEmptyName()

static BOOL CRYPT_IsEmptyName ( const CERT_NAME_BLOB name)
static

Definition at line 1110 of file chain.c.

1111{
1112 BOOL empty;
1113
1114 if (!name->cbData)
1115 empty = TRUE;
1116 else if (name->cbData == 2 && name->pbData[1] == 0)
1117 {
1118 /* An empty sequence is also empty */
1119 empty = TRUE;
1120 }
1121 else
1122 empty = FALSE;
1123 return empty;
1124}
static const WCHAR empty[]
Definition: main.c:47

Referenced by compare_subject_with_constraints().

◆ CRYPT_IsSimpleChainCyclic()

static BOOL CRYPT_IsSimpleChainCyclic ( const CERT_SIMPLE_CHAIN chain)
inlinestatic

Definition at line 407 of file chain.c.

408{
409 if (chain->cElement)
410 return chain->rgpElement[chain->cElement - 1]->TrustStatus.dwErrorStatus
412 else
413 return FALSE;
414}

Referenced by CRYPT_BuildSimpleChain(), and CRYPT_CheckSimpleChain().

◆ CRYPT_IsValidNameConstraint()

static BOOL CRYPT_IsValidNameConstraint ( const CERT_NAME_CONSTRAINTS_INFO info)
static

Definition at line 1234 of file chain.c.

1235{
1236 DWORD i;
1237 BOOL ret = TRUE;
1238
1239 /* Make sure at least one permitted or excluded subtree is present. From
1240 * RFC 5280, section 4.2.1.10:
1241 * "Conforming CAs MUST NOT issue certificates where name constraints is an
1242 * empty sequence. That is, either the permittedSubtrees field or the
1243 * excludedSubtrees MUST be present."
1244 */
1245 if (!info->cPermittedSubtree && !info->cExcludedSubtree)
1246 {
1247 WARN_(chain)("constraints contain no permitted nor excluded subtree\n");
1248 ret = FALSE;
1249 }
1250 /* Check that none of the constraints specifies a minimum or a maximum.
1251 * See RFC 5280, section 4.2.1.10:
1252 * "Within this profile, the minimum and maximum fields are not used with
1253 * any name forms, thus, the minimum MUST be zero, and maximum MUST be
1254 * absent. However, if an application encounters a critical name
1255 * constraints extension that specifies other values for minimum or
1256 * maximum for a name form that appears in a subsequent certificate, the
1257 * application MUST either process these fields or reject the
1258 * certificate."
1259 * Since it gives no guidance as to how to process these fields, we
1260 * reject any name constraint that contains them.
1261 */
1262 for (i = 0; ret && i < info->cPermittedSubtree; i++)
1263 if (info->rgPermittedSubtree[i].dwMinimum ||
1264 info->rgPermittedSubtree[i].fMaximum)
1265 {
1266 TRACE_(chain)("found a minimum or maximum in permitted subtrees\n");
1267 ret = FALSE;
1268 }
1269 for (i = 0; ret && i < info->cExcludedSubtree; i++)
1270 if (info->rgExcludedSubtree[i].dwMinimum ||
1271 info->rgExcludedSubtree[i].fMaximum)
1272 {
1273 TRACE_(chain)("found a minimum or maximum in excluded subtrees\n");
1274 ret = FALSE;
1275 }
1276 return ret;
1277}

Referenced by CRYPT_CheckChainNameConstraints().

◆ CRYPT_KeyUsageValid()

static BOOL CRYPT_KeyUsageValid ( CertificateChainEngine engine,
PCCERT_CONTEXT  cert,
BOOL  isRoot,
BOOL  isCA,
DWORD  index 
)
static

Definition at line 1723 of file chain.c.

1725{
1727 BOOL ret;
1728 BYTE usageBits = 0;
1729
1730 ext = CertFindExtension(szOID_KEY_USAGE, cert->pCertInfo->cExtension,
1731 cert->pCertInfo->rgExtension);
1732 if (ext)
1733 {
1735 DWORD size = sizeof(usage);
1736
1737 ret = CryptDecodeObjectEx(cert->dwCertEncodingType, X509_BITS,
1738 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL,
1739 &usage, &size);
1740 if (!ret)
1741 return FALSE;
1742 else if (usage.cbData > 2)
1743 {
1744 /* The key usage extension only defines 9 bits => no more than 2
1745 * bytes are needed to encode all known usages.
1746 */
1747 return FALSE;
1748 }
1749 else
1750 {
1751 /* The only bit relevant to chain validation is the keyCertSign
1752 * bit, which is always in the least significant byte of the
1753 * key usage bits.
1754 */
1755 usageBits = usage.pbData[usage.cbData - 1];
1756 }
1757 }
1758 if (isCA)
1759 {
1760 if (!ext)
1761 {
1762 /* MS appears to violate RFC 5280, section 4.2.1.3 (Key Usage)
1763 * here. Quoting the RFC:
1764 * "This [key usage] extension MUST appear in certificates that
1765 * contain public keys that are used to validate digital signatures
1766 * on other public key certificates or CRLs."
1767 * MS appears to accept certs that do not contain key usage
1768 * extensions as CA certs. V1 and V2 certificates did not have
1769 * extensions, and many root certificates are V1 certificates, so
1770 * perhaps this is prudent. On the other hand, MS also accepts V3
1771 * certs without key usage extensions. Because some CAs, e.g.
1772 * Certum, also do not include key usage extensions in their
1773 * intermediate certificates, we are forced to accept V3
1774 * certificates without key usage extensions as well.
1775 */
1776 ret = TRUE;
1777 }
1778 else
1779 {
1780 if (!(usageBits & CERT_KEY_CERT_SIGN_KEY_USAGE))
1781 {
1782 WARN_(chain)("keyCertSign not asserted on a CA cert\n");
1783 ret = FALSE;
1784 }
1785 else
1786 ret = TRUE;
1787 }
1788 }
1789 else
1790 {
1791 if (ext && (usageBits & CERT_KEY_CERT_SIGN_KEY_USAGE))
1792 {
1793 WARN_(chain)("keyCertSign asserted on a non-CA cert\n");
1794 ret = FALSE;
1795 }
1796 else
1797 ret = TRUE;
1798 }
1799 return ret;
1800}
#define X509_BITS
Definition: wincrypt.h:3392
#define CERT_KEY_CERT_SIGN_KEY_USAGE
Definition: wincrypt.h:309

Referenced by CRYPT_CheckSimpleChain().

◆ CRYPT_VerifyChainRevocation()

static void CRYPT_VerifyChainRevocation ( PCERT_CHAIN_CONTEXT  chain,
LPFILETIME  pTime,
HCERTSTORE  hAdditionalStore,
const CERT_CHAIN_PARA pChainPara,
DWORD  chainFlags 
)
static

Definition at line 2632 of file chain.c.

2635{
2636 DWORD cContext;
2637
2638 if (chainFlags & CERT_CHAIN_REVOCATION_CHECK_END_CERT)
2639 cContext = 1;
2640 else if ((chainFlags & CERT_CHAIN_REVOCATION_CHECK_CHAIN) ||
2642 {
2643 DWORD i;
2644
2645 for (i = 0, cContext = 0; i < chain->cChain; i++)
2646 {
2647 if (i < chain->cChain - 1 ||
2649 cContext += chain->rgpChain[i]->cElement;
2650 else
2651 cContext += chain->rgpChain[i]->cElement - 1;
2652 }
2653 }
2654 else
2655 cContext = 0;
2656 if (cContext)
2657 {
2658 DWORD i, j, iContext, revocationFlags;
2659 CERT_REVOCATION_PARA revocationPara = { sizeof(revocationPara), 0 };
2660 CERT_REVOCATION_STATUS revocationStatus =
2661 { sizeof(revocationStatus), 0 };
2662 BOOL ret;
2663
2664 revocationFlags = CERT_VERIFY_REV_CHAIN_FLAG;
2666 revocationFlags |= CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION;
2669 revocationPara.pftTimeToUse = pTime;
2670 if (hAdditionalStore)
2671 {
2672 revocationPara.cCertStore = 1;
2673 revocationPara.rgCertStore = &hAdditionalStore;
2674 revocationPara.hCrlStore = hAdditionalStore;
2675 }
2676 if (pChainPara->cbSize == sizeof(CERT_CHAIN_PARA))
2677 {
2678 revocationPara.dwUrlRetrievalTimeout =
2679 pChainPara->dwUrlRetrievalTimeout;
2680 revocationPara.fCheckFreshnessTime =
2681 pChainPara->fCheckRevocationFreshnessTime;
2682 revocationPara.dwFreshnessTime =
2683 pChainPara->dwRevocationFreshnessTime;
2684 }
2685 for (i = 0, iContext = 0; iContext < cContext && i < chain->cChain; i++)
2686 {
2687 for (j = 0; iContext < cContext &&
2688 j < chain->rgpChain[i]->cElement; j++, iContext++)
2689 {
2690 PCCERT_CONTEXT certToCheck =
2691 chain->rgpChain[i]->rgpElement[j]->pCertContext;
2692
2693 if (j < chain->rgpChain[i]->cElement - 1)
2694 revocationPara.pIssuerCert =
2695 chain->rgpChain[i]->rgpElement[j + 1]->pCertContext;
2696 else
2697 revocationPara.pIssuerCert = NULL;
2699 CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certToCheck,
2700 revocationFlags, &revocationPara, &revocationStatus);
2701
2702 if (!ret && chainFlags & CERT_CHAIN_REVOCATION_CHECK_CHAIN
2703 && revocationStatus.dwError == CRYPT_E_NO_REVOCATION_CHECK && revocationPara.pIssuerCert == NULL)
2704 ret = TRUE;
2705
2706 if (!ret)
2707 {
2709 chain, iContext);
2710 DWORD error;
2711
2712 switch (revocationStatus.dwError)
2713 {
2717 /* If the revocation status is unknown, it's assumed
2718 * to be offline too.
2719 */
2722 break;
2725 break;
2726 case CRYPT_E_REVOKED:
2728 break;
2729 default:
2730 WARN("unmapped error %08x\n", revocationStatus.dwError);
2731 error = 0;
2732 }
2733 if (element)
2734 {
2735 /* FIXME: set element's pRevocationInfo member */
2736 element->TrustStatus.dwErrorStatus |= error;
2737 }
2738 chain->TrustStatus.dwErrorStatus |= error;
2739 }
2740 }
2741 }
2742 }
2743}
#define WARN(fmt,...)
Definition: debug.h:112
BOOL WINAPI CertVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType, DWORD cContext, PVOID rgpvContext[], DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus)
Definition: cert.c:1934
static PCERT_CHAIN_ELEMENT CRYPT_FindIthElementInChain(const CERT_CHAIN_CONTEXT *chain, DWORD i)
Definition: chain.c:2611
#define error(str)
Definition: mkdosfs.c:1605
LPFILETIME pftTimeToUse
Definition: wincrypt.h:808
HCERTSTORE hCrlStore
Definition: wincrypt.h:807
PCCERT_CONTEXT pIssuerCert
Definition: wincrypt.h:804
HCERTSTORE * rgCertStore
Definition: wincrypt.h:806
#define CERT_TRUST_IS_REVOKED
Definition: wincrypt.h:872
#define CERT_TRUST_REVOCATION_STATUS_UNKNOWN
Definition: wincrypt.h:876
#define CERT_CHAIN_REVOCATION_CHECK_CHAIN
Definition: wincrypt.h:1057
#define CERT_CHAIN_REVOCATION_CHECK_END_CERT
Definition: wincrypt.h:1056
#define CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT
Definition: wincrypt.h:1061
#define CERT_TRUST_IS_OFFLINE_REVOCATION
Definition: wincrypt.h:886
#define CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION
Definition: wincrypt.h:820
#define CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
Definition: wincrypt.h:1058
#define CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG
Definition: wincrypt.h:821
#define CERT_CONTEXT_REVOCATION_TYPE
Definition: wincrypt.h:818
#define CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY
Definition: wincrypt.h:1059
#define CERT_VERIFY_REV_CHAIN_FLAG
Definition: wincrypt.h:819
#define CRYPT_E_REVOKED
Definition: winerror.h:3019
#define CRYPT_E_NO_REVOCATION_DLL
Definition: winerror.h:3020
#define CRYPT_E_NOT_IN_REVOCATION_DATABASE
Definition: winerror.h:3023
#define CRYPT_E_NO_REVOCATION_CHECK
Definition: winerror.h:3021
#define CRYPT_E_REVOCATION_OFFLINE
Definition: winerror.h:3022

Referenced by CertGetCertificateChain().

◆ debugstr_filetime()

static LPCSTR debugstr_filetime ( LPFILETIME  pTime)
static

Definition at line 2213 of file chain.c.

2214{
2215 if (!pTime)
2216 return "(nil)";
2217 return wine_dbg_sprintf("%p (%s)", pTime, filetime_to_str(pTime));
2218}
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296

Referenced by CertGetCertificateChain(), CRYPT_BuildAlternateContextFromChain(), and CRYPT_GetSimpleChainForCert().

◆ default_chain_engine_free()

void default_chain_engine_free ( void  )

Definition at line 255 of file chain.c.

256{
259}
static CertificateChainEngine * default_lm_engine
Definition: chain.c:164
static CertificateChainEngine * default_cu_engine
Definition: chain.c:164

Referenced by DllMain().

◆ directory_name_matches()

static BOOL directory_name_matches ( const CERT_NAME_BLOB constraint,
const CERT_NAME_BLOB name 
)
static

Definition at line 864 of file chain.c.

866{
867 CERT_NAME_INFO *constraintName;
868 DWORD size;
869 BOOL match = FALSE;
870
872 constraint->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &constraintName, &size))
873 {
874 DWORD i;
875
876 match = TRUE;
877 for (i = 0; match && i < constraintName->cRDN; i++)
880 (CERT_NAME_BLOB *)name, &constraintName->rgRDN[i]);
881 LocalFree(constraintName);
882 }
883 return match;
884}
BOOL WINAPI CertIsRDNAttrsInCertificateName(DWORD dwCertEncodingType, DWORD dwFlags, PCERT_NAME_BLOB pCertName, PCERT_RDN pRDN)
Definition: cert.c:2131
PCERT_RDN rgRDN
Definition: wincrypt.h:268
#define X509_NAME
Definition: wincrypt.h:3372
#define CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG
Definition: wincrypt.h:2807

Referenced by alt_name_matches(), and compare_subject_with_constraints().

◆ dns_name_matches()

static BOOL dns_name_matches ( LPCWSTR  constraint,
LPCWSTR  name,
DWORD trustErrorStatus 
)
static

Definition at line 775 of file chain.c.

777{
778 BOOL match = FALSE;
779
780 TRACE("%s, %s\n", debugstr_w(constraint), debugstr_w(name));
781
782 if (!constraint)
783 *trustErrorStatus |= CERT_TRUST_INVALID_NAME_CONSTRAINTS;
784 else if (!name)
785 ; /* no match */
786 /* RFC 5280, section 4.2.1.10:
787 * "DNS name restrictions are expressed as host.example.com. Any DNS name
788 * that can be constructed by simply adding zero or more labels to the
789 * left-hand side of the name satisfies the name constraint. For example,
790 * www.host.example.com would satisfy the constraint but host1.example.com
791 * would not."
792 */
793 else if (lstrlenW(name) == lstrlenW(constraint))
794 match = !lstrcmpiW(name, constraint);
795 else if (lstrlenW(name) > lstrlenW(constraint))
796 {
797 match = !lstrcmpiW(name + lstrlenW(name) - lstrlenW(constraint),
798 constraint);
799 if (match)
800 {
801 BOOL dot = FALSE;
802 LPCWSTR ptr;
803
804 /* This only matches if name is a subdomain of constraint, i.e.
805 * there's a '.' between the beginning of the name and the
806 * matching portion of the name.
807 */
808 for (ptr = name + lstrlenW(name) - lstrlenW(constraint);
809 !dot && ptr >= name; ptr--)
810 if (*ptr == '.')
811 dot = TRUE;
812 match = dot;
813 }
814 }
815 /* else: name is too short, no match */
816
817 return match;
818}
#define lstrlenW
Definition: compat.h:750
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
static PVOID ptr
Definition: dispmode.c:27
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by alt_name_matches().

◆ domain_name_matches()

static BOOL domain_name_matches ( LPCWSTR  constraint,
LPCWSTR  name 
)
static

Definition at line 647 of file chain.c.

648{
649 BOOL match;
650
651 /* RFC 5280, section 4.2.1.10:
652 * "For URIs, the constraint applies to the host part of the name...
653 * When the constraint begins with a period, it MAY be expanded with one
654 * or more labels. That is, the constraint ".example.com" is satisfied by
655 * both host.example.com and my.host.example.com. However, the constraint
656 * ".example.com" is not satisfied by "example.com". When the constraint
657 * does not begin with a period, it specifies a host."
658 * and for email addresses,
659 * "To indicate all Internet mail addresses on a particular host, the
660 * constraint is specified as the host name. For example, the constraint
661 * "example.com" is satisfied by any mail address at the host
662 * "example.com". To specify any address within a domain, the constraint
663 * is specified with a leading period (as with URIs)."
664 */
665 if (constraint[0] == '.')
666 {
667 /* Must be strictly greater than, a name can't begin with '.' */
668 if (lstrlenW(name) > lstrlenW(constraint))
669 match = !lstrcmpiW(name + lstrlenW(name) - lstrlenW(constraint),
670 constraint);
671 else
672 {
673 /* name is too short, no match */
674 match = FALSE;
675 }
676 }
677 else
678 match = !lstrcmpiW(name, constraint);
679 return match;
680}

Referenced by rfc822_name_matches(), and url_matches().

◆ dump_alt_name()

static void dump_alt_name ( LPCSTR  type,
const CERT_EXTENSION ext 
)
static

Definition at line 1465 of file chain.c.

1466{
1468 DWORD size;
1469
1470 TRACE_(chain)("%s:\n", type);
1472 ext->Value.pbData, ext->Value.cbData,
1474 {
1475 DWORD i;
1476
1477 TRACE_(chain)("%d alt name entries:\n", name->cAltEntry);
1478 for (i = 0; i < name->cAltEntry; i++)
1479 dump_alt_name_entry(&name->rgAltEntry[i]);
1480 LocalFree(name);
1481 }
1482}
static void dump_alt_name_entry(const CERT_ALT_NAME_ENTRY *entry)
Definition: chain.c:1426

Referenced by dump_extension().

◆ dump_alt_name_entry()

static void dump_alt_name_entry ( const CERT_ALT_NAME_ENTRY entry)
static

Definition at line 1426 of file chain.c.

1427{
1428 LPWSTR str;
1429
1430 switch (entry->dwAltNameChoice)
1431 {
1433 TRACE_(chain)("CERT_ALT_NAME_OTHER_NAME, oid = %s\n",
1434 debugstr_a(entry->u.pOtherName->pszObjId));
1435 break;
1437 TRACE_(chain)("CERT_ALT_NAME_RFC822_NAME: %s\n",
1438 debugstr_w(entry->u.pwszRfc822Name));
1439 break;
1441 TRACE_(chain)("CERT_ALT_NAME_DNS_NAME: %s\n",
1442 debugstr_w(entry->u.pwszDNSName));
1443 break;
1445 str = name_value_to_str(&entry->u.DirectoryName);
1446 TRACE_(chain)("CERT_ALT_NAME_DIRECTORY_NAME: %s\n", debugstr_w(str));
1448 break;
1449 case CERT_ALT_NAME_URL:
1450 TRACE_(chain)("CERT_ALT_NAME_URL: %s\n", debugstr_w(entry->u.pwszURL));
1451 break;
1453 TRACE_(chain)("CERT_ALT_NAME_IP_ADDRESS: %d bytes\n",
1454 entry->u.IPAddress.cbData);
1455 break;
1457 TRACE_(chain)("CERT_ALT_NAME_REGISTERED_ID: %s\n",
1458 debugstr_a(entry->u.pszRegisteredID));
1459 break;
1460 default:
1461 TRACE_(chain)("dwAltNameChoice = %d\n", entry->dwAltNameChoice);
1462 }
1463}
static LPWSTR name_value_to_str(const CERT_NAME_BLOB *name)
Definition: chain.c:1410
uint32_t entry
Definition: isohybrid.c:63
const WCHAR * str
#define CERT_ALT_NAME_OTHER_NAME
Definition: wincrypt.h:345
#define CERT_ALT_NAME_REGISTERED_ID
Definition: wincrypt.h:353
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by dump_alt_name(), and dump_general_subtree().

◆ dump_authenticode_extra_chain_policy_para()

static void dump_authenticode_extra_chain_policy_para ( AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA extraPara)
static

Definition at line 3077 of file chain.c.

3079{
3080 if (extraPara)
3081 {
3082 TRACE_(chain)("cbSize = %d\n", extraPara->cbSize);
3083 TRACE_(chain)("dwRegPolicySettings = %08x\n",
3084 extraPara->dwRegPolicySettings);
3085 TRACE_(chain)("pSignerInfo = %p\n", extraPara->pSignerInfo);
3086 }
3087}

Referenced by verify_authenticode_policy().

◆ dump_basic_constraints()

static void dump_basic_constraints ( const CERT_EXTENSION ext)
static

Definition at line 1484 of file chain.c.

1485{
1487 DWORD size = 0;
1488
1490 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG,
1491 NULL, &info, &size))
1492 {
1493 TRACE_(chain)("SubjectType: %02x\n", info->SubjectType.pbData[0]);
1494 TRACE_(chain)("%s path length constraint\n",
1495 info->fPathLenConstraint ? "has" : "doesn't have");
1496 TRACE_(chain)("path length=%d\n", info->dwPathLenConstraint);
1497 LocalFree(info);
1498 }
1499}

Referenced by dump_extension().

◆ dump_basic_constraints2()

static void dump_basic_constraints2 ( const CERT_EXTENSION ext)
static

Definition at line 1501 of file chain.c.

1502{
1503 CERT_BASIC_CONSTRAINTS2_INFO constraints;
1505
1507 szOID_BASIC_CONSTRAINTS2, ext->Value.pbData, ext->Value.cbData,
1508 0, NULL, &constraints, &size))
1509 {
1510 TRACE_(chain)("basic constraints:\n");
1511 TRACE_(chain)("can%s be a CA\n", constraints.fCA ? "" : "not");
1512 TRACE_(chain)("%s path length constraint\n",
1513 constraints.fPathLenConstraint ? "has" : "doesn't have");
1514 TRACE_(chain)("path length=%d\n", constraints.dwPathLenConstraint);
1515 }
1516}

Referenced by dump_extension().

◆ dump_cert_policies()

static void dump_cert_policies ( const CERT_EXTENSION ext)
static

Definition at line 1576 of file chain.c.

1577{
1578 CERT_POLICIES_INFO *policies;
1579 DWORD size;
1580
1582 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
1583 &policies, &size))
1584 {
1585 DWORD i, j;
1586
1587 TRACE_(chain)("%d policies:\n", policies->cPolicyInfo);
1588 for (i = 0; i < policies->cPolicyInfo; i++)
1589 {
1590 TRACE_(chain)("policy identifier: %s\n",
1592 TRACE_(chain)("%d policy qualifiers:\n",
1593 policies->rgPolicyInfo[i].cPolicyQualifier);
1594 for (j = 0; j < policies->rgPolicyInfo[i].cPolicyQualifier; j++)
1595 TRACE_(chain)("%s\n", debugstr_a(
1596 policies->rgPolicyInfo[i].rgPolicyQualifier[j].
1597 pszPolicyQualifierId));
1598 }
1599 LocalFree(policies);
1600 }
1601}
CERT_POLICY_QUALIFIER_INFO * rgPolicyQualifier
Definition: wincrypt.h:395
DWORD cPolicyQualifier
Definition: wincrypt.h:394

Referenced by dump_extension().

◆ dump_chain_para()

static void dump_chain_para ( const CERT_CHAIN_PARA pChainPara)
static

Definition at line 2864 of file chain.c.

2865{
2866 TRACE_(chain)("%d\n", pChainPara->cbSize);
2867 if (pChainPara->cbSize >= sizeof(CERT_CHAIN_PARA_NO_EXTRA_FIELDS))
2868 dump_usage_match("RequestedUsage", &pChainPara->RequestedUsage);
2869 if (pChainPara->cbSize >= sizeof(CERT_CHAIN_PARA))
2870 {
2871 dump_usage_match("RequestedIssuancePolicy",
2872 &pChainPara->RequestedIssuancePolicy);
2873 TRACE_(chain)("%d\n", pChainPara->dwUrlRetrievalTimeout);
2874 TRACE_(chain)("%d\n", pChainPara->fCheckRevocationFreshnessTime);
2875 TRACE_(chain)("%d\n", pChainPara->dwRevocationFreshnessTime);
2876 }
2877}
static void dump_usage_match(LPCSTR name, const CERT_USAGE_MATCH *usageMatch)
Definition: chain.c:2851

Referenced by CertGetCertificateChain().

◆ dump_element()

static void dump_element ( PCCERT_CONTEXT  cert)
static

Definition at line 1689 of file chain.c.

1690{
1691 LPWSTR name = NULL;
1692 DWORD len, i;
1693
1694 TRACE_(chain)("%p: version %d\n", cert, cert->pCertInfo->dwVersion);
1697 name = CryptMemAlloc(len * sizeof(WCHAR));
1698 if (name)
1699 {
1702 TRACE_(chain)("issued by %s\n", debugstr_w(name));
1704 }
1706 NULL, 0);
1707 name = CryptMemAlloc(len * sizeof(WCHAR));
1708 if (name)
1709 {
1711 name, len);
1712 TRACE_(chain)("issued to %s\n", debugstr_w(name));
1714 }
1715 TRACE_(chain)("valid from %s to %s\n",
1716 filetime_to_str(&cert->pCertInfo->NotBefore),
1717 filetime_to_str(&cert->pCertInfo->NotAfter));
1718 TRACE_(chain)("%d extensions\n", cert->pCertInfo->cExtension);
1719 for (i = 0; i < cert->pCertInfo->cExtension; i++)
1720 dump_extension(&cert->pCertInfo->rgExtension[i]);
1721}
static void dump_extension(const CERT_EXTENSION *ext)
Definition: chain.c:1647
DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString)
Definition: str.c:1228
GLenum GLsizei len
Definition: glext.h:6722
#define CERT_NAME_SIMPLE_DISPLAY_TYPE
Definition: wincrypt.h:3500
#define CERT_NAME_ISSUER_FLAG
Definition: wincrypt.h:3506

Referenced by CRYPT_CheckSimpleChain().

◆ dump_enhanced_key_usage()

static void dump_enhanced_key_usage ( const CERT_EXTENSION ext)
static

Definition at line 1603 of file chain.c.

1604{
1606 DWORD size;
1607
1609 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
1610 &usage, &size))
1611 {
1612 DWORD i;
1613
1614 TRACE_(chain)("%d usages:\n", usage->cUsageIdentifier);
1615 for (i = 0; i < usage->cUsageIdentifier; i++)
1616 TRACE_(chain)("%s\n", usage->rgpszUsageIdentifier[i]);
1618 }
1619}

Referenced by dump_extension().

◆ dump_extension()

static void dump_extension ( const CERT_EXTENSION ext)
static

Definition at line 1647 of file chain.c.

1648{
1649 TRACE_(chain)("%s (%scritical)\n", debugstr_a(ext->pszObjId),
1650 ext->fCritical ? "" : "not ");
1651 if (!strcmp(ext->pszObjId, szOID_SUBJECT_ALT_NAME))
1652 dump_alt_name("subject alt name", ext);
1653 else if (!strcmp(ext->pszObjId, szOID_ISSUER_ALT_NAME))
1654 dump_alt_name("issuer alt name", ext);
1655 else if (!strcmp(ext->pszObjId, szOID_BASIC_CONSTRAINTS))
1657 else if (!strcmp(ext->pszObjId, szOID_KEY_USAGE))
1659 else if (!strcmp(ext->pszObjId, szOID_SUBJECT_ALT_NAME2))
1660 dump_alt_name("subject alt name 2", ext);
1661 else if (!strcmp(ext->pszObjId, szOID_ISSUER_ALT_NAME2))
1662 dump_alt_name("issuer alt name 2", ext);
1663 else if (!strcmp(ext->pszObjId, szOID_BASIC_CONSTRAINTS2))
1665 else if (!strcmp(ext->pszObjId, szOID_NAME_CONSTRAINTS))
1667 else if (!strcmp(ext->pszObjId, szOID_CERT_POLICIES))
1669 else if (!strcmp(ext->pszObjId, szOID_ENHANCED_KEY_USAGE))
1671 else if (!strcmp(ext->pszObjId, szOID_NETSCAPE_CERT_TYPE))
1673}
static void dump_netscape_cert_type(const CERT_EXTENSION *ext)
Definition: chain.c:1621
static void dump_basic_constraints(const CERT_EXTENSION *ext)
Definition: chain.c:1484
static void dump_key_usage(const CERT_EXTENSION *ext)
Definition: chain.c:1518
static void dump_enhanced_key_usage(const CERT_EXTENSION *ext)
Definition: chain.c:1603
static void dump_basic_constraints2(const CERT_EXTENSION *ext)
Definition: chain.c:1501
static void dump_alt_name(LPCSTR type, const CERT_EXTENSION *ext)
Definition: chain.c:1465
static void dump_name_constraints(const CERT_EXTENSION *ext)
Definition: chain.c:1552
static void dump_cert_policies(const CERT_EXTENSION *ext)
Definition: chain.c:1576
#define szOID_ISSUER_ALT_NAME2
Definition: wincrypt.h:3188
#define szOID_NETSCAPE_CERT_TYPE
Definition: wincrypt.h:3340
#define szOID_ISSUER_ALT_NAME
Definition: wincrypt.h:3181

Referenced by dump_element().

◆ dump_general_subtree()

static void dump_general_subtree ( const CERT_GENERAL_SUBTREE subtree)
static

Definition at line 1545 of file chain.c.

1546{
1547 dump_alt_name_entry(&subtree->Base);
1548 TRACE_(chain)("dwMinimum = %d, fMaximum = %d, dwMaximum = %d\n",
1549 subtree->dwMinimum, subtree->fMaximum, subtree->dwMaximum);
1550}

Referenced by dump_name_constraints().

◆ dump_key_usage()

static void dump_key_usage ( const CERT_EXTENSION ext)
static

Definition at line 1518 of file chain.c.

1519{
1521 DWORD size = sizeof(usage);
1522
1524 ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL, &usage, &size))
1525 {
1526#define trace_usage_bit(bits, bit) \
1527 if ((bits) & (bit)) TRACE_(chain)("%s\n", #bit)
1528 if (usage.cbData)
1529 {
1538 }
1539#undef trace_usage_bit
1540 if (usage.cbData > 1 && usage.pbData[1] & CERT_DECIPHER_ONLY_KEY_USAGE)
1541 TRACE_(chain)("CERT_DECIPHER_ONLY_KEY_USAGE\n");
1542 }
1543}
#define trace_usage_bit(bits, bit)
#define CERT_KEY_ENCIPHERMENT_KEY_USAGE
Definition: wincrypt.h:306
#define CERT_NON_REPUDIATION_KEY_USAGE
Definition: wincrypt.h:305
#define CERT_CRL_SIGN_KEY_USAGE
Definition: wincrypt.h:311
#define CERT_DIGITAL_SIGNATURE_KEY_USAGE
Definition: wincrypt.h:304
#define CERT_ENCIPHER_ONLY_KEY_USAGE
Definition: wincrypt.h:312
#define CERT_DECIPHER_ONLY_KEY_USAGE
Definition: wincrypt.h:314
#define CERT_KEY_AGREEMENT_KEY_USAGE
Definition: wincrypt.h:308
#define CERT_DATA_ENCIPHERMENT_KEY_USAGE
Definition: wincrypt.h:307

Referenced by dump_extension().

◆ dump_name_constraints()

static void dump_name_constraints ( const CERT_EXTENSION ext)
static

Definition at line 1552 of file chain.c.

1553{
1554 CERT_NAME_CONSTRAINTS_INFO *nameConstraints;
1555 DWORD size;
1556
1558 ext->Value.pbData, ext->Value.cbData,
1560 &size))
1561 {
1562 DWORD i;
1563
1564 TRACE_(chain)("%d permitted subtrees:\n",
1565 nameConstraints->cPermittedSubtree);
1566 for (i = 0; i < nameConstraints->cPermittedSubtree; i++)
1567 dump_general_subtree(&nameConstraints->rgPermittedSubtree[i]);
1568 TRACE_(chain)("%d excluded subtrees:\n",
1569 nameConstraints->cExcludedSubtree);
1570 for (i = 0; i < nameConstraints->cExcludedSubtree; i++)
1571 dump_general_subtree(&nameConstraints->rgExcludedSubtree[i]);
1572 LocalFree(nameConstraints);
1573 }
1574}
static void dump_general_subtree(const CERT_GENERAL_SUBTREE *subtree)
Definition: chain.c:1545

Referenced by dump_extension().

◆ dump_netscape_cert_type()

static void dump_netscape_cert_type ( const CERT_EXTENSION ext)
static

Definition at line 1621 of file chain.c.

1622{
1624 DWORD size = sizeof(usage);
1625
1627 ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL, &usage, &size))
1628 {
1629#define trace_cert_type_bit(bits, bit) \
1630 if ((bits) & (bit)) TRACE_(chain)("%s\n", #bit)
1631 if (usage.cbData)
1632 {
1633 trace_cert_type_bit(usage.pbData[0],
1635 trace_cert_type_bit(usage.pbData[0],
1642 }
1643#undef trace_cert_type_bit
1644 }
1645}
#define trace_cert_type_bit(bits, bit)
#define NETSCAPE_SSL_CA_CERT_TYPE
Definition: wincrypt.h:3360
#define NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE
Definition: wincrypt.h:3357
#define NETSCAPE_SIGN_CERT_TYPE
Definition: wincrypt.h:3359
#define NETSCAPE_SIGN_CA_CERT_TYPE
Definition: wincrypt.h:3362
#define NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE
Definition: wincrypt.h:3356
#define NETSCAPE_SMIME_CERT_TYPE
Definition: wincrypt.h:3358
#define NETSCAPE_SMIME_CA_CERT_TYPE
Definition: wincrypt.h:3361

Referenced by dump_extension().

◆ dump_policy_para()

static void dump_policy_para ( PCERT_CHAIN_POLICY_PARA  para)
static

Definition at line 3706 of file chain.c.

3707{
3708 if (para)
3709 {
3710 TRACE_(chain)("cbSize = %d\n", para->cbSize);
3711 TRACE_(chain)("dwFlags = %08x\n", para->dwFlags);
3712 TRACE_(chain)("pvExtraPolicyPara = %p\n", para->pvExtraPolicyPara);
3713 }
3714}

Referenced by CertVerifyCertificateChainPolicy().

◆ dump_ssl_extra_chain_policy_para()

static void dump_ssl_extra_chain_policy_para ( HTTPSPolicyCallbackData sslPara)
static

Definition at line 3446 of file chain.c.

3447{
3448 if (sslPara)
3449 {
3450 TRACE_(chain)("cbSize = %d\n", sslPara->u.cbSize);
3451 TRACE_(chain)("dwAuthType = %d\n", sslPara->dwAuthType);
3452 TRACE_(chain)("fdwChecks = %08x\n", sslPara->fdwChecks);
3453 TRACE_(chain)("pwszServerName = %s\n",
3454 debugstr_w(sslPara->pwszServerName));
3455 }
3456}

Referenced by verify_ssl_policy().

◆ dump_usage_match()

static void dump_usage_match ( LPCSTR  name,
const CERT_USAGE_MATCH usageMatch 
)
static

Definition at line 2851 of file chain.c.

2852{
2853 if (usageMatch->Usage.cUsageIdentifier)
2854 {
2855 DWORD i;
2856
2857 TRACE_(chain)("%s: %s\n", name,
2858 usageMatch->dwType == USAGE_MATCH_TYPE_AND ? "AND" : "OR");
2859 for (i = 0; i < usageMatch->Usage.cUsageIdentifier; i++)
2860 TRACE_(chain)("%s\n", usageMatch->Usage.rgpszUsageIdentifier[i]);
2861 }
2862}
CERT_ENHKEY_USAGE Usage
Definition: wincrypt.h:1048

Referenced by dump_chain_para().

◆ filetime_to_str()

static LPCSTR filetime_to_str ( const FILETIME time)
static

Definition at line 1675 of file chain.c.

1676{
1677 char date[80];
1678 char dateFmt[80]; /* sufficient for all versions of LOCALE_SSHORTDATE */
1679 SYSTEMTIME sysTime;
1680
1681 if (!time) return "(null)";
1682
1684 FileTimeToSystemTime(time, &sysTime);
1685 GetDateFormatA(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, date, ARRAY_SIZE(date));
1686 return wine_dbg_sprintf("%s", date);
1687}
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
INT WINAPI GetLocaleInfoA(LCID lcid, LCTYPE lctype, LPSTR buffer, INT len)
Definition: lang.c:1028
INT WINAPI GetDateFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCSTR lpFormat, LPSTR lpDateStr, INT cchOut)
Definition: lcformat.c:936
__u16 date
Definition: mkdosfs.c:8
#define LOCALE_SYSTEM_DEFAULT
#define LOCALE_SSHORTDATE
Definition: winnls.h:60

Referenced by CRYPT_CheckSimpleChain(), debugstr_filetime(), and dump_element().

◆ find_element_with_error()

static void find_element_with_error ( PCCERT_CHAIN_CONTEXT  chain,
DWORD  error,
LONG iChain,
LONG iElement 
)
static

Definition at line 2982 of file chain.c.

2984{
2985 DWORD i, j;
2986
2987 for (i = 0; i < chain->cChain; i++)
2988 for (j = 0; j < chain->rgpChain[i]->cElement; j++)
2989 if (chain->rgpChain[i]->rgpElement[j]->TrustStatus.dwErrorStatus &
2990 error)
2991 {
2992 *iChain = i;
2993 *iElement = j;
2994 return;
2995 }
2996}

Referenced by verify_base_policy(), verify_basic_constraints_policy(), and verify_ssl_policy().

◆ find_matching_domain_component()

static BOOL find_matching_domain_component ( const CERT_NAME_INFO name,
LPCWSTR  component 
)
static

Definition at line 3216 of file chain.c.

3218{
3219 BOOL matches = FALSE;
3220 DWORD i, j;
3221
3222 for (i = 0; !matches && i < name->cRDN; i++)
3223 for (j = 0; j < name->rgRDN[i].cRDNAttr; j++)
3225 name->rgRDN[i].rgRDNAttr[j].pszObjId))
3226 {
3227 const CERT_RDN_ATTR *attr;
3228
3229 attr = &name->rgRDN[i].rgRDNAttr[j];
3230 /* Compare with memicmpW rather than strcmpiW in order to avoid
3231 * a match with a string with an embedded NULL. The component
3232 * must match one domain component attribute's entire string
3233 * value with a case-insensitive match.
3234 */
3235 matches = !memicmpW(component, (LPCWSTR)attr->Value.pbData,
3236 attr->Value.cbData / sizeof(WCHAR));
3237 }
3238 return matches;
3239}
#define matches(FN)
Definition: match.h:70
#define memicmpW(s1, s2, n)
Definition: unicode.h:27
Definition: cookie.c:202
#define szOID_DOMAIN_COMPONENT
Definition: wincrypt.h:3205

Referenced by match_dns_to_subject_dn().

◆ free_chain_engine()

static void free_chain_engine ( CertificateChainEngine engine)
static

Definition at line 201 of file chain.c.

202{
203 if(!engine || InterlockedDecrement(&engine->ref))
204 return;
205
206 CertCloseStore(engine->hWorld, 0);
207 CertCloseStore(engine->hRoot, 0);
208 CryptMemFree(engine);
209}

Referenced by CertFreeCertificateChainEngine(), and default_chain_engine_free().

◆ get_chain_engine()

static CertificateChainEngine * get_chain_engine ( HCERTCHAINENGINE  handle,
BOOL  allow_default 
)
static

Definition at line 166 of file chain.c.

167{
168 const CERT_CHAIN_ENGINE_CONFIG config = { sizeof(config) };
169
171 if(!allow_default)
172 return NULL;
173
174 if(!default_cu_engine) {
179 }
180
181 return default_cu_engine;
182 }
183
185 if(!allow_default)
186 return NULL;
187
188 if(!default_lm_engine) {
193 }
194
195 return default_lm_engine;
196 }
197
199}
struct config_s config
void WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine)
Definition: chain.c:249
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define HCCE_CURRENT_USER
Definition: wincrypt.h:3613
#define HCCE_LOCAL_MACHINE
Definition: wincrypt.h:3614
#define CERT_SYSTEM_STORE_LOCAL_MACHINE
Definition: wincrypt.h:2326

Referenced by CertFreeCertificateChainEngine(), and CertGetCertificateChain().

◆ get_subject_alt_name_ext()

static PCERT_EXTENSION get_subject_alt_name_ext ( const CERT_INFO cert)
inlinestatic

Definition at line 955 of file chain.c.

956{
958
960 cert->cExtension, cert->rgExtension);
961 if (!ext)
963 cert->cExtension, cert->rgExtension);
964 return ext;
965}

Referenced by CRYPT_CheckNameConstraints(), and verify_ssl_policy().

◆ ip_address_matches()

static BOOL ip_address_matches ( const CRYPT_DATA_BLOB constraint,
const CRYPT_DATA_BLOB name,
DWORD trustErrorStatus 
)
static

Definition at line 820 of file chain.c.

822{
823 BOOL match = FALSE;
824
825 TRACE("(%d, %p), (%d, %p)\n", constraint->cbData, constraint->pbData,
826 name->cbData, name->pbData);
827
828 /* RFC5280, section 4.2.1.10, iPAddress syntax: either 8 or 32 bytes, for
829 * IPv4 or IPv6 addresses, respectively.
830 */
831 if (constraint->cbData != sizeof(DWORD) * 2 && constraint->cbData != 32)
832 *trustErrorStatus |= CERT_TRUST_INVALID_NAME_CONSTRAINTS;
833 else if (name->cbData == sizeof(DWORD) &&
834 constraint->cbData == sizeof(DWORD) * 2)
835 {
836 DWORD subnet, mask, addr;
837
838 memcpy(&subnet, constraint->pbData, sizeof(subnet));
839 memcpy(&mask, constraint->pbData + sizeof(subnet), sizeof(mask));
840 memcpy(&addr, name->pbData, sizeof(addr));
841 /* These are really in big-endian order, but for equality matching we
842 * don't need to swap to host order
843 */
844 match = (subnet & mask) == (addr & mask);
845 }
846 else if (name->cbData == 16 && constraint->cbData == 32)
847 {
848 const BYTE *subnet, *mask, *addr;
849 DWORD i;
850
851 subnet = constraint->pbData;
852 mask = constraint->pbData + 16;
853 addr = name->pbData;
854 match = TRUE;
855 for (i = 0; match && i < 16; i++)
856 if ((subnet[i] & mask[i]) != (addr[i] & mask[i]))
857 match = FALSE;
858 }
859 /* else: name is wrong size, no match */
860
861 return match;
862}
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum const GLvoid * addr
Definition: glext.h:9621

Referenced by alt_name_matches().

◆ match_common_name()

static BOOL match_common_name ( LPCWSTR  server_name,
const CERT_RDN_ATTR nameAttr 
)
static

Definition at line 3298 of file chain.c.

3299{
3300 LPCWSTR allowed = (LPCWSTR)nameAttr->Value.pbData;
3301 LPCWSTR allowed_component = allowed;
3302 DWORD allowed_len = nameAttr->Value.cbData / sizeof(WCHAR);
3303 LPCWSTR server_component = server_name;
3304 DWORD server_len = strlenW(server_name);
3305 BOOL matches = TRUE, allow_wildcards = TRUE;
3306
3307 TRACE_(chain)("CN = %s\n", debugstr_wn(allowed_component, allowed_len));
3308
3309 /* Remove trailing NULLs from the allowed name; while they shouldn't appear
3310 * in a certificate in the first place, they sometimes do, and they should
3311 * be ignored.
3312 */
3313 while (allowed_len && allowed_component[allowed_len - 1] == 0)
3314 allowed_len--;
3315
3316 /* From RFC 2818 (HTTP over TLS), section 3.1:
3317 * "Names may contain the wildcard character * which is considered to match
3318 * any single domain name component or component fragment. E.g.,
3319 * *.a.com matches foo.a.com but not bar.foo.a.com. f*.com matches foo.com
3320 * but not bar.com."
3321 *
3322 * And from RFC 2595 (Using TLS with IMAP, POP3 and ACAP), section 2.4:
3323 * "A "*" wildcard character MAY be used as the left-most name component in
3324 * the certificate. For example, *.example.com would match a.example.com,
3325 * foo.example.com, etc. but would not match example.com."
3326 *
3327 * There are other protocols which use TLS, and none of them is
3328 * authoritative. This accepts certificates in common usage, e.g.
3329 * *.domain.com matches www.domain.com but not domain.com, and
3330 * www*.domain.com matches www1.domain.com but not mail.domain.com.
3331 */
3332 do {
3333 LPCWSTR allowed_dot, server_dot;
3334
3335 allowed_dot = memchrW(allowed_component, '.',
3336 allowed_len - (allowed_component - allowed));
3337 server_dot = memchrW(server_component, '.',
3338 server_len - (server_component - server_name));
3339 /* The number of components must match */
3340 if ((!allowed_dot && server_dot) || (allowed_dot && !server_dot))
3341 {
3342 if (!allowed_dot)
3343 WARN_(chain)("%s: too many components for CN=%s\n",
3344 debugstr_w(server_name), debugstr_wn(allowed, allowed_len));
3345 else
3346 WARN_(chain)("%s: not enough components for CN=%s\n",
3347 debugstr_w(server_name), debugstr_wn(allowed, allowed_len));
3348 matches = FALSE;
3349 }
3350 else
3351 {
3352 LPCWSTR allowed_end, server_end;
3353 BOOL has_wildcard;
3354
3355 allowed_end = allowed_dot ? allowed_dot : allowed + allowed_len;
3356 server_end = server_dot ? server_dot : server_name + server_len;
3357 matches = match_domain_component(allowed_component,
3358 allowed_end - allowed_component, server_component,
3359 server_end - server_component, allow_wildcards, &has_wildcard);
3360 /* Once a non-wildcard component is seen, no wildcard components
3361 * may follow
3362 */
3363 if (!has_wildcard)
3364 allow_wildcards = FALSE;
3365 if (matches)
3366 {
3367 allowed_component = allowed_dot ? allowed_dot + 1 : allowed_end;
3368 server_component = server_dot ? server_dot + 1 : server_end;
3369 }
3370 }
3371 } while (matches && allowed_component &&
3372 allowed_component - allowed < allowed_len &&
3373 server_component && server_component - server_name < server_len);
3374 TRACE_(chain)("returning %d\n", matches);
3375 return matches;
3376}
static BOOL match_domain_component(LPCWSTR allowed_component, DWORD allowed_len, LPCWSTR server_component, DWORD server_len, BOOL allow_wildcards, BOOL *see_wildcard)
Definition: chain.c:3241
WINE_UNICODE_INLINE WCHAR * memchrW(const WCHAR *ptr, WCHAR ch, size_t n)
Definition: unicode.h:295
#define debugstr_wn
Definition: kernel32.h:33
#define strlenW(s)
Definition: unicode.h:28
CERT_RDN_VALUE_BLOB Value
Definition: wincrypt.h:258
char * server_name
Definition: widl.c:145

Referenced by match_dns_to_subject_dn().

◆ match_dns_to_subject_alt_name()

static BOOL match_dns_to_subject_alt_name ( const CERT_EXTENSION ext,
LPCWSTR  server_name 
)
static

Definition at line 3148 of file chain.c.

3150{
3151 BOOL matches = FALSE;
3153 DWORD size;
3154
3156 /* This could be spoofed by the embedded NULL vulnerability, since the
3157 * returned CERT_ALT_NAME_INFO doesn't have a way to indicate the
3158 * encoded length of a name. Fortunately CryptDecodeObjectEx fails if
3159 * the encoded form of the name contains a NULL.
3160 */
3162 ext->Value.pbData, ext->Value.cbData,
3164 &subjectName, &size))
3165 {
3166 DWORD i;
3167
3168 /* RFC 5280 states that multiple instances of each name type may exist,
3169 * in section 4.2.1.6:
3170 * "Multiple name forms, and multiple instances of each name form,
3171 * MAY be included."
3172 * It doesn't specify the behavior in such cases, but both RFC 2818
3173 * and RFC 2595 explicitly accept a certificate if any name matches.
3174 */
3175 for (i = 0; !matches && i < subjectName->cAltEntry; i++)
3176 {
3177 if (subjectName->rgAltEntry[i].dwAltNameChoice ==
3179 {
3180 TRACE_(chain)("dNSName: %s\n", debugstr_w(
3181 subjectName->rgAltEntry[i].u.pwszDNSName));
3182 if (subjectName->rgAltEntry[i].u.pwszDNSName[0] == '*')
3183 {
3184 LPCWSTR server_name_dot;
3185
3186 /* Matching a wildcard: a wildcard matches a single name
3187 * component, which is terminated by a dot. RFC 1034
3188 * doesn't define whether multiple wildcards are allowed,
3189 * but I will assume that they are not until proven
3190 * otherwise. RFC 1034 also states that 'the "*" label
3191 * always matches at least one whole label and sometimes
3192 * more, but always whole labels.' Native crypt32 does not
3193 * match more than one label with a wildcard, so I do the
3194 * same here. Thus, a wildcard only accepts the first
3195 * label, then requires an exact match of the remaining
3196 * string.
3197 */
3198 server_name_dot = strchrW(server_name, '.');
3199 if (server_name_dot)
3200 {
3201 if (!strcmpiW(server_name_dot,
3202 subjectName->rgAltEntry[i].u.pwszDNSName + 1))
3203 matches = TRUE;
3204 }
3205 }
3206 else if (!strcmpiW(server_name,
3207 subjectName->rgAltEntry[i].u.pwszDNSName))
3208 matches = TRUE;
3209 }
3210 }
3212 }
3213 return matches;
3214}
#define strchrW(s, c)
Definition: unicode.h:34
#define strcmpiW(s1, s2)
Definition: unicode.h:39

Referenced by verify_ssl_policy().

◆ match_dns_to_subject_dn()

static BOOL match_dns_to_subject_dn ( PCCERT_CONTEXT  cert,
LPCWSTR  server_name 
)
static

Definition at line 3378 of file chain.c.

3379{
3380 BOOL matches = FALSE;
3382 DWORD size;
3383
3386 cert->pCertInfo->Subject.pbData, cert->pCertInfo->Subject.cbData,
3388 &name, &size))
3389 {
3390 /* If the subject distinguished name contains any name components,
3391 * make sure all of them are present.
3392 */
3394 {
3396
3397 do {
3398 LPCWSTR dot = strchrW(ptr, '.'), end;
3399 /* 254 is the maximum DNS label length, see RFC 1035 */
3400 WCHAR component[255];
3401 DWORD len;
3402
3403 end = dot ? dot : ptr + strlenW(ptr);
3404 len = end - ptr;
3405 if (len >= ARRAY_SIZE(component))
3406 {
3407 WARN_(chain)("domain component %s too long\n",
3408 debugstr_wn(ptr, len));
3409 matches = FALSE;
3410 }
3411 else
3412 {
3413 memcpy(component, ptr, len * sizeof(WCHAR));
3414 component[len] = 0;
3416 }
3417 ptr = dot ? dot + 1 : end;
3418 } while (matches && ptr && *ptr);
3419 }
3420 else
3421 {
3422 DWORD i, j;
3423
3424 /* If the certificate isn't using a DN attribute in the name, make
3425 * make sure at least one common name matches. From RFC 2818,
3426 * section 3.1:
3427 * "If more than one identity of a given type is present in the
3428 * certificate (e.g., more than one dNSName name, a match in any
3429 * one of the set is considered acceptable.)"
3430 */
3431 for (i = 0; !matches && i < name->cRDN; i++)
3432 for (j = 0; !matches && j < name->rgRDN[i].cRDNAttr; j++)
3433 {
3434 PCERT_RDN_ATTR attr = &name->rgRDN[i].rgRDNAttr[j];
3435
3436 if (attr->pszObjId && !strcmp(szOID_COMMON_NAME,
3437 attr->pszObjId))
3439 }
3440 }
3441 LocalFree(name);
3442 }
3443 return matches;
3444}
PCERT_RDN_ATTR WINAPI CertFindRDNAttr(LPCSTR pszObjId, PCERT_NAME_INFO pName)
Definition: cert.c:2051
static BOOL find_matching_domain_component(const CERT_NAME_INFO *name, LPCWSTR component)
Definition: chain.c:3216
static BOOL match_common_name(LPCWSTR server_name, const CERT_RDN_ATTR *nameAttr)
Definition: chain.c:3298
GLuint GLuint end
Definition: gl.h:1545
#define szOID_COMMON_NAME
Definition: wincrypt.h:3134

Referenced by verify_ssl_policy().

◆ match_domain_component()

static BOOL match_domain_component ( LPCWSTR  allowed_component,
DWORD  allowed_len,
LPCWSTR  server_component,
DWORD  server_len,
BOOL  allow_wildcards,
BOOL see_wildcard 
)
static

Definition at line 3241 of file chain.c.

3244{
3245 LPCWSTR allowed_ptr, server_ptr;
3246 BOOL matches = TRUE;
3247
3248 *see_wildcard = FALSE;
3249
3250 if (server_len < allowed_len)
3251 {
3252 WARN_(chain)("domain component %s too short for %s\n",
3253 debugstr_wn(server_component, server_len),
3254 debugstr_wn(allowed_component, allowed_len));
3255 /* A domain component can't contain a wildcard character, so a domain
3256 * component shorter than the allowed string can't produce a match.
3257 */
3258 return FALSE;
3259 }
3260 for (allowed_ptr = allowed_component, server_ptr = server_component;
3261 matches && allowed_ptr - allowed_component < allowed_len;
3262 allowed_ptr++, server_ptr++)
3263 {
3264 if (*allowed_ptr == '*')
3265 {
3266 if (allowed_ptr - allowed_component < allowed_len - 1)
3267 {
3268 WARN_(chain)("non-wildcard characters after wildcard not supported\n");
3269 matches = FALSE;
3270 }
3271 else if (!allow_wildcards)
3272 {
3273 WARN_(chain)("wildcard after non-wildcard component\n");
3274 matches = FALSE;
3275 }
3276 else
3277 {
3278 /* the preceding characters must have matched, so the rest of
3279 * the component also matches.
3280 */
3281 *see_wildcard = TRUE;
3282 break;
3283 }
3284 }
3285 if (matches)
3286 matches = tolowerW(*allowed_ptr) == tolowerW(*server_ptr);
3287 }
3288 if (matches && server_ptr - server_component < server_len)
3289 {
3290 /* If there are unmatched characters in the server domain component,
3291 * the server domain only matches if the allowed string ended in a '*'.
3292 */
3293 matches = *allowed_ptr == '*';
3294 }
3295 return matches;
3296}
#define tolowerW(n)
Definition: unicode.h:44

Referenced by match_common_name().

◆ name_value_to_str()

static LPWSTR name_value_to_str ( const CERT_NAME_BLOB name)
static

Definition at line 1410 of file chain.c.

1411{
1414 LPWSTR str = NULL;
1415
1416 if (len)
1417 {
1418 str = CryptMemAlloc(len * sizeof(WCHAR));
1419 if (str)
1422 }
1423 return str;
1424}
DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indent, const CERT_NAME_BLOB *pName, DWORD dwStrType, LPWSTR psz, DWORD csz) DECLSPEC_HIDDEN
Definition: str.c:576
#define CERT_SIMPLE_NAME_STR
Definition: wincrypt.h:3484

Referenced by dump_alt_name_entry().

◆ rfc822_attr_matches_excluded_name()

static BOOL rfc822_attr_matches_excluded_name ( const CERT_RDN_ATTR attr,
const CERT_NAME_CONSTRAINTS_INFO nameConstraints,
DWORD trustErrorStatus 
)
static

Definition at line 1017 of file chain.c.

1019{
1020 DWORD i;
1021 BOOL match = FALSE;
1022
1023 for (i = 0; !match && i < nameConstraints->cExcludedSubtree; i++)
1024 {
1025 const CERT_ALT_NAME_ENTRY *constraint =
1026 &nameConstraints->rgExcludedSubtree[i].Base;
1027
1028 if (constraint->dwAltNameChoice == CERT_ALT_NAME_RFC822_NAME)
1030 (LPCWSTR)attr->Value.pbData, trustErrorStatus);
1031 }
1032 return match;
1033}
LPWSTR pwszRfc822Name
Definition: wincrypt.h:336

Referenced by compare_subject_with_email_constraints().

◆ rfc822_attr_matches_permitted_name()

static BOOL rfc822_attr_matches_permitted_name ( const CERT_RDN_ATTR attr,
const CERT_NAME_CONSTRAINTS_INFO nameConstraints,
DWORD trustErrorStatus,
BOOL present 
)
static

Definition at line 1035 of file chain.c.

1038{
1039 DWORD i;
1040 BOOL match = FALSE;
1041
1042 for (i = 0; !match && i < nameConstraints->cPermittedSubtree; i++)
1043 {
1044 const CERT_ALT_NAME_ENTRY *constraint =
1045 &nameConstraints->rgPermittedSubtree[i].Base;
1046
1047 if (constraint->dwAltNameChoice == CERT_ALT_NAME_RFC822_NAME)
1048 {
1049 *present = TRUE;
1051 (LPCWSTR)attr->Value.pbData, trustErrorStatus);
1052 }
1053 }
1054 return match;
1055}

Referenced by compare_subject_with_email_constraints().

◆ rfc822_name_matches()

static BOOL rfc822_name_matches ( LPCWSTR  constraint,
LPCWSTR  name,
DWORD trustErrorStatus 
)
static

Definition at line 751 of file chain.c.

753{
754 BOOL match = FALSE;
755 LPCWSTR at;
756
757 TRACE("%s, %s\n", debugstr_w(constraint), debugstr_w(name));
758
759 if (!constraint)
760 *trustErrorStatus |= CERT_TRUST_INVALID_NAME_CONSTRAINTS;
761 else if (!name)
762 ; /* no match */
763 else if (strchrW(constraint, '@'))
764 match = !lstrcmpiW(constraint, name);
765 else
766 {
767 if ((at = strchrW(name, '@')))
768 match = domain_name_matches(constraint, at + 1);
769 else
770 match = !lstrcmpiW(constraint, name);
771 }
772 return match;
773}
static BOOL domain_name_matches(LPCWSTR constraint, LPCWSTR name)
Definition: chain.c:647

Referenced by alt_name_matches(), rfc822_attr_matches_excluded_name(), and rfc822_attr_matches_permitted_name().

◆ url_matches()

static BOOL url_matches ( LPCWSTR  constraint,
LPCWSTR  name,
DWORD trustErrorStatus 
)
static

Definition at line 682 of file chain.c.

684{
685 BOOL match = FALSE;
686
687 TRACE("%s, %s\n", debugstr_w(constraint), debugstr_w(name));
688
689 if (!constraint)
690 *trustErrorStatus |= CERT_TRUST_INVALID_NAME_CONSTRAINTS;
691 else if (!name)
692 ; /* no match */
693 else
694 {
695 LPCWSTR colon, authority_end, at, hostname = NULL;
696 /* The maximum length for a hostname is 254 in the DNS, see RFC 1034 */
697 WCHAR hostname_buf[255];
698
699 /* RFC 5280: only the hostname portion of the URL is compared. From
700 * section 4.2.1.10:
701 * "For URIs, the constraint applies to the host part of the name.
702 * The constraint MUST be specified as a fully qualified domain name
703 * and MAY specify a host or a domain."
704 * The format for URIs is in RFC 2396.
705 *
706 * First, remove any scheme that's present. */
707 colon = strchrW(name, ':');
708 if (colon && *(colon + 1) == '/' && *(colon + 2) == '/')
709 name = colon + 3;
710 /* Next, find the end of the authority component. (The authority is
711 * generally just the hostname, but it may contain a username or a port.
712 * Those are removed next.)
713 */
714 authority_end = strchrW(name, '/');
715 if (!authority_end)
716 authority_end = strchrW(name, '?');
717 if (!authority_end)
718 authority_end = name + strlenW(name);
719 /* Remove any port number from the authority. The userinfo portion
720 * of an authority may contain a colon, so stop if a userinfo portion
721 * is found (indicated by '@').
722 */
723 for (colon = authority_end; colon >= name && *colon != ':' &&
724 *colon != '@'; colon--)
725 ;
726 if (*colon == ':')
727 authority_end = colon;
728 /* Remove any username from the authority */
729 if ((at = strchrW(name, '@')))
730 name = at;
731 /* Ignore any path or query portion of the URL. */
732 if (*authority_end)
733 {
734 if (authority_end - name < ARRAY_SIZE(hostname_buf))
735 {
736 memcpy(hostname_buf, name,
737 (authority_end - name) * sizeof(WCHAR));
738 hostname_buf[authority_end - name] = 0;
739 hostname = hostname_buf;
740 }
741 /* else: Hostname is too long, not a match */
742 }
743 else
744 hostname = name;
745 if (hostname)
746 match = domain_name_matches(constraint, hostname);
747 }
748 return match;
749}
char * hostname
Definition: ftp.c:88

Referenced by alt_name_matches().

◆ verify_authenticode_policy()

static BOOL WINAPI verify_authenticode_policy ( LPCSTR  szPolicyOID,
PCCERT_CHAIN_CONTEXT  pChainContext,
PCERT_CHAIN_POLICY_PARA  pPolicyPara,
PCERT_CHAIN_POLICY_STATUS  pPolicyStatus 
)
static

Definition at line 3089 of file chain.c.

3092{
3093 BOOL ret = verify_base_policy(szPolicyOID, pChainContext, pPolicyPara,
3094 pPolicyStatus);
3096
3097 if (pPolicyPara)
3098 extraPara = pPolicyPara->pvExtraPolicyPara;
3099 if (TRACE_ON(chain))
3101 if (ret && pPolicyStatus->dwError == CERT_E_UNTRUSTEDROOT)
3102 {
3103 CERT_PUBLIC_KEY_INFO msPubKey = { { 0 } };
3104 BOOL isMSTestRoot = FALSE;
3105 PCCERT_CONTEXT failingCert =
3106 pChainContext->rgpChain[pPolicyStatus->lChainIndex]->
3107 rgpElement[pPolicyStatus->lElementIndex]->pCertContext;
3108 DWORD i;
3109 CRYPT_DATA_BLOB keyBlobs[] = {
3110 { sizeof(msTestPubKey1), msTestPubKey1 },
3111 { sizeof(msTestPubKey2), msTestPubKey2 },
3112 };
3113
3114 /* Check whether the root is an MS test root */
3115 for (i = 0; !isMSTestRoot && i < ARRAY_SIZE(keyBlobs); i++)
3116 {
3117 msPubKey.PublicKey.cbData = keyBlobs[i].cbData;
3118 msPubKey.PublicKey.pbData = keyBlobs[i].pbData;
3121 &failingCert->pCertInfo->SubjectPublicKeyInfo, &msPubKey))
3122 isMSTestRoot = TRUE;
3123 }
3124 if (isMSTestRoot)
3125 pPolicyStatus->dwError = CERT_E_UNTRUSTEDTESTROOT;
3126 }
3127 return ret;
3128}
BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pPublicKey1, PCERT_PUBLIC_KEY_INFO pPublicKey2)
Definition: cert.c:1244
static BYTE msTestPubKey2[]
Definition: chain.c:3070
static void dump_authenticode_extra_chain_policy_para(AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA *extraPara)
Definition: chain.c:3077
static BYTE msTestPubKey1[]
Definition: chain.c:3064
CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo
Definition: wincrypt.h:248
CRYPT_BIT_BLOB PublicKey
Definition: wincrypt.h:226
BYTE * pbData
Definition: wincrypt.h:197
#define PKCS_7_ASN_ENCODING
Definition: wincrypt.h:2299
#define CERT_E_UNTRUSTEDROOT
Definition: winerror.h:3125
#define CERT_E_UNTRUSTEDTESTROOT
Definition: winerror.h:3129

Referenced by CertVerifyCertificateChainPolicy().

◆ verify_base_policy()

static BOOL WINAPI verify_base_policy ( LPCSTR  szPolicyOID,
PCCERT_CHAIN_CONTEXT  pChainContext,
PCERT_CHAIN_POLICY_PARA  pPolicyPara,
PCERT_CHAIN_POLICY_STATUS  pPolicyStatus 
)
static

Definition at line 2998 of file chain.c.

3001{
3002 DWORD checks = 0;
3003
3004 if (pPolicyPara)
3005 checks = pPolicyPara->dwFlags;
3006 pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = -1;
3007 pPolicyStatus->dwError = NO_ERROR;
3008 if (pChainContext->TrustStatus.dwErrorStatus &
3010 {
3011 pPolicyStatus->dwError = TRUST_E_CERT_SIGNATURE;
3012 find_element_with_error(pChainContext,
3014 &pPolicyStatus->lElementIndex);
3015 }
3016 else if (pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_CYCLIC)
3017 {
3018 pPolicyStatus->dwError = CERT_E_CHAINING;
3020 &pPolicyStatus->lChainIndex, &pPolicyStatus->lElementIndex);
3021 /* For a cyclic chain, which element is a cycle isn't meaningful */
3022 pPolicyStatus->lElementIndex = -1;
3023 }
3024 if (!pPolicyStatus->dwError &&
3027 {
3028 pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT;
3029 find_element_with_error(pChainContext,
3031 &pPolicyStatus->lElementIndex);
3032 }
3033 if (!pPolicyStatus->dwError &&
3035 {
3036 pPolicyStatus->dwError = CERT_E_EXPIRED;
3037 find_element_with_error(pChainContext,
3039 &pPolicyStatus->lElementIndex);
3040 }
3041 if (!pPolicyStatus->dwError &&
3042 pChainContext->TrustStatus.dwErrorStatus &
3045 {
3046 pPolicyStatus->dwError = CERT_E_WRONG_USAGE;
3047 find_element_with_error(pChainContext,
3049 &pPolicyStatus->lElementIndex);
3050 }
3051 if (!pPolicyStatus->dwError &&
3052 pChainContext->TrustStatus.dwErrorStatus &
3055 {
3056 pPolicyStatus->dwError = CERT_E_CRITICAL;
3057 find_element_with_error(pChainContext,
3059 &pPolicyStatus->lElementIndex);
3060 }
3061 return TRUE;
3062}
#define NO_ERROR
Definition: dderror.h:5
static void find_element_with_error(PCCERT_CHAIN_CONTEXT chain, DWORD error, LONG *iChain, LONG *iElement)
Definition: chain.c:2982
#define CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG
Definition: wincrypt.h:980
#define CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG
Definition: wincrypt.h:981
#define CERT_CHAIN_POLICY_IGNORE_NOT_SUPPORTED_CRITICAL_EXT_FLAG
Definition: wincrypt.h:997
#define CERT_E_CHAINING
Definition: winerror.h:3126
#define CERT_E_WRONG_USAGE
Definition: winerror.h:3132
#define TRUST_E_CERT_SIGNATURE
Definition: winerror.h:3107
#define CERT_E_CRITICAL
Definition: winerror.h:3121
#define CERT_E_EXPIRED
Definition: winerror.h:3117

Referenced by CertVerifyCertificateChainPolicy(), verify_authenticode_policy(), and verify_ms_root_policy().

◆ verify_basic_constraints_policy()

static BOOL WINAPI verify_basic_constraints_policy ( LPCSTR  szPolicyOID,
PCCERT_CHAIN_CONTEXT  pChainContext,
PCERT_CHAIN_POLICY_PARA  pPolicyPara,
PCERT_CHAIN_POLICY_STATUS  pPolicyStatus 
)
static

Definition at line 3130 of file chain.c.

3133{
3134 pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = -1;
3135 if (pChainContext->TrustStatus.dwErrorStatus &
3137 {
3138 pPolicyStatus->dwError = TRUST_E_BASIC_CONSTRAINTS;
3139 find_element_with_error(pChainContext,
3141 &pPolicyStatus->lElementIndex);
3142 }
3143 else
3144 pPolicyStatus->dwError = NO_ERROR;
3145 return TRUE;
3146}
#define TRUST_E_BASIC_CONSTRAINTS
Definition: winerror.h:3110

Referenced by CertVerifyCertificateChainPolicy().

◆ verify_ms_root_policy()

static BOOL WINAPI verify_ms_root_policy ( LPCSTR  szPolicyOID,
PCCERT_CHAIN_CONTEXT  pChainContext,
PCERT_CHAIN_POLICY_PARA  pPolicyPara,
PCERT_CHAIN_POLICY_STATUS  pPolicyStatus 
)
static

Definition at line 3665 of file chain.c.

3668{
3669 BOOL ret = verify_base_policy(szPolicyOID, pChainContext, pPolicyPara,
3670 pPolicyStatus);
3671
3672 if (ret && !pPolicyStatus->dwError)
3673 {
3674 CERT_PUBLIC_KEY_INFO msPubKey = { { 0 } };
3675 BOOL isMSRoot = FALSE;
3676 DWORD i;
3677 CRYPT_DATA_BLOB keyBlobs[] = {
3678 { sizeof(msPubKey1), msPubKey1 },
3679 { sizeof(msPubKey2), msPubKey2 },
3680 { sizeof(msPubKey3), msPubKey3 },
3681 };
3682 PCERT_SIMPLE_CHAIN rootChain =
3683 pChainContext->rgpChain[pChainContext->cChain -1 ];
3685 rootChain->rgpElement[rootChain->cElement - 1]->pCertContext;
3686
3687 for (i = 0; !isMSRoot && i < ARRAY_SIZE(keyBlobs); i++)
3688 {
3689 msPubKey.PublicKey.cbData = keyBlobs[i].cbData;
3690 msPubKey.PublicKey.pbData = keyBlobs[i].pbData;
3693 &root->pCertInfo->SubjectPublicKeyInfo, &msPubKey))
3694 isMSRoot = TRUE;
3695 }
3696 if (isMSRoot)
3697 pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = 0;
3698 }
3699 return ret;
3700}
static BYTE msPubKey3[]
Definition: chain.c:3627
static BYTE msPubKey2[]
Definition: chain.c:3608
static BYTE msPubKey1[]
Definition: chain.c:3589
PCERT_CHAIN_ELEMENT * rgpElement
Definition: wincrypt.h:928

Referenced by CertVerifyCertificateChainPolicy().

◆ verify_ssl_policy()

static BOOL WINAPI verify_ssl_policy ( LPCSTR  szPolicyOID,
PCCERT_CHAIN_CONTEXT  pChainContext,
PCERT_CHAIN_POLICY_PARA  pPolicyPara,
PCERT_CHAIN_POLICY_STATUS  pPolicyStatus 
)
static

Definition at line 3458 of file chain.c.

3461{
3462 HTTPSPolicyCallbackData *sslPara = NULL;
3463 DWORD checks = 0;
3464
3465 if (pPolicyPara)
3466 sslPara = pPolicyPara->pvExtraPolicyPara;
3467 if (TRACE_ON(chain))
3469 if (sslPara && sslPara->u.cbSize >= sizeof(HTTPSPolicyCallbackData))
3470 checks = sslPara->fdwChecks;
3471 pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = -1;
3472 if (pChainContext->TrustStatus.dwErrorStatus &
3474 {
3475 pPolicyStatus->dwError = TRUST_E_CERT_SIGNATURE;
3476 find_element_with_error(pChainContext,
3478 &pPolicyStatus->lElementIndex);
3479 }
3480 else if (pChainContext->TrustStatus.dwErrorStatus &
3483 {
3484 pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT;
3485 find_element_with_error(pChainContext,
3487 &pPolicyStatus->lElementIndex);
3488 }
3489 else if (pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_CYCLIC)
3490 {
3491 pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT;
3492 find_element_with_error(pChainContext,
3493 CERT_TRUST_IS_CYCLIC, &pPolicyStatus->lChainIndex,
3494 &pPolicyStatus->lElementIndex);
3495 /* For a cyclic chain, which element is a cycle isn't meaningful */
3496 pPolicyStatus->lElementIndex = -1;
3497 }
3498 else if (pChainContext->TrustStatus.dwErrorStatus &
3501 {
3502 pPolicyStatus->dwError = CERT_E_EXPIRED;
3503 find_element_with_error(pChainContext,
3505 &pPolicyStatus->lElementIndex);
3506 }
3507 else if (pChainContext->TrustStatus.dwErrorStatus &
3510 {
3511 pPolicyStatus->dwError = CERT_E_WRONG_USAGE;
3512 find_element_with_error(pChainContext,
3514 &pPolicyStatus->lElementIndex);
3515 }
3516 else if (pChainContext->TrustStatus.dwErrorStatus &
3518 {
3519 pPolicyStatus->dwError = CERT_E_REVOKED;
3520 find_element_with_error(pChainContext,
3521 CERT_TRUST_IS_REVOKED, &pPolicyStatus->lChainIndex,
3522 &pPolicyStatus->lElementIndex);
3523 }
3524 else if (pChainContext->TrustStatus.dwErrorStatus &
3527 {
3528 pPolicyStatus->dwError = CERT_E_REVOCATION_FAILURE;
3529 find_element_with_error(pChainContext,
3531 &pPolicyStatus->lElementIndex);
3532 }
3533 else if (pChainContext->TrustStatus.dwErrorStatus &
3535 {
3536 pPolicyStatus->dwError = CERT_E_CRITICAL;
3537 find_element_with_error(pChainContext,
3539 &pPolicyStatus->lElementIndex);
3540 }
3541 else
3542 pPolicyStatus->dwError = NO_ERROR;
3543 /* We only need bother checking whether the name in the end certificate
3544 * matches if the chain is otherwise okay.
3545 */
3546 if (!pPolicyStatus->dwError && pPolicyPara &&
3547 pPolicyPara->cbSize >= sizeof(CERT_CHAIN_POLICY_PARA))
3548 {
3549 if (sslPara && sslPara->u.cbSize >= sizeof(HTTPSPolicyCallbackData))
3550 {
3551 if (sslPara->dwAuthType == AUTHTYPE_SERVER &&
3552 sslPara->pwszServerName &&
3554 {
3556 PCERT_EXTENSION altNameExt;
3557 BOOL matches;
3558
3559 cert = pChainContext->rgpChain[0]->rgpElement[0]->pCertContext;
3560 altNameExt = get_subject_alt_name_ext(cert->pCertInfo);
3561 /* If the alternate name extension exists, the name it contains
3562 * is bound to the certificate, so make sure the name matches
3563 * it. Otherwise, look for the server name in the subject
3564 * distinguished name. RFC5280, section 4.2.1.6:
3565 * "Whenever such identities are to be bound into a
3566 * certificate, the subject alternative name (or issuer
3567 * alternative name) extension MUST be used; however, a DNS
3568 * name MAY also be represented in the subject field using the
3569 * domainComponent attribute."
3570 */
3571 if (altNameExt)
3573 sslPara->pwszServerName);
3574 else
3576 sslPara->pwszServerName);
3577 if (!matches)
3578 {
3579 pPolicyStatus->dwError = CERT_E_CN_NO_MATCH;
3580 pPolicyStatus->lChainIndex = 0;
3581 pPolicyStatus->lElementIndex = 0;
3582 }
3583 }
3584 }
3585 }
3586 return TRUE;
3587}
static BOOL match_dns_to_subject_alt_name(const CERT_EXTENSION *ext, LPCWSTR server_name)
Definition: chain.c:3148
static void dump_ssl_extra_chain_policy_para(HTTPSPolicyCallbackData *sslPara)
Definition: chain.c:3446
static BOOL match_dns_to_subject_dn(PCCERT_CONTEXT cert, LPCWSTR server_name)
Definition: chain.c:3378
#define AUTHTYPE_SERVER
Definition: wincrypt.h:1035
#define CERT_E_REVOCATION_FAILURE
Definition: winerror.h:3130
#define CERT_E_REVOKED
Definition: winerror.h:3128
#define CERT_E_CN_NO_MATCH
Definition: winerror.h:3131
#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
Definition: winhttp.h:282
#define SECURITY_FLAG_IGNORE_UNKNOWN_CA
Definition: winhttp.h:281
#define SECURITY_FLAG_IGNORE_CERT_CN_INVALID
Definition: winhttp.h:283
#define SECURITY_FLAG_IGNORE_WRONG_USAGE
Definition: wininet.h:831
#define SECURITY_FLAG_IGNORE_REVOCATION
Definition: wininet.h:829

Referenced by CertVerifyCertificateChainPolicy().

◆ WINE_DECLARE_DEBUG_CHANNEL()

WINE_DECLARE_DEBUG_CHANNEL ( chain  )

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( crypt  )

Variable Documentation

◆ default_cu_engine

CertificateChainEngine* default_cu_engine
static

Definition at line 164 of file chain.c.

Referenced by default_chain_engine_free(), and get_chain_engine().

◆ default_lm_engine

CertificateChainEngine * default_lm_engine
static

Definition at line 164 of file chain.c.

Referenced by default_chain_engine_free(), and get_chain_engine().

◆ msPubKey1

BYTE msPubKey1[]
static
Initial value:
= {
0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xdf,0x08,0xba,0xe3,0x3f,0x6e,
0x64,0x9b,0xf5,0x89,0xaf,0x28,0x96,0x4a,0x07,0x8f,0x1b,0x2e,0x8b,0x3e,0x1d,
0xfc,0xb8,0x80,0x69,0xa3,0xa1,0xce,0xdb,0xdf,0xb0,0x8e,0x6c,0x89,0x76,0x29,
0x4f,0xca,0x60,0x35,0x39,0xad,0x72,0x32,0xe0,0x0b,0xae,0x29,0x3d,0x4c,0x16,
0xd9,0x4b,0x3c,0x9d,0xda,0xc5,0xd3,0xd1,0x09,0xc9,0x2c,0x6f,0xa6,0xc2,0x60,
0x53,0x45,0xdd,0x4b,0xd1,0x55,0xcd,0x03,0x1c,0xd2,0x59,0x56,0x24,0xf3,0xe5,
0x78,0xd8,0x07,0xcc,0xd8,0xb3,0x1f,0x90,0x3f,0xc0,0x1a,0x71,0x50,0x1d,0x2d,
0xa7,0x12,0x08,0x6d,0x7c,0xb0,0x86,0x6c,0xc7,0xba,0x85,0x32,0x07,0xe1,0x61,
0x6f,0xaf,0x03,0xc5,0x6d,0xe5,0xd6,0xa1,0x8f,0x36,0xf6,0xc1,0x0b,0xd1,0x3e,
0x69,0x97,0x48,0x72,0xc9,0x7f,0xa4,0xc8,0xc2,0x4a,0x4c,0x7e,0xa1,0xd1,0x94,
0xa6,0xd7,0xdc,0xeb,0x05,0x46,0x2e,0xb8,0x18,0xb4,0x57,0x1d,0x86,0x49,0xdb,
0x69,0x4a,0x2c,0x21,0xf5,0x5e,0x0f,0x54,0x2d,0x5a,0x43,0xa9,0x7a,0x7e,0x6a,
0x8e,0x50,0x4d,0x25,0x57,0xa1,0xbf,0x1b,0x15,0x05,0x43,0x7b,0x2c,0x05,0x8d,
0xbd,0x3d,0x03,0x8c,0x93,0x22,0x7d,0x63,0xea,0x0a,0x57,0x05,0x06,0x0a,0xdb,
0x61,0x98,0x65,0x2d,0x47,0x49,0xa8,0xe7,0xe6,0x56,0x75,0x5c,0xb8,0x64,0x08,
0x63,0xa9,0x30,0x40,0x66,0xb2,0xf9,0xb6,0xe3,0x34,0xe8,0x67,0x30,0xe1,0x43,
0x0b,0x87,0xff,0xc9,0xbe,0x72,0x10,0x5e,0x23,0xf0,0x9b,0xa7,0x48,0x65,0xbf,
0x09,0x88,0x7b,0xcd,0x72,0xbc,0x2e,0x79,0x9b,0x7b,0x02,0x03,0x01,0x00,0x01 }

Definition at line 3589 of file chain.c.

Referenced by verify_ms_root_policy().

◆ msPubKey2

BYTE msPubKey2[]
static
Initial value:
= {
0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0x02,0xbd,0xc1,0x70,0xe6,
0x3b,0xf2,0x4e,0x1b,0x28,0x9f,0x97,0x78,0x5e,0x30,0xea,0xa2,0xa9,0x8d,0x25,
0x5f,0xf8,0xfe,0x95,0x4c,0xa3,0xb7,0xfe,0x9d,0xa2,0x20,0x3e,0x7c,0x51,0xa2,
0x9b,0xa2,0x8f,0x60,0x32,0x6b,0xd1,0x42,0x64,0x79,0xee,0xac,0x76,0xc9,0x54,
0xda,0xf2,0xeb,0x9c,0x86,0x1c,0x8f,0x9f,0x84,0x66,0xb3,0xc5,0x6b,0x7a,0x62,
0x23,0xd6,0x1d,0x3c,0xde,0x0f,0x01,0x92,0xe8,0x96,0xc4,0xbf,0x2d,0x66,0x9a,
0x9a,0x68,0x26,0x99,0xd0,0x3a,0x2c,0xbf,0x0c,0xb5,0x58,0x26,0xc1,0x46,0xe7,
0x0a,0x3e,0x38,0x96,0x2c,0xa9,0x28,0x39,0xa8,0xec,0x49,0x83,0x42,0xe3,0x84,
0x0f,0xbb,0x9a,0x6c,0x55,0x61,0xac,0x82,0x7c,0xa1,0x60,0x2d,0x77,0x4c,0xe9,
0x99,0xb4,0x64,0x3b,0x9a,0x50,0x1c,0x31,0x08,0x24,0x14,0x9f,0xa9,0xe7,0x91,
0x2b,0x18,0xe6,0x3d,0x98,0x63,0x14,0x60,0x58,0x05,0x65,0x9f,0x1d,0x37,0x52,
0x87,0xf7,0xa7,0xef,0x94,0x02,0xc6,0x1b,0xd3,0xbf,0x55,0x45,0xb3,0x89,0x80,
0xbf,0x3a,0xec,0x54,0x94,0x4e,0xae,0xfd,0xa7,0x7a,0x6d,0x74,0x4e,0xaf,0x18,
0xcc,0x96,0x09,0x28,0x21,0x00,0x57,0x90,0x60,0x69,0x37,0xbb,0x4b,0x12,0x07,
0x3c,0x56,0xff,0x5b,0xfb,0xa4,0x66,0x0a,0x08,0xa6,0xd2,0x81,0x56,0x57,0xef,
0xb6,0x3b,0x5e,0x16,0x81,0x77,0x04,0xda,0xf6,0xbe,0xae,0x80,0x95,0xfe,0xb0,
0xcd,0x7f,0xd6,0xa7,0x1a,0x72,0x5c,0x3c,0xca,0xbc,0xf0,0x08,0xa3,0x22,0x30,
0xb3,0x06,0x85,0xc9,0xb3,0x20,0x77,0x13,0x85,0xdf,0x02,0x03,0x01,0x00,0x01 }

Definition at line 3608 of file chain.c.

Referenced by verify_ms_root_policy().

◆ msPubKey3

BYTE msPubKey3[]
static

Definition at line 3627 of file chain.c.

Referenced by verify_ms_root_policy().

◆ msTestPubKey1

BYTE msTestPubKey1[]
static
Initial value:
= {
0x30,0x47,0x02,0x40,0x81,0x55,0x22,0xb9,0x8a,0xa4,0x6f,0xed,0xd6,0xe7,0xd9,
0x66,0x0f,0x55,0xbc,0xd7,0xcd,0xd5,0xbc,0x4e,0x40,0x02,0x21,0xa2,0xb1,0xf7,
0x87,0x30,0x85,0x5e,0xd2,0xf2,0x44,0xb9,0xdc,0x9b,0x75,0xb6,0xfb,0x46,0x5f,
0x42,0xb6,0x9d,0x23,0x36,0x0b,0xde,0x54,0x0f,0xcd,0xbd,0x1f,0x99,0x2a,0x10,
0x58,0x11,0xcb,0x40,0xcb,0xb5,0xa7,0x41,0x02,0x03,0x01,0x00,0x01 }

Definition at line 3064 of file chain.c.

Referenced by verify_authenticode_policy().

◆ msTestPubKey2

BYTE msTestPubKey2[]
static
Initial value:
= {
0x30,0x47,0x02,0x40,0x9c,0x50,0x05,0x1d,0xe2,0x0e,0x4c,0x53,0xd8,0xd9,0xb5,
0xe5,0xfd,0xe9,0xe3,0xad,0x83,0x4b,0x80,0x08,0xd9,0xdc,0xe8,0xe8,0x35,0xf8,
0x11,0xf1,0xe9,0x9b,0x03,0x7a,0x65,0x64,0x76,0x35,0xce,0x38,0x2c,0xf2,0xb6,
0x71,0x9e,0x06,0xd9,0xbf,0xbb,0x31,0x69,0xa3,0xf6,0x30,0xa0,0x78,0x7b,0x18,
0xdd,0x50,0x4d,0x79,0x1e,0xeb,0x61,0xc1,0x02,0x03,0x01,0x00,0x01 }

Definition at line 3070 of file chain.c.

Referenced by verify_authenticode_policy().

◆ rootW