ReactOS 0.4.17-dev-444-g71ee754
chain.c File Reference
#include <stdarg.h>
#include <wchar.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "wincrypt.h"
#include "wininet.h"
#include "wine/debug.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 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, const WCHAR *component, size_t len)
 
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 CertificateChainEnginedefault_cu_engine
 
static CertificateChainEnginedefault_lm_engine
 
static BYTE msTestPubKey1 []
 
static BYTE msTestPubKey2 []
 
static BYTE msPubKey1 []
 
static BYTE msPubKey2 []
 
static BYTE msPubKey3 []
 
static BYTE msPubKey4 []
 
static BYTE msPubKey5 []
 

Macro Definition Documentation

◆ CERT_CHAIN_PARA_HAS_EXTRA_FIELDS

#define CERT_CHAIN_PARA_HAS_EXTRA_FIELDS

Definition at line 26 of file chain.c.

◆ CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS

#define CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS

Definition at line 27 of file chain.c.

◆ CHAIN_QUALITY_BASIC_CONSTRAINTS

#define CHAIN_QUALITY_BASIC_CONSTRAINTS   2

Definition at line 2513 of file chain.c.

◆ CHAIN_QUALITY_COMPLETE_CHAIN

#define CHAIN_QUALITY_COMPLETE_CHAIN   4

Definition at line 2512 of file chain.c.

◆ CHAIN_QUALITY_HIGHEST

#define CHAIN_QUALITY_HIGHEST
Value:
#define CHAIN_QUALITY_SIGNATURE_VALID
Definition: chain.c:2510
#define CHAIN_QUALITY_TRUSTED_ROOT
Definition: chain.c:2514
#define CHAIN_QUALITY_TIME_VALID
Definition: chain.c:2511
#define CHAIN_QUALITY_BASIC_CONSTRAINTS
Definition: chain.c:2513
#define CHAIN_QUALITY_COMPLETE_CHAIN
Definition: chain.c:2512

Definition at line 2516 of file chain.c.

◆ CHAIN_QUALITY_SIGNATURE_VALID

#define CHAIN_QUALITY_SIGNATURE_VALID   0x16

Definition at line 2510 of file chain.c.

◆ CHAIN_QUALITY_TIME_VALID

#define CHAIN_QUALITY_TIME_VALID   8

Definition at line 2511 of file chain.c.

◆ CHAIN_QUALITY_TRUSTED_ROOT

#define CHAIN_QUALITY_TRUSTED_ROOT   1

Definition at line 2514 of file chain.c.

◆ DEFAULT_CYCLE_MODULUS

#define DEFAULT_CYCLE_MODULUS   7

Definition at line 36 of file chain.c.

◆ IS_TRUST_ERROR_SET

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

Definition at line 2521 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 3792 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 882 of file chain.c.

884{
885 BOOL match = FALSE;
886
887 if (name->dwAltNameChoice == constraint->dwAltNameChoice)
888 {
889 if (present)
890 *present = TRUE;
891 switch (constraint->dwAltNameChoice)
892 {
894 match = rfc822_name_matches(constraint->pwszURL,
895 name->pwszURL, trustErrorStatus);
896 break;
898 match = dns_name_matches(constraint->pwszURL,
899 name->pwszURL, trustErrorStatus);
900 break;
902 match = url_matches(constraint->pwszURL,
903 name->pwszURL, trustErrorStatus);
904 break;
906 match = ip_address_matches(&constraint->IPAddress,
907 &name->IPAddress, trustErrorStatus);
908 break;
911 &name->DirectoryName);
912 break;
913 default:
914 ERR("name choice %ld unsupported in this context\n",
915 constraint->dwAltNameChoice);
916 *trustErrorStatus |=
918 }
919 }
920 else if (present)
921 *present = FALSE;
922 return match;
923}
#define ERR(fmt,...)
Definition: precomp.h:57
#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:678
static BOOL ip_address_matches(const CRYPT_DATA_BLOB *constraint, const CRYPT_DATA_BLOB *name, DWORD *trustErrorStatus)
Definition: chain.c:816
static BOOL dns_name_matches(LPCWSTR constraint, LPCWSTR name, DWORD *trustErrorStatus)
Definition: chain.c:771
static BOOL rfc822_name_matches(LPCWSTR constraint, LPCWSTR name, DWORD *trustErrorStatus)
Definition: chain.c:747
static BOOL directory_name_matches(const CERT_NAME_BLOB *constraint, const CERT_NAME_BLOB *name)
Definition: chain.c:860
unsigned int BOOL
Definition: ntddk_ex.h:94
LPWSTR pwszURL
Definition: wincrypt.h:348
DWORD dwAltNameChoice
Definition: wincrypt.h:342
CRYPT_DATA_BLOB IPAddress
Definition: wincrypt.h:349
CERT_NAME_BLOB DirectoryName
Definition: wincrypt.h:347
Definition: match.c:28
Definition: name.c:39
#define CERT_ALT_NAME_URL
Definition: wincrypt.h:360
#define CERT_ALT_NAME_DIRECTORY_NAME
Definition: wincrypt.h:358
#define CERT_ALT_NAME_IP_ADDRESS
Definition: wincrypt.h:361
#define CERT_ALT_NAME_RFC822_NAME
Definition: wincrypt.h:355
#define CERT_ALT_NAME_DNS_NAME
Definition: wincrypt.h:356
#define CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT
Definition: wincrypt.h:994

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 925 of file chain.c.

927{
928 DWORD i;
929 BOOL match = FALSE;
930
931 for (i = 0; !match && i < nameConstraints->cExcludedSubtree; i++)
933 &nameConstraints->rgExcludedSubtree[i].Base, trustErrorStatus, NULL);
934 return match;
935}
#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:882
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:584
PCERT_GENERAL_SUBTREE rgExcludedSubtree
Definition: wincrypt.h:594

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 937 of file chain.c.

940{
941 DWORD i;
942 BOOL match = FALSE;
943
944 for (i = 0; !match && i < nameConstraints->cPermittedSubtree; i++)
946 &nameConstraints->rgPermittedSubtree[i].Base, trustErrorStatus,
947 present);
948 return match;
949}
PCERT_GENERAL_SUBTREE rgPermittedSubtree
Definition: wincrypt.h:592

Referenced by compare_alt_name_with_constraints().

◆ CertCreateCertificateChainEngine()

BOOL WINAPI CertCreateCertificateChainEngine ( PCERT_CHAIN_ENGINE_CONFIG  pConfig,
HCERTCHAINENGINE phChainEngine 
)

Definition at line 221 of file chain.c.

223{
224 BOOL ret;
225
226 TRACE("(%p, %p)\n", pConfig, phChainEngine);
227
229 && pConfig->cbSize != sizeof(CERT_CHAIN_ENGINE_CONFIG))
230 {
232 return FALSE;
233 }
235 if (!ret)
236 {
237 *phChainEngine = NULL;
238 return FALSE;
239 }
240
242 return *phChainEngine != NULL;
243}
#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
return ret
Definition: mutex.c:146
#define TRACE(s)
Definition: solgame.cpp:4
HCERTSTORE hRestrictedRoot
Definition: wincrypt.h:3786
#define CERT_SYSTEM_STORE_CURRENT_USER
Definition: wincrypt.h:2528

Referenced by check_ssl_policy(), CRYPTDLG_MakeEngine(), save_pfx(), and testCreateCertChainEngine().

◆ CertDuplicateCertificateChain()

PCCERT_CHAIN_CONTEXT WINAPI CertDuplicateCertificateChain ( PCCERT_CHAIN_CONTEXT  pChainContext)

Definition at line 2944 of file chain.c.

2946{
2947 CertificateChain *chain = (CertificateChain*)pChainContext;
2948
2949 TRACE("(%p)\n", pChainContext);
2950
2951 if (chain)
2953 return pChainContext;
2954}
#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 2969 of file chain.c.

2972{
2973 FIXME("(%p, %08lx, %08lx, %ld, %p, %p): stub\n", store, certEncodingType,
2974 findFlags, findType, findPara, prevChainContext);
2975 return NULL;
2976}
#define FIXME(fmt,...)
Definition: precomp.h:53

◆ CertFreeCertificateChain()

VOID WINAPI CertFreeCertificateChain ( PCCERT_CHAIN_CONTEXT  pChainContext)

Definition at line 2956 of file chain.c.

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

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

◆ CertFreeCertificateChainEngine()

void WINAPI CertFreeCertificateChainEngine ( HCERTCHAINENGINE  hChainEngine)

Definition at line 245 of file chain.c.

246{
247 TRACE("(%p)\n", hChainEngine);
249}
static CertificateChainEngine * get_chain_engine(HCERTCHAINENGINE handle, BOOL allow_default)
Definition: chain.c:162
static void free_chain_engine(CertificateChainEngine *engine)
Definition: chain.c:197

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

◆ 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 2875 of file chain.c.

2879{
2880 CertificateChainEngine *engine;
2881 BOOL ret;
2883
2884 TRACE("(%p, %p, %s, %p, %p, %08lx, %p, %p)\n", hChainEngine, pCertContext,
2885 debugstr_filetime(pTime), hAdditionalStore, pChainPara, dwFlags,
2886 pvReserved, ppChainContext);
2887
2888 engine = get_chain_engine(hChainEngine, TRUE);
2889 if (!engine)
2890 return FALSE;
2891
2892 if (ppChainContext)
2893 *ppChainContext = NULL;
2894 if (!pChainPara)
2895 {
2897 return FALSE;
2898 }
2899 if (!pCertContext->pCertInfo->SignatureAlgorithm.pszObjId)
2900 {
2902 return FALSE;
2903 }
2904
2905 if (TRACE_ON(chain))
2906 dump_chain_para(pChainPara);
2907 /* FIXME: what about HCCE_LOCAL_MACHINE? */
2908 ret = CRYPT_BuildCandidateChainFromCert(engine, pCertContext, pTime,
2909 hAdditionalStore, dwFlags, &chain);
2910 if (ret)
2911 {
2912 CertificateChain *alternate = NULL;
2913 PCERT_CHAIN_CONTEXT pChain;
2914
2915 do {
2916 alternate = CRYPT_BuildAlternateContextFromChain(engine,
2917 pTime, hAdditionalStore, dwFlags, chain);
2918
2919 /* Alternate contexts are added as "lower quality" contexts of
2920 * chain, to avoid loops in alternate chain creation.
2921 * The highest-quality chain is chosen at the end.
2922 */
2923 if (alternate)
2925 } while (ret && alternate);
2929 pChain = (PCERT_CHAIN_CONTEXT)chain;
2930 CRYPT_VerifyChainRevocation(pChain, pTime, hAdditionalStore,
2931 pChainPara, dwFlags);
2932 CRYPT_CheckUsages(pChain, pChainPara);
2933 TRACE_(chain)("error status: %08lx\n",
2934 pChain->TrustStatus.dwErrorStatus);
2935 if (ppChainContext)
2936 *ppChainContext = pChain;
2937 else
2939 }
2940 TRACE("returning %d\n", ret);
2941 return ret;
2942}
static BOOL CRYPT_BuildCandidateChainFromCert(CertificateChainEngine *engine, PCCERT_CONTEXT cert, LPFILETIME pTime, HCERTSTORE hAdditionalStore, DWORD flags, CertificateChain **ppChain)
Definition: chain.c:2247
static BOOL CRYPT_AddAlternateChainToChain(CertificateChain *chain, const CertificateChain *alternate)
Definition: chain.c:2582
static void CRYPT_VerifyChainRevocation(PCERT_CHAIN_CONTEXT chain, LPFILETIME pTime, HCERTSTORE hAdditionalStore, const CERT_CHAIN_PARA *pChainPara, DWORD chainFlags)
Definition: chain.c:2628
VOID WINAPI CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext)
Definition: chain.c:2956
static void CRYPT_FreeLowerQualityChains(CertificateChain *chain)
Definition: chain.c:2347
static void CRYPT_CheckUsages(PCERT_CHAIN_CONTEXT chain, const CERT_CHAIN_PARA *pChainPara)
Definition: chain.c:2741
static LPCSTR debugstr_filetime(LPFILETIME pTime)
Definition: chain.c:2209
static CertificateChain * CRYPT_BuildAlternateContextFromChain(CertificateChainEngine *engine, LPFILETIME pTime, HCERTSTORE hAdditionalStore, DWORD flags, CertificateChain *chain)
Definition: chain.c:2438
static CertificateChain * CRYPT_ChooseHighestQualityChain(CertificateChain *chain)
Definition: chain.c:2550
static void dump_chain_para(const CERT_CHAIN_PARA *pChainPara)
Definition: chain.c:2860
#define TRACE_(x)
Definition: compat.h:76
#define TRACE_ON(x)
Definition: compat.h:75
static LPCWSTR LPVOID pvReserved
Definition: asmcache.c:749
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
CERT_TRUST_STATUS TrustStatus
Definition: wincrypt.h:1051
PCERT_INFO pCertInfo
Definition: wincrypt.h:491
CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm
Definition: wincrypt.h:252
#define CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS
Definition: wincrypt.h:1177
struct _CERT_CHAIN_CONTEXT * PCERT_CHAIN_CONTEXT
Definition: wincrypt.h:1046
#define ERROR_INVALID_DATA
Definition: winerror.h:238

Referenced by CertTrustFinalPolicy(), check_and_store_certs(), getChain(), netconn_verify_cert(), save_cert_as_cms(), save_pfx(), test_CERT_CHAIN_PARA_cbSize(), testGetCertChain(), testVerifyCertChainPolicy(), 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 3806 of file chain.c.

3809{
3810 static HCRYPTOIDFUNCSET set = NULL;
3811 BOOL ret = FALSE;
3813 HCRYPTOIDFUNCADDR hFunc = NULL;
3814
3815 TRACE("(%s, %p, %p, %p)\n", debugstr_a(szPolicyOID), pChainContext,
3816 pPolicyPara, pPolicyStatus);
3817 if (TRACE_ON(chain))
3818 dump_policy_para(pPolicyPara);
3819
3820 if (IS_INTOID(szPolicyOID))
3821 {
3822 switch (LOWORD(szPolicyOID))
3823 {
3825 verifyPolicy = verify_base_policy;
3826 break;
3828 verifyPolicy = verify_authenticode_policy;
3829 break;
3831 verifyPolicy = verify_ssl_policy;
3832 break;
3834 verifyPolicy = verify_basic_constraints_policy;
3835 break;
3837 verifyPolicy = verify_ms_root_policy;
3838 break;
3839 default:
3840 FIXME("unimplemented for %d\n", LOWORD(szPolicyOID));
3841 }
3842 }
3843 if (!verifyPolicy)
3844 {
3845 if (!set)
3849 (void **)&verifyPolicy, &hFunc);
3850 }
3851 if (verifyPolicy)
3852 ret = verifyPolicy(szPolicyOID, pChainContext, pPolicyPara,
3853 pPolicyStatus);
3854 if (hFunc)
3856 TRACE("returning %d (%08lx)\n", ret, pPolicyStatus->dwError);
3857 return ret;
3858}
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:3738
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:3450
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:3127
static void dump_policy_para(PCERT_CHAIN_POLICY_PARA para)
Definition: chain.c:3796
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:2994
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:3086
BOOL(WINAPI * CertVerifyCertificateChainPolicyFunc)(LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
Definition: chain.c:3792
HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, DWORD dwFlags)
Definition: oid.c:103
BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr)
Definition: oid.c:375
BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, DWORD dwFlags)
Definition: oid.c:456
#define debugstr_a
Definition: kernel32.h:31
#define LOWORD(l)
Definition: pedump.c:82
#define CERT_CHAIN_POLICY_MICROSOFT_ROOT
Definition: wincrypt.h:1080
#define CERT_CHAIN_POLICY_BASE
Definition: wincrypt.h:1074
#define CERT_CHAIN_POLICY_BASIC_CONSTRAINTS
Definition: wincrypt.h:1078
#define X509_ASN_ENCODING
Definition: wincrypt.h:2501
#define CERT_CHAIN_POLICY_AUTHENTICODE
Definition: wincrypt.h:1075
#define CERT_CHAIN_POLICY_SSL
Definition: wincrypt.h:1077
#define CRYPT_OID_VERIFY_CERTIFICATE_CHAIN_POLICY_FUNC
Definition: wincrypt.h:2675

Referenced by checkChainPolicyStatus(), netconn_verify_cert(), SoftpubAuthenticode(), testVerifyCertChainPolicy(), 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 963 of file chain.c.

965{
966 CERT_ALT_NAME_INFO *subjectAltName;
967 DWORD size;
968
970 altNameExt->Value.pbData, altNameExt->Value.cbData,
972 &subjectAltName, &size))
973 {
974 DWORD i;
975
976 for (i = 0; i < subjectAltName->cAltEntry; i++)
977 {
978 BOOL nameFormPresent;
979
980 /* A name constraint only applies if the name form is present.
981 * From RFC 5280, section 4.2.1.10:
982 * "Restrictions apply only when the specified name form is
983 * present. If no name of the type is in the certificate,
984 * the certificate is acceptable."
985 */
987 &subjectAltName->rgAltEntry[i], nameConstraints,
988 trustErrorStatus))
989 {
990 TRACE_(chain)("subject alternate name form %ld excluded\n",
991 subjectAltName->rgAltEntry[i].dwAltNameChoice);
992 *trustErrorStatus |=
994 }
995 nameFormPresent = FALSE;
997 &subjectAltName->rgAltEntry[i], nameConstraints,
998 trustErrorStatus, &nameFormPresent) && nameFormPresent)
999 {
1000 TRACE_(chain)("subject alternate name form %ld not permitted\n",
1001 subjectAltName->rgAltEntry[i].dwAltNameChoice);
1002 *trustErrorStatus |=
1004 }
1005 }
1006 LocalFree(subjectAltName);
1007 }
1008 else
1009 *trustErrorStatus |=
1011}
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:6998
static BOOL alt_name_matches_excluded_name(const CERT_ALT_NAME_ENTRY *name, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
Definition: chain.c:925
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:937
GLsizeiptr size
Definition: glext.h:5919
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
PCERT_ALT_NAME_ENTRY rgAltEntry
Definition: wincrypt.h:366
CRYPT_OBJID_BLOB Value
Definition: wincrypt.h:241
BYTE * pbData
Definition: wincrypt.h:112
#define CRYPT_DECODE_NOCOPY_FLAG
Definition: wincrypt.h:3608
#define CERT_TRUST_INVALID_EXTENSION
Definition: wincrypt.h:990
#define CRYPT_DECODE_ALLOC_FLAG
Definition: wincrypt.h:3612
#define CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT
Definition: wincrypt.h:996
#define CERT_TRUST_INVALID_NAME_CONSTRAINTS
Definition: wincrypt.h:993
#define CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT
Definition: wincrypt.h:997
#define X509_ALTERNATE_NAME
Definition: wincrypt.h:3529

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 1122 of file chain.c.

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

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 1053 of file chain.c.

1056{
1058 DWORD size;
1059
1061 subjectName->pbData, subjectName->cbData,
1063 {
1064 DWORD i, j;
1065
1066 for (i = 0; i < name->cRDN; i++)
1067 for (j = 0; j < name->rgRDN[i].cRDNAttr; j++)
1068 if (!strcmp(name->rgRDN[i].rgRDNAttr[j].pszObjId,
1070 {
1071 BOOL nameFormPresent;
1072
1073 /* A name constraint only applies if the name form is
1074 * present. From RFC 5280, section 4.2.1.10:
1075 * "Restrictions apply only when the specified name form is
1076 * present. If no name of the type is in the certificate,
1077 * the certificate is acceptable."
1078 */
1080 &name->rgRDN[i].rgRDNAttr[j], nameConstraints,
1081 trustErrorStatus))
1082 {
1083 TRACE_(chain)(
1084 "email address in subject name is excluded\n");
1085 *trustErrorStatus |=
1087 }
1088 nameFormPresent = FALSE;
1090 &name->rgRDN[i].rgRDNAttr[j], nameConstraints,
1091 trustErrorStatus, &nameFormPresent) && nameFormPresent)
1092 {
1093 TRACE_(chain)(
1094 "email address in subject name is not permitted\n");
1095 *trustErrorStatus |=
1097 }
1098 }
1099 LocalFree(name);
1100 }
1101 else
1102 *trustErrorStatus |=
1104}
static BOOL rfc822_attr_matches_excluded_name(const CERT_RDN_ATTR *attr, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
Definition: chain.c:1013
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:1031
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
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:3537
#define szOID_RSA_emailAddr
Definition: wincrypt.h:3188

Referenced by compare_subject_with_constraints().

◆ CRYPT_AddAlternateChainToChain()

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

Definition at line 2582 of file chain.c.

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

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 423 of file chain.c.

425{
426 BOOL ret = FALSE;
428
429 if (element)
430 {
431 if (!chain->cElement)
432 chain->rgpElement = CryptMemAlloc(sizeof(PCERT_CHAIN_ELEMENT));
433 else
434 chain->rgpElement = CryptMemRealloc(chain->rgpElement,
435 (chain->cElement + 1) * sizeof(PCERT_CHAIN_ELEMENT));
436 if (chain->rgpElement)
437 {
438 chain->rgpElement[chain->cElement++] = element;
439 memset(element, 0, sizeof(CERT_CHAIN_ELEMENT));
440 element->cbSize = sizeof(CERT_CHAIN_ELEMENT);
442 if (chain->cElement > 1)
443 chain->rgpElement[chain->cElement - 2]->TrustStatus.dwInfoStatus
444 = subjectInfoStatus;
445 /* FIXME: initialize the rest of element */
446 if (!(chain->cElement % engine->CycleDetectionModulus))
447 {
449 /* Reinitialize the element pointer in case the chain is
450 * cyclic, in which case the chain is truncated.
451 */
452 element = chain->rgpElement[chain->cElement - 1];
453 }
454 CRYPT_CombineTrustStatus(&chain->TrustStatus,
455 &element->TrustStatus);
456 ret = TRUE;
457 }
458 else
460 }
461 return ret;
462}
PCCERT_CONTEXT WINAPI CertDuplicateCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:358
static void CRYPT_CheckSimpleChainForCycles(PCERT_SIMPLE_CHAIN chain)
Definition: chain.c:379
static void CRYPT_CombineTrustStatus(CERT_TRUST_STATUS *chainStatus, const CERT_TRUST_STATUS *elementStatus)
Definition: chain.c:412
VOID WINAPI CryptMemFree(LPVOID pv)
Definition: main.c:146
static BYTE cert[]
Definition: msg.c:1374
#define memset(x, y, z)
Definition: compat.h:39
DWORD CycleDetectionModulus
Definition: chain.c:51
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 54 of file chain.c.

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

Referenced by CRYPT_CreateChainEngine().

◆ CRYPT_BuildAlternateContextFromChain()

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

Definition at line 2438 of file chain.c.

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

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 2247 of file chain.c.

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

Referenced by CertGetCertificateChain().

◆ CRYPT_BuildSimpleChain()

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

Definition at line 2177 of file chain.c.

2179{
2180 BOOL ret = TRUE;
2181 PCCERT_CONTEXT cert = chain->rgpElement[chain->cElement - 1]->pCertContext;
2182
2183 while (ret && !CRYPT_IsSimpleChainCyclic(chain) &&
2185 {
2187 &chain->rgpElement[chain->cElement - 1]->TrustStatus.dwInfoStatus);
2188
2189 if (issuer)
2190 {
2192 chain->rgpElement[chain->cElement - 1]->TrustStatus.dwInfoStatus);
2193 /* CRYPT_AddCertToSimpleChain add-ref's the issuer, so free it to
2194 * close the enumeration that found it
2195 */
2197 cert = issuer;
2198 }
2199 else
2200 {
2201 TRACE_(chain)("Couldn't find issuer, halting chain creation\n");
2202 chain->TrustStatus.dwErrorStatus |= CERT_TRUST_IS_PARTIAL_CHAIN;
2203 break;
2204 }
2205 }
2206 return ret;
2207}
static BOOL CRYPT_IsSimpleChainCyclic(const CERT_SIMPLE_CHAIN *chain)
Definition: chain.c:403
DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert)
Definition: chain.c:264
static WCHAR issuer[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1972
#define CERT_TRUST_IS_PARTIAL_CHAIN
Definition: wincrypt.h:1003

Referenced by CRYPT_BuildAlternateContextFromChain(), and CRYPT_GetSimpleChainForCert().

◆ CRYPT_ChainQuality()

static DWORD CRYPT_ChainQuality ( const CertificateChain chain)
static

Definition at line 2524 of file chain.c.

2525{
2527
2528 if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus,
2530 quality &= ~CHAIN_QUALITY_TRUSTED_ROOT;
2531 if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus,
2533 quality &= ~CHAIN_QUALITY_BASIC_CONSTRAINTS;
2534 if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus,
2536 quality &= ~CHAIN_QUALITY_COMPLETE_CHAIN;
2537 if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus,
2539 quality &= ~CHAIN_QUALITY_TIME_VALID;
2540 if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus,
2542 quality &= ~CHAIN_QUALITY_SIGNATURE_VALID;
2543 return quality;
2544}
#define CHAIN_QUALITY_HIGHEST
Definition: chain.c:2516
#define IS_TRUST_ERROR_SET(TrustStatus, bits)
Definition: chain.c:2521
int quality
Definition: jpeglib.h:994
#define CERT_TRUST_INVALID_BASIC_CONSTRAINTS
Definition: wincrypt.h:992
#define CERT_TRUST_IS_NOT_TIME_NESTED
Definition: wincrypt.h:983
#define CERT_TRUST_IS_NOT_SIGNATURE_VALID
Definition: wincrypt.h:985
#define CERT_TRUST_IS_UNTRUSTED_ROOT
Definition: wincrypt.h:987
#define CERT_TRUST_IS_NOT_TIME_VALID
Definition: wincrypt.h:982

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 576 of file chain.c.

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

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

Referenced by CRYPT_CheckSimpleChain().

◆ CRYPT_CheckChainPolicies()

static void CRYPT_CheckChainPolicies ( PCERT_SIMPLE_CHAIN  chain)
static

Definition at line 1377 of file chain.c.

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

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 1192 of file chain.c.

1195{
1197
1198 if (ext)
1199 compare_alt_name_with_constraints(ext, nameConstraints,
1200 trustErrorStatus);
1201 /* Name constraints apply to the subject alternative name as well as the
1202 * subject name. From RFC 5280, section 4.2.1.10:
1203 * "Restrictions apply to the subject distinguished name and apply to
1204 * subject alternative names."
1205 */
1206 compare_subject_with_constraints(&cert->Subject, nameConstraints,
1207 trustErrorStatus);
1208}
static void compare_alt_name_with_constraints(const CERT_EXTENSION *altNameExt, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
Definition: chain.c:963
static void compare_subject_with_constraints(const CERT_NAME_BLOB *subjectName, const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, DWORD *trustErrorStatus)
Definition: chain.c:1122
static PCERT_EXTENSION get_subject_alt_name_ext(const CERT_INFO *cert)
Definition: chain.c:951
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 1353 of file chain.c.

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

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 {
95 HCERTSTORE rootStore = CertOpenSystemStoreW(0, L"Root");
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
PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrev)
Definition: store.c:922
BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
Definition: store.c:1121
HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, LPCWSTR szSubSystemProtocol)
Definition: store.c:910
#define check(expected, result)
Definition: dplayx.c:32
#define L(x)
Definition: resources.c:13

Referenced by CertCreateCertificateChainEngine().

◆ CRYPT_CheckRootCert()

static void CRYPT_CheckRootCert ( HCERTSTORE  hRoot,
PCERT_CHAIN_ELEMENT  rootElement 
)
static

Definition at line 487 of file chain.c.

489{
490 PCCERT_CONTEXT root = rootElement->pCertContext;
491
492 if (!CryptVerifyCertificateSignatureEx(0, root->dwCertEncodingType,
495 {
496 TRACE_(chain)("Last certificate's signature is invalid\n");
497 rootElement->TrustStatus.dwErrorStatus |=
499 }
500 CRYPT_CheckTrustedStatus(hRoot, rootElement);
501}
BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, DWORD dwSubjectType, void *pvSubject, DWORD dwIssuerType, void *pvIssuer, DWORD dwFlags, void *pvReserved)
Definition: cert.c:2914
static void CRYPT_CheckTrustedStatus(HCERTSTORE hRoot, PCERT_CHAIN_ELEMENT rootElement)
Definition: chain.c:474
static HTREEITEM hRoot
Definition: treeview.c:383
PCCERT_CONTEXT pCertContext
Definition: wincrypt.h:1028
CERT_TRUST_STATUS TrustStatus
Definition: wincrypt.h:1029
#define CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT
Definition: wincrypt.h:3632
#define CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT
Definition: wincrypt.h:3627

Referenced by CRYPT_CheckSimpleChain().

◆ CRYPT_CheckSimpleChain()

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

Definition at line 1875 of file chain.c.

1877{
1878 PCERT_CHAIN_ELEMENT rootElement = chain->rgpElement[chain->cElement - 1];
1879 int i;
1880 BOOL pathLengthConstraintViolated = FALSE;
1881 CERT_BASIC_CONSTRAINTS2_INFO constraints = { FALSE, FALSE, 0 };
1882 DWORD status;
1883
1884 TRACE_(chain)("checking chain with %ld elements for time %s\n",
1885 chain->cElement, filetime_to_str(time));
1886 for (i = chain->cElement - 1; i >= 0; i--)
1887 {
1888 BOOL isRoot;
1889
1890 if (TRACE_ON(chain))
1891 dump_element(chain->rgpElement[i]->pCertContext);
1892 if (i == chain->cElement - 1)
1894 chain->rgpElement[i]->pCertContext);
1895 else
1896 isRoot = FALSE;
1897 if (!CRYPT_IsCertVersionValid(chain->rgpElement[i]->pCertContext))
1898 {
1899 /* MS appears to accept certs whose versions don't match their
1900 * contents, so there isn't an appropriate error code.
1901 */
1902 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1904 }
1906 chain->rgpElement[i]->pCertContext->pCertInfo) != 0)
1907 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1909 if (i != 0)
1910 {
1911 /* Check the signature of the cert this issued */
1914 (void *)chain->rgpElement[i - 1]->pCertContext,
1916 (void *)chain->rgpElement[i]->pCertContext, 0, NULL))
1917 chain->rgpElement[i - 1]->TrustStatus.dwErrorStatus |=
1919 /* Once a path length constraint has been violated, every remaining
1920 * CA cert's basic constraints is considered invalid.
1921 */
1922 if (pathLengthConstraintViolated)
1923 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1925 else if (!CRYPT_CheckBasicConstraintsForCA(engine,
1926 chain->rgpElement[i]->pCertContext, &constraints, i - 1, isRoot,
1927 &pathLengthConstraintViolated))
1928 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1930 else if (constraints.fPathLenConstraint &&
1931 constraints.dwPathLenConstraint)
1932 {
1933 /* This one's valid - decrement max length */
1934 constraints.dwPathLenConstraint--;
1935 }
1936 }
1937 else
1938 {
1939 /* Check whether end cert has a basic constraints extension */
1941 chain->rgpElement[i]->pCertContext, &constraints, FALSE))
1942 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1944 }
1945 if (!CRYPT_KeyUsageValid(engine, chain->rgpElement[i]->pCertContext,
1946 isRoot, constraints.fCA, i))
1947 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1950 {
1951 /* If the chain is cyclic, then the path length constraints
1952 * are violated, because the chain is infinitely long.
1953 */
1954 pathLengthConstraintViolated = TRUE;
1955 chain->TrustStatus.dwErrorStatus |=
1958 }
1959 /* Check whether every critical extension is supported */
1961 chain->rgpElement[i]->pCertContext))
1962 chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
1965 CRYPT_CombineTrustStatus(&chain->TrustStatus,
1966 &chain->rgpElement[i]->TrustStatus);
1967 }
1971 {
1972 rootElement->TrustStatus.dwInfoStatus |= status;
1973 CRYPT_CheckRootCert(engine->hRoot, rootElement);
1974 }
1975 CRYPT_CombineTrustStatus(&chain->TrustStatus, &rootElement->TrustStatus);
1976}
LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify, PCERT_INFO pCertInfo)
Definition: cert.c:2229
static void CRYPT_CheckChainPolicies(PCERT_SIMPLE_CHAIN chain)
Definition: chain.c:1377
static void CRYPT_CheckChainNameConstraints(PCERT_SIMPLE_CHAIN chain)
Definition: chain.c:1275
static BOOL CRYPT_KeyUsageValid(CertificateChainEngine *engine, PCCERT_CONTEXT cert, BOOL isRoot, BOOL isCA, DWORD index)
Definition: chain.c:1719
static BOOL CRYPT_IsCertVersionValid(PCCERT_CONTEXT cert)
Definition: chain.c:1836
static BOOL CRYPT_CheckBasicConstraintsForCA(CertificateChainEngine *engine, PCCERT_CONTEXT cert, CERT_BASIC_CONSTRAINTS2_INFO *chainConstraints, DWORD remainingCAs, BOOL isRoot, BOOL *pathLengthConstraintViolated)
Definition: chain.c:576
static BOOL CRYPT_CriticalExtensionsSupported(PCCERT_CONTEXT cert)
Definition: chain.c:1798
static LPCSTR filetime_to_str(const FILETIME *time)
Definition: chain.c:1671
static void CRYPT_CheckRootCert(HCERTSTORE hRoot, PCERT_CHAIN_ELEMENT rootElement)
Definition: chain.c:487
static void dump_element(PCCERT_CONTEXT cert)
Definition: chain.c:1685
__u16 time
Definition: mkdosfs.c:8
HCERTSTORE hRoot
Definition: chain.c:46
Definition: ps.c:97
#define CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT
Definition: wincrypt.h:1001
#define CERT_TRUST_IS_NOT_VALID_FOR_USAGE
Definition: wincrypt.h:986

Referenced by CRYPT_BuildAlternateContextFromChain(), and CRYPT_GetSimpleChainForCert().

◆ CRYPT_CheckSimpleChainForCycles()

static void CRYPT_CheckSimpleChainForCycles ( PCERT_SIMPLE_CHAIN  chain)
static

Definition at line 379 of file chain.c.

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

Referenced by CRYPT_AddCertToSimpleChain().

◆ CRYPT_CheckTrustedStatus()

static void CRYPT_CheckTrustedStatus ( HCERTSTORE  hRoot,
PCERT_CHAIN_ELEMENT  rootElement 
)
static

Definition at line 474 of file chain.c.

476{
478 rootElement->pCertContext);
479
480 if (!trustedRoot)
481 rootElement->TrustStatus.dwErrorStatus |=
483 else
484 CertFreeCertificateContext(trustedRoot);
485}

Referenced by CRYPT_CheckRootCert().

◆ CRYPT_CheckUsages()

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

Definition at line 2741 of file chain.c.

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

Referenced by CertGetCertificateChain().

◆ CRYPT_ChooseHighestQualityChain()

static CertificateChain * CRYPT_ChooseHighestQualityChain ( CertificateChain chain)
static

Definition at line 2550 of file chain.c.

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

Referenced by CertGetCertificateChain().

◆ CRYPT_CloseStores()

static void CRYPT_CloseStores ( DWORD  cStores,
HCERTSTORE stores 
)
inlinestatic

Definition at line 63 of file chain.c.

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

Referenced by CRYPT_CreateChainEngine().

◆ CRYPT_CombineTrustStatus()

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

Definition at line 412 of file chain.c.

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

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 2373 of file chain.c.

2375{
2377
2378 if (copy)
2379 {
2380 copy->ref = 1;
2381 copy->world = CertDuplicateStore(chain->world);
2382 copy->context.cbSize = sizeof(CERT_CHAIN_CONTEXT);
2383 /* Leave the trust status of the copied chain unset, it'll get
2384 * rechecked after the new chain is done.
2385 */
2386 memset(&copy->context.TrustStatus, 0, sizeof(CERT_TRUST_STATUS));
2387 copy->context.cLowerQualityChainContext = 0;
2388 copy->context.rgpLowerQualityChainContext = NULL;
2389 copy->context.fHasRevocationFreshnessTime = FALSE;
2390 copy->context.dwRevocationFreshnessTime = 0;
2391 copy->context.rgpChain = CryptMemAlloc(
2392 (iChain + 1) * sizeof(PCERT_SIMPLE_CHAIN));
2393 if (copy->context.rgpChain)
2394 {
2395 BOOL ret = TRUE;
2396 DWORD i;
2397
2398 memset(copy->context.rgpChain, 0,
2399 (iChain + 1) * sizeof(PCERT_SIMPLE_CHAIN));
2400 if (iChain)
2401 {
2402 for (i = 0; ret && iChain && i < iChain - 1; i++)
2403 {
2404 copy->context.rgpChain[i] =
2405 CRYPT_CopySimpleChainToElement(chain->context.rgpChain[i],
2406 chain->context.rgpChain[i]->cElement - 1);
2407 if (!copy->context.rgpChain[i])
2408 ret = FALSE;
2409 }
2410 }
2411 else
2412 i = 0;
2413 if (ret)
2414 {
2415 copy->context.rgpChain[i] =
2416 CRYPT_CopySimpleChainToElement(chain->context.rgpChain[i],
2417 iElement);
2418 if (!copy->context.rgpChain[i])
2419 ret = FALSE;
2420 }
2421 if (!ret)
2422 {
2424 copy = NULL;
2425 }
2426 else
2427 copy->context.cChain = iChain + 1;
2428 }
2429 else
2430 {
2432 copy = NULL;
2433 }
2434 }
2435 return copy;
2436}
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:2292
HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
Definition: store.c:1110

Referenced by CRYPT_BuildAlternateContextFromChain().

◆ CRYPT_CopySimpleChainToElement()

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

Definition at line 2292 of file chain.c.

2294{
2296
2297 if (copy)
2298 {
2299 memset(copy, 0, sizeof(CERT_SIMPLE_CHAIN));
2300 copy->cbSize = sizeof(CERT_SIMPLE_CHAIN);
2301 copy->rgpElement =
2302 CryptMemAlloc((iElement + 1) * sizeof(PCERT_CHAIN_ELEMENT));
2303 if (copy->rgpElement)
2304 {
2305 DWORD i;
2306 BOOL ret = TRUE;
2307
2308 memset(copy->rgpElement, 0,
2309 (iElement + 1) * sizeof(PCERT_CHAIN_ELEMENT));
2310 for (i = 0; ret && i <= iElement; i++)
2311 {
2314
2315 if (element)
2316 {
2317 *element = *chain->rgpElement[i];
2319 chain->rgpElement[i]->pCertContext);
2320 /* Reset the trust status of the copied element, it'll get
2321 * rechecked after the new chain is done.
2322 */
2323 memset(&element->TrustStatus, 0, sizeof(CERT_TRUST_STATUS));
2324 copy->rgpElement[copy->cElement++] = element;
2325 }
2326 else
2327 ret = FALSE;
2328 }
2329 if (!ret)
2330 {
2331 for (i = 0; i <= iElement; i++)
2332 CryptMemFree(copy->rgpElement[i]);
2333 CryptMemFree(copy->rgpElement);
2335 copy = NULL;
2336 }
2337 }
2338 else
2339 {
2341 copy = NULL;
2342 }
2343 }
2344 return copy;
2345}
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 if(!root) {
121 if(config->cbSize >= sizeof(CERT_CHAIN_ENGINE_CONFIG) && config->hExclusiveRoot)
122 root = CertDuplicateStore(config->hExclusiveRoot);
123 else if (config->hRestrictedRoot)
124 root = CertDuplicateStore(config->hRestrictedRoot);
125 else
126 root = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, L"Root");
127 if(!root)
128 return NULL;
129 }
130
131 engine = CryptMemAlloc(sizeof(CertificateChainEngine));
132 if(!engine) {
134 return NULL;
135 }
136
137 engine->ref = 1;
138 engine->hRoot = root;
140 worldStores[0] = CertDuplicateStore(engine->hRoot);
141 worldStores[1] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, L"CA");
142 worldStores[2] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, L"My");
143 worldStores[3] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, L"Trust");
144
145 CRYPT_AddStoresToCollection(engine->hWorld, ARRAY_SIZE(worldStores), worldStores);
146 CRYPT_AddStoresToCollection(engine->hWorld, config->cAdditionalStore, config->rghAdditionalStore);
147 CRYPT_CloseStores(ARRAY_SIZE(worldStores), worldStores);
148
149 engine->dwFlags = config->dwFlags;
150 engine->dwUrlRetrievalTimeout = config->dwUrlRetrievalTimeout;
151 engine->MaximumCachedCertificates = config->MaximumCachedCertificates;
152 if(config->CycleDetectionModulus)
153 engine->CycleDetectionModulus = config->CycleDetectionModulus;
154 else
156
157 return engine;
158}
#define ARRAY_SIZE(A)
Definition: main.h:20
struct _root root
static void CRYPT_CloseStores(DWORD cStores, HCERTSTORE *stores)
Definition: chain.c:63
#define DEFAULT_CYCLE_MODULUS
Definition: chain.c:36
static void CRYPT_AddStoresToCollection(HCERTSTORE collection, DWORD cStores, HCERTSTORE *stores)
Definition: chain.c:54
DWORD MaximumCachedCertificates
Definition: chain.c:50
DWORD dwUrlRetrievalTimeout
Definition: chain.c:49
#define CERT_STORE_PROV_SYSTEM_W
Definition: wincrypt.h:2463

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

◆ CRYPT_CriticalExtensionsSupported()

static BOOL CRYPT_CriticalExtensionsSupported ( PCCERT_CONTEXT  cert)
static

Definition at line 1798 of file chain.c.

1799{
1800 BOOL ret = TRUE;
1801 DWORD i;
1802
1803 for (i = 0; ret && i < cert->pCertInfo->cExtension; i++)
1804 {
1805 if (cert->pCertInfo->rgExtension[i].fCritical)
1806 {
1807 LPCSTR oid = cert->pCertInfo->rgExtension[i].pszObjId;
1808
1810 ret = TRUE;
1811 else if (!strcmp(oid, szOID_BASIC_CONSTRAINTS2))
1812 ret = TRUE;
1813 else if (!strcmp(oid, szOID_NAME_CONSTRAINTS))
1814 ret = TRUE;
1815 else if (!strcmp(oid, szOID_KEY_USAGE))
1816 ret = TRUE;
1817 else if (!strcmp(oid, szOID_SUBJECT_ALT_NAME))
1818 ret = TRUE;
1819 else if (!strcmp(oid, szOID_SUBJECT_ALT_NAME2))
1820 ret = TRUE;
1821 else if (!strcmp(oid, szOID_CERT_POLICIES))
1822 ret = TRUE;
1823 else if (!strcmp(oid, szOID_ENHANCED_KEY_USAGE))
1824 ret = TRUE;
1825 else
1826 {
1827 FIXME("unsupported critical extension %s\n",
1828 debugstr_a(oid));
1829 ret = FALSE;
1830 }
1831 }
1832 }
1833 return ret;
1834}
const char * LPCSTR
Definition: typedefs.h:52
#define szOID_BASIC_CONSTRAINTS2
Definition: wincrypt.h:3345
#define szOID_NAME_CONSTRAINTS
Definition: wincrypt.h:3351
#define szOID_KEY_USAGE
Definition: wincrypt.h:3341
#define szOID_BASIC_CONSTRAINTS
Definition: wincrypt.h:3339
#define szOID_SUBJECT_ALT_NAME
Definition: wincrypt.h:3336
#define szOID_CERT_POLICIES
Definition: wincrypt.h:3353
#define szOID_SUBJECT_ALT_NAME2
Definition: wincrypt.h:3343

Referenced by CRYPT_CheckSimpleChain().

◆ CRYPT_DecodeBasicConstraints()

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

Definition at line 509 of file chain.c.

511{
512 BOOL ret = TRUE;
514 cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
515
516 constraints->fPathLenConstraint = FALSE;
517 if (ext)
518 {
520 DWORD size = 0;
521
523 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG,
524 NULL, &info, &size);
525 if (ret)
526 {
527 if (info->SubjectType.cbData == 1)
528 constraints->fCA =
529 info->SubjectType.pbData[0] & CERT_CA_SUBJECT_FLAG;
531 }
532 }
533 else
534 {
536 cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
537 if (ext)
538 {
540
542 szOID_BASIC_CONSTRAINTS2, ext->Value.pbData, ext->Value.cbData,
543 0, NULL, constraints, &size);
544 }
545 else
546 constraints->fCA = defaultIfNotSpecified;
547 }
548 return ret;
549}
#define CERT_CA_SUBJECT_FLAG
Definition: wincrypt.h:387
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 1978 of file chain.c.

1980{
1981 CRYPT_URL_ARRAY *urls;
1983 DWORD size;
1984 BOOL res;
1985
1986 issuer = CertFindCertificateInStore(store, cert->dwCertEncodingType, 0, type, para, prev_issuer);
1987 if(issuer) {
1988 TRACE("Found in store %p\n", issuer);
1989 return issuer;
1990 }
1991
1992 /* FIXME: For alternate issuers, we don't search world store nor try to retrieve issuer from URL.
1993 * This needs more tests.
1994 */
1995 if(prev_issuer)
1996 return NULL;
1997
1998 if(engine->hWorld) {
1999 issuer = CertFindCertificateInStore(engine->hWorld, cert->dwCertEncodingType, 0, type, para, NULL);
2000 if(issuer) {
2001 TRACE("Found in world %p\n", issuer);
2002 return issuer;
2003 }
2004 }
2005
2007 if(!res)
2008 return NULL;
2009
2010 urls = CryptMemAlloc(size);
2011 if(!urls)
2012 return NULL;
2013
2015 if(res)
2016 {
2017 CERT_CONTEXT *new_cert;
2018 HCERTSTORE new_store;
2019 unsigned i;
2020
2021 for(i=0; i < urls->cUrl; i++)
2022 {
2023 TRACE("Trying URL %s\n", debugstr_w(urls->rgwszUrl[i]));
2024
2027 0, (void**)&new_cert, NULL, NULL, NULL, NULL);
2028 if(!res)
2029 {
2030 TRACE("CryptRetrieveObjectByUrlW failed: %lu\n", GetLastError());
2031 continue;
2032 }
2033
2034 /* FIXME: Use new_cert->hCertStore once cert ref count bug is fixed. */
2037 issuer = CertFindCertificateInStore(new_store, cert->dwCertEncodingType, 0, type, para, NULL);
2039 CertCloseStore(new_store, 0);
2040 if(issuer)
2041 {
2042 TRACE("Found downloaded issuer %p\n", issuer);
2043 break;
2044 }
2045 }
2046 }
2047
2048 CryptMemFree(urls);
2049 return issuer;
2050}
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:284
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:1738
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CONTEXT_OID_CERTIFICATE
Definition: wincrypt.h:1876
#define URL_OID_CERTIFICATE_ISSUER
Definition: wincrypt.h:1748
#define CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL
Definition: wincrypt.h:3778
#define CRYPT_AIA_RETRIEVAL
Definition: wincrypt.h:1894
#define CERT_STORE_PROV_MEMORY
Definition: wincrypt.h:2455
#define CERT_STORE_ADD_NEW
Definition: wincrypt.h:2651
#define CRYPT_CACHE_ONLY_RETRIEVAL
Definition: wincrypt.h:1883

Referenced by CRYPT_GetIssuer().

◆ CRYPT_FindIthElementInChain()

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

Definition at line 2607 of file chain.c.

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

Referenced by CRYPT_VerifyChainRevocation().

◆ CRYPT_FreeChainContext()

static void CRYPT_FreeChainContext ( CertificateChain chain)
static

Definition at line 2358 of file chain.c.

2359{
2360 DWORD i;
2361
2363 for (i = 0; i < chain->context.cChain; i++)
2364 CRYPT_FreeSimpleChain(chain->context.rgpChain[i]);
2365 CryptMemFree(chain->context.rgpChain);
2366 CertCloseStore(chain->world, 0);
2368}

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

◆ CRYPT_FreeChainElement()

static void CRYPT_FreeChainElement ( PCERT_CHAIN_ELEMENT  element)
static

Definition at line 373 of file chain.c.

374{
375 CertFreeCertificateContext(element->pCertContext);
377}

Referenced by CRYPT_CheckSimpleChainForCycles(), and CRYPT_FreeSimpleChain().

◆ CRYPT_FreeLowerQualityChains()

static void CRYPT_FreeLowerQualityChains ( CertificateChain chain)
static

Definition at line 2347 of file chain.c.

2348{
2349 DWORD i;
2350
2351 for (i = 0; i < chain->context.cLowerQualityChainContext; i++)
2352 CertFreeCertificateChain(chain->context.rgpLowerQualityChainContext[i]);
2353 CryptMemFree(chain->context.rgpLowerQualityChainContext);
2354 chain->context.cLowerQualityChainContext = 0;
2355 chain->context.rgpLowerQualityChainContext = NULL;
2356}

Referenced by CertGetCertificateChain(), and CRYPT_FreeChainContext().

◆ CRYPT_FreeSimpleChain()

static void CRYPT_FreeSimpleChain ( PCERT_SIMPLE_CHAIN  chain)
static

Definition at line 464 of file chain.c.

465{
466 DWORD i;
467
468 for (i = 0; i < chain->cElement; i++)
469 CRYPT_FreeChainElement(chain->rgpElement[i]);
470 CryptMemFree(chain->rgpElement);
472}

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 2052 of file chain.c.

2055{
2058 DWORD size;
2059
2060 *infoStatus = 0;
2062 subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
2063 {
2065 BOOL ret;
2066
2068 X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData,
2070 &info, &size);
2071 if (ret)
2072 {
2073 CERT_ID id;
2074
2075 if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
2076 {
2077 id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2078 memcpy(&id.IssuerSerialNumber.Issuer, &info->CertIssuer,
2079 sizeof(CERT_NAME_BLOB));
2080 memcpy(&id.IssuerSerialNumber.SerialNumber,
2081 &info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB));
2082
2083 issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
2084 if (issuer)
2085 {
2086 TRACE_(chain)("issuer found by issuer/serial number\n");
2088 }
2089 }
2090 else if (info->KeyId.cbData)
2091 {
2092 id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2093
2094 memcpy(&id.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
2095 issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
2096 if (issuer)
2097 {
2098 TRACE_(chain)("issuer found by key id\n");
2099 *infoStatus = CERT_TRUST_HAS_KEY_MATCH_ISSUER;
2100 }
2101 }
2102 LocalFree(info);
2103 }
2104 }
2106 subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
2107 {
2109 BOOL ret;
2110
2112 X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
2114 &info, &size);
2115 if (ret)
2116 {
2117 CERT_ID id;
2118
2119 if (info->AuthorityCertIssuer.cAltEntry &&
2120 info->AuthorityCertSerialNumber.cbData)
2121 {
2122 PCERT_ALT_NAME_ENTRY directoryName = NULL;
2123 DWORD i;
2124
2125 for (i = 0; !directoryName &&
2126 i < info->AuthorityCertIssuer.cAltEntry; i++)
2127 if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice
2129 directoryName =
2130 &info->AuthorityCertIssuer.rgAltEntry[i];
2131 if (directoryName)
2132 {
2133 id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2134 memcpy(&id.IssuerSerialNumber.Issuer,
2135 &directoryName->DirectoryName, sizeof(CERT_NAME_BLOB));
2136 memcpy(&id.IssuerSerialNumber.SerialNumber,
2137 &info->AuthorityCertSerialNumber,
2138 sizeof(CRYPT_INTEGER_BLOB));
2139
2140 issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
2141 if (issuer)
2142 {
2143 TRACE_(chain)("issuer found by directory name\n");
2145 }
2146 }
2147 else
2148 FIXME("no supported name type in authority key id2\n");
2149 }
2150 else if (info->KeyId.cbData)
2151 {
2152 id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2153 memcpy(&id.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
2154 issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
2155 if (issuer)
2156 {
2157 TRACE_(chain)("issuer found by key id\n");
2158 *infoStatus = CERT_TRUST_HAS_KEY_MATCH_ISSUER;
2159 }
2160 }
2161 LocalFree(info);
2162 }
2163 }
2164 else
2165 {
2166 issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_SUBJECT_NAME,
2167 &subject->pCertInfo->Issuer, flags, prevIssuer);
2168 TRACE_(chain)("issuer found by name\n");
2170 }
2171 return issuer;
2172}
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:1978
GLuint id
Definition: glext.h:5910
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
DWORD dwCertEncodingType
Definition: wincrypt.h:488
CERT_NAME_BLOB Issuer
Definition: wincrypt.h:253
#define CERT_FIND_CERT_ID
Definition: wincrypt.h:3054
#define X509_AUTHORITY_KEY_ID2
Definition: wincrypt.h:3550
#define szOID_AUTHORITY_KEY_IDENTIFIER
Definition: wincrypt.h:3331
#define CERT_ID_ISSUER_SERIAL_NUMBER
Definition: wincrypt.h:3838
#define CERT_ID_KEY_IDENTIFIER
Definition: wincrypt.h:3839
#define CERT_TRUST_HAS_EXACT_MATCH_ISSUER
Definition: wincrypt.h:1008
#define CERT_TRUST_HAS_KEY_MATCH_ISSUER
Definition: wincrypt.h:1009
#define X509_AUTHORITY_KEY_ID
Definition: wincrypt.h:3526
#define CERT_TRUST_HAS_NAME_MATCH_ISSUER
Definition: wincrypt.h:1010
#define CERT_FIND_SUBJECT_NAME
Definition: wincrypt.h:3025
#define szOID_AUTHORITY_KEY_IDENTIFIER2
Definition: wincrypt.h:3356

Referenced by CRYPT_BuildAlternateContextFromChain(), and CRYPT_BuildSimpleChain().

◆ CRYPT_GetNameConstraints()

static CERT_NAME_CONSTRAINTS_INFO * CRYPT_GetNameConstraints ( CERT_INFO cert)
static

Definition at line 1211 of file chain.c.

1212{
1214
1216
1218 cert->rgExtension)))
1219 {
1220 DWORD size;
1221
1223 ext->Value.pbData, ext->Value.cbData,
1225 &size);
1226 }
1227 return info;
1228}
#define X509_NAME_CONSTRAINTS
Definition: wincrypt.h:3577

Referenced by CRYPT_CheckChainNameConstraints().

◆ CRYPT_GetPolicies()

static CERT_POLICIES_INFO * CRYPT_GetPolicies ( PCCERT_CONTEXT  cert)
static

Definition at line 1335 of file chain.c.

1336{
1338 CERT_POLICIES_INFO *policies = NULL;
1339
1340 ext = CertFindExtension(szOID_KEY_USAGE, cert->pCertInfo->cExtension,
1341 cert->pCertInfo->rgExtension);
1342 if (ext)
1343 {
1344 DWORD size;
1345
1347 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
1348 &policies, &size);
1349 }
1350 return policies;
1351}
#define X509_CERT_POLICIES
Definition: wincrypt.h:3533

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 2216 of file chain.c.

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

Referenced by CRYPT_BuildCandidateChainFromCert().

◆ CRYPT_IsCertificateSelfSigned()

DWORD CRYPT_IsCertificateSelfSigned ( const CERT_CONTEXT cert)

Definition at line 264 of file chain.c.

265{
266 DWORD size, status = 0;
268 BOOL ret;
269
271 cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
272 {
274
275 ret = CryptDecodeObjectEx(cert->dwCertEncodingType,
276 X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
278 &info, &size);
279 if (ret)
280 {
281 if (info->AuthorityCertIssuer.cAltEntry &&
282 info->AuthorityCertSerialNumber.cbData)
283 {
284 PCERT_ALT_NAME_ENTRY directoryName = NULL;
285 DWORD i;
286
287 for (i = 0; !directoryName &&
288 i < info->AuthorityCertIssuer.cAltEntry; i++)
289 if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice
291 directoryName =
292 &info->AuthorityCertIssuer.rgAltEntry[i];
293 if (directoryName)
294 {
295 if (CertCompareCertificateName(cert->dwCertEncodingType, &directoryName->DirectoryName, &cert->pCertInfo->Issuer)
296 && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber, &cert->pCertInfo->SerialNumber))
298 }
299 else
300 {
301 FIXME("no supported name type in authority key id2\n");
302 ret = FALSE;
303 }
304 }
305 else if (info->KeyId.cbData)
306 {
309 if (ret && size == info->KeyId.cbData)
310 {
312
313 if (buf)
314 {
316 if (!memcmp(buf, info->KeyId.pbData, size))
319 }
320 }
321 }
323 }
324 }
326 cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
327 {
329
330 ret = CryptDecodeObjectEx(cert->dwCertEncodingType,
331 X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData,
333 &info, &size);
334 if (ret)
335 {
336 if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
337 {
338 if (CertCompareCertificateName(cert->dwCertEncodingType, &info->CertIssuer, &cert->pCertInfo->Issuer)
339 && CertCompareIntegerBlob(&info->CertSerialNumber, &cert->pCertInfo->SerialNumber))
341 }
342 else if (info->KeyId.cbData)
343 {
346 if (ret && size == info->KeyId.cbData)
347 {
349
350 if (buf)
351 {
354 if (!memcmp(buf, info->KeyId.pbData, size))
357 }
358 }
359 }
361 }
362 }
363 else
364 if (CertCompareCertificateName(cert->dwCertEncodingType, &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer))
366
367 if (status)
369
370 return status;
371}
BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType, PCERT_NAME_BLOB pCertName1, PCERT_NAME_BLOB pCertName2)
Definition: cert.c:1250
BOOL WINAPI CertCompareIntegerBlob(PCRYPT_INTEGER_BLOB pInt1, PCRYPT_INTEGER_BLOB pInt2)
Definition: cert.c:1291
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
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:2853
#define CERT_TRUST_IS_SELF_SIGNED
Definition: wincrypt.h:1011

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

◆ CRYPT_IsCertVersionValid()

static BOOL CRYPT_IsCertVersionValid ( PCCERT_CONTEXT  cert)
static

Definition at line 1836 of file chain.c.

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

Referenced by CRYPT_CheckSimpleChain().

◆ CRYPT_IsEmptyName()

static BOOL CRYPT_IsEmptyName ( const CERT_NAME_BLOB name)
static

Definition at line 1106 of file chain.c.

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

Referenced by compare_subject_with_constraints().

◆ CRYPT_IsSimpleChainCyclic()

static BOOL CRYPT_IsSimpleChainCyclic ( const CERT_SIMPLE_CHAIN chain)
inlinestatic

Definition at line 403 of file chain.c.

404{
405 if (chain->cElement)
406 return chain->rgpElement[chain->cElement - 1]->TrustStatus.dwErrorStatus
408 else
409 return FALSE;
410}

Referenced by CRYPT_BuildSimpleChain(), and CRYPT_CheckSimpleChain().

◆ CRYPT_IsValidNameConstraint()

static BOOL CRYPT_IsValidNameConstraint ( const CERT_NAME_CONSTRAINTS_INFO info)
static

Definition at line 1230 of file chain.c.

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

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 1719 of file chain.c.

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

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 2628 of file chain.c.

2631{
2632 DWORD cContext;
2633
2634 if (chainFlags & CERT_CHAIN_REVOCATION_CHECK_END_CERT)
2635 cContext = 1;
2636 else if ((chainFlags & CERT_CHAIN_REVOCATION_CHECK_CHAIN) ||
2638 {
2639 DWORD i;
2640
2641 for (i = 0, cContext = 0; i < chain->cChain; i++)
2642 {
2643 if (i < chain->cChain - 1 ||
2645 cContext += chain->rgpChain[i]->cElement;
2646 else
2647 cContext += chain->rgpChain[i]->cElement - 1;
2648 }
2649 }
2650 else
2651 cContext = 0;
2652 if (cContext)
2653 {
2654 DWORD i, j, iContext, revocationFlags;
2655 CERT_REVOCATION_PARA revocationPara = { sizeof(revocationPara), 0 };
2656 CERT_REVOCATION_STATUS revocationStatus =
2657 { sizeof(revocationStatus), 0 };
2658 BOOL ret;
2659
2660 revocationFlags = CERT_VERIFY_REV_CHAIN_FLAG;
2662 revocationFlags |= CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION;
2665 revocationPara.pftTimeToUse = pTime;
2666 if (hAdditionalStore)
2667 {
2668 revocationPara.cCertStore = 1;
2669 revocationPara.rgCertStore = &hAdditionalStore;
2670 revocationPara.hCrlStore = hAdditionalStore;
2671 }
2672 if (pChainPara->cbSize == sizeof(CERT_CHAIN_PARA))
2673 {
2674 revocationPara.dwUrlRetrievalTimeout =
2675 pChainPara->dwUrlRetrievalTimeout;
2676 revocationPara.fCheckFreshnessTime =
2677 pChainPara->fCheckRevocationFreshnessTime;
2678 revocationPara.dwFreshnessTime =
2679 pChainPara->dwRevocationFreshnessTime;
2680 }
2681 for (i = 0, iContext = 0; iContext < cContext && i < chain->cChain; i++)
2682 {
2683 for (j = 0; iContext < cContext &&
2684 j < chain->rgpChain[i]->cElement; j++, iContext++)
2685 {
2686 PCCERT_CONTEXT certToCheck =
2687 chain->rgpChain[i]->rgpElement[j]->pCertContext;
2688
2689 if (j < chain->rgpChain[i]->cElement - 1)
2690 revocationPara.pIssuerCert =
2691 chain->rgpChain[i]->rgpElement[j + 1]->pCertContext;
2692 else
2693 revocationPara.pIssuerCert = NULL;
2695 CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certToCheck,
2696 revocationFlags, &revocationPara, &revocationStatus);
2697
2698 if (!ret && chainFlags & CERT_CHAIN_REVOCATION_CHECK_CHAIN
2699 && revocationStatus.dwError == CRYPT_E_NO_REVOCATION_CHECK && revocationPara.pIssuerCert == NULL)
2700 ret = TRUE;
2701
2702 if (!ret)
2703 {
2705 chain, iContext);
2706 DWORD error;
2707
2708 switch (revocationStatus.dwError)
2709 {
2713 /* If the revocation status is unknown, it's assumed
2714 * to be offline too.
2715 */
2718 break;
2721 break;
2722 case CRYPT_E_REVOKED:
2724 break;
2725 default:
2726 WARN("unmapped error %08lx\n", revocationStatus.dwError);
2727 error = 0;
2728 }
2729 if (element)
2730 {
2731 /* FIXME: set element's pRevocationInfo member */
2732 element->TrustStatus.dwErrorStatus |= error;
2733 }
2734 chain->TrustStatus.dwErrorStatus |= error;
2735 }
2736 }
2737 }
2738 }
2739}
#define WARN(fmt,...)
Definition: precomp.h:61
BOOL WINAPI CertVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType, DWORD cContext, PVOID rgpvContext[], DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus)
Definition: cert.c:2005
static PCERT_CHAIN_ELEMENT CRYPT_FindIthElementInChain(const CERT_CHAIN_CONTEXT *chain, DWORD i)
Definition: chain.c:2607
#define error(str)
Definition: mkdosfs.c:1605
LPFILETIME pftTimeToUse
Definition: wincrypt.h:920
HCERTSTORE hCrlStore
Definition: wincrypt.h:919
PCCERT_CONTEXT pIssuerCert
Definition: wincrypt.h:916
HCERTSTORE * rgCertStore
Definition: wincrypt.h:918
#define CERT_TRUST_IS_REVOKED
Definition: wincrypt.h:984
#define CERT_TRUST_REVOCATION_STATUS_UNKNOWN
Definition: wincrypt.h:988
#define CERT_CHAIN_REVOCATION_CHECK_CHAIN
Definition: wincrypt.h:1170
#define CERT_CHAIN_REVOCATION_CHECK_END_CERT
Definition: wincrypt.h:1169
#define CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT
Definition: wincrypt.h:1174
#define CERT_TRUST_IS_OFFLINE_REVOCATION
Definition: wincrypt.h:998
#define CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION
Definition: wincrypt.h:932
#define CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
Definition: wincrypt.h:1171
#define CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG
Definition: wincrypt.h:933
#define CERT_CONTEXT_REVOCATION_TYPE
Definition: wincrypt.h:930
#define CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY
Definition: wincrypt.h:1172
#define CERT_VERIFY_REV_CHAIN_FLAG
Definition: wincrypt.h:931
#define CRYPT_E_REVOKED
Definition: winerror.h:4433
#define CRYPT_E_NO_REVOCATION_DLL
Definition: winerror.h:4434
#define CRYPT_E_NOT_IN_REVOCATION_DATABASE
Definition: winerror.h:4437
#define CRYPT_E_NO_REVOCATION_CHECK
Definition: winerror.h:4435
#define CRYPT_E_REVOCATION_OFFLINE
Definition: winerror.h:4436

Referenced by CertGetCertificateChain().

◆ debugstr_filetime()

static LPCSTR debugstr_filetime ( LPFILETIME  pTime)
static

Definition at line 2209 of file chain.c.

2210{
2211 if (!pTime)
2212 return "(nil)";
2213 return wine_dbg_sprintf("%p (%s)", pTime, filetime_to_str(pTime));
2214}
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 251 of file chain.c.

252{
255}
static CertificateChainEngine * default_lm_engine
Definition: chain.c:160
static CertificateChainEngine * default_cu_engine
Definition: chain.c:160

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 860 of file chain.c.

862{
863 CERT_NAME_INFO *constraintName;
864 DWORD size;
865 BOOL match = FALSE;
866
868 constraint->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &constraintName, &size))
869 {
870 DWORD i;
871
872 match = TRUE;
873 for (i = 0; match && i < constraintName->cRDN; i++)
876 (CERT_NAME_BLOB *)name, &constraintName->rgRDN[i]);
877 LocalFree(constraintName);
878 }
879 return match;
880}
BOOL WINAPI CertIsRDNAttrsInCertificateName(DWORD dwCertEncodingType, DWORD dwFlags, PCERT_NAME_BLOB pCertName, PCERT_RDN pRDN)
Definition: cert.c:2202
PCERT_RDN rgRDN
Definition: wincrypt.h:277
#define X509_NAME
Definition: wincrypt.h:3524
#define CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG
Definition: wincrypt.h:2954

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 771 of file chain.c.

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

Referenced by alt_name_matches().

◆ domain_name_matches()

static BOOL domain_name_matches ( LPCWSTR  constraint,
LPCWSTR  name 
)
static

Definition at line 643 of file chain.c.

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

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 1461 of file chain.c.

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

Referenced by dump_extension().

◆ dump_alt_name_entry()

static void dump_alt_name_entry ( const CERT_ALT_NAME_ENTRY entry)
static

Definition at line 1422 of file chain.c.

1423{
1424 LPWSTR str;
1425
1426 switch (entry->dwAltNameChoice)
1427 {
1429 TRACE_(chain)("CERT_ALT_NAME_OTHER_NAME, oid = %s\n",
1430 debugstr_a(entry->pOtherName->pszObjId));
1431 break;
1433 TRACE_(chain)("CERT_ALT_NAME_RFC822_NAME: %s\n",
1434 debugstr_w(entry->pwszRfc822Name));
1435 break;
1437 TRACE_(chain)("CERT_ALT_NAME_DNS_NAME: %s\n",
1438 debugstr_w(entry->pwszDNSName));
1439 break;
1441 str = name_value_to_str(&entry->DirectoryName);
1442 TRACE_(chain)("CERT_ALT_NAME_DIRECTORY_NAME: %s\n", debugstr_w(str));
1444 break;
1445 case CERT_ALT_NAME_URL:
1446 TRACE_(chain)("CERT_ALT_NAME_URL: %s\n", debugstr_w(entry->pwszURL));
1447 break;
1449 TRACE_(chain)("CERT_ALT_NAME_IP_ADDRESS: %ld bytes\n",
1450 entry->IPAddress.cbData);
1451 break;
1453 TRACE_(chain)("CERT_ALT_NAME_REGISTERED_ID: %s\n",
1454 debugstr_a(entry->pszRegisteredID));
1455 break;
1456 default:
1457 TRACE_(chain)("dwAltNameChoice = %ld\n", entry->dwAltNameChoice);
1458 }
1459}
static LPWSTR name_value_to_str(const CERT_NAME_BLOB *name)
Definition: chain.c:1406
uint32_t entry
Definition: isohybrid.c:63
const WCHAR * str
uint16_t * LPWSTR
Definition: typedefs.h:56
#define CERT_ALT_NAME_OTHER_NAME
Definition: wincrypt.h:354
#define CERT_ALT_NAME_REGISTERED_ID
Definition: wincrypt.h:362

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 3074 of file chain.c.

3076{
3077 if (extraPara)
3078 {
3079 TRACE_(chain)("cbSize = %ld\n", extraPara->cbSize);
3080 TRACE_(chain)("dwRegPolicySettings = %08lx\n",
3081 extraPara->dwRegPolicySettings);
3082 TRACE_(chain)("pSignerInfo = %p\n", extraPara->pSignerInfo);
3083 }
3084}

Referenced by verify_authenticode_policy().

◆ dump_basic_constraints()

static void dump_basic_constraints ( const CERT_EXTENSION ext)
static

Definition at line 1480 of file chain.c.

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

Referenced by dump_extension().

◆ dump_basic_constraints2()

static void dump_basic_constraints2 ( const CERT_EXTENSION ext)
static

Definition at line 1497 of file chain.c.

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

Referenced by dump_extension().

◆ dump_cert_policies()

static void dump_cert_policies ( const CERT_EXTENSION ext)
static

Definition at line 1572 of file chain.c.

1573{
1574 CERT_POLICIES_INFO *policies;
1575 DWORD size;
1576
1578 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
1579 &policies, &size))
1580 {
1581 DWORD i, j;
1582
1583 TRACE_(chain)("%ld policies:\n", policies->cPolicyInfo);
1584 for (i = 0; i < policies->cPolicyInfo; i++)
1585 {
1586 TRACE_(chain)("policy identifier: %s\n",
1588 TRACE_(chain)("%ld policy qualifiers:\n",
1589 policies->rgPolicyInfo[i].cPolicyQualifier);
1590 for (j = 0; j < policies->rgPolicyInfo[i].cPolicyQualifier; j++)
1591 TRACE_(chain)("%s\n", debugstr_a(
1592 policies->rgPolicyInfo[i].rgPolicyQualifier[j].
1593 pszPolicyQualifierId));
1594 }
1595 LocalFree(policies);
1596 }
1597}
CERT_POLICY_QUALIFIER_INFO * rgPolicyQualifier
Definition: wincrypt.h:404
DWORD cPolicyQualifier
Definition: wincrypt.h:403

Referenced by dump_extension().

◆ dump_chain_para()

static void dump_chain_para ( const CERT_CHAIN_PARA pChainPara)
static

Definition at line 2860 of file chain.c.

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

Referenced by CertGetCertificateChain().

◆ dump_element()

static void dump_element ( PCCERT_CONTEXT  cert)
static

Definition at line 1685 of file chain.c.

1686{
1687 LPWSTR name = NULL;
1688 DWORD len, i;
1689
1690 TRACE_(chain)("%p: version %ld\n", cert, cert->pCertInfo->dwVersion);
1693 name = CryptMemAlloc(len * sizeof(WCHAR));
1694 if (name)
1695 {
1698 TRACE_(chain)("issued by %s\n", debugstr_w(name));
1700 }
1702 NULL, 0);
1703 name = CryptMemAlloc(len * sizeof(WCHAR));
1704 if (name)
1705 {
1707 name, len);
1708 TRACE_(chain)("issued to %s\n", debugstr_w(name));
1710 }
1711 TRACE_(chain)("valid from %s to %s\n",
1712 filetime_to_str(&cert->pCertInfo->NotBefore),
1713 filetime_to_str(&cert->pCertInfo->NotAfter));
1714 TRACE_(chain)("%ld extensions\n", cert->pCertInfo->cExtension);
1715 for (i = 0; i < cert->pCertInfo->cExtension; i++)
1716 dump_extension(&cert->pCertInfo->rgExtension[i]);
1717}
static void dump_extension(const CERT_EXTENSION *ext)
Definition: chain.c:1643
DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT cert, DWORD type, DWORD flags, void *type_para, LPWSTR name_string, DWORD name_len)
Definition: str.c:1013
GLenum GLsizei len
Definition: glext.h:6722
short WCHAR
Definition: pedump.c:58
#define CERT_NAME_SIMPLE_DISPLAY_TYPE
Definition: wincrypt.h:3658
#define CERT_NAME_ISSUER_FLAG
Definition: wincrypt.h:3664

Referenced by CRYPT_CheckSimpleChain().

◆ dump_enhanced_key_usage()

static void dump_enhanced_key_usage ( const CERT_EXTENSION ext)
static

Definition at line 1599 of file chain.c.

1600{
1602 DWORD size;
1603
1605 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
1606 &usage, &size))
1607 {
1608 DWORD i;
1609
1610 TRACE_(chain)("%ld usages:\n", usage->cUsageIdentifier);
1611 for (i = 0; i < usage->cUsageIdentifier; i++)
1612 TRACE_(chain)("%s\n", usage->rgpszUsageIdentifier[i]);
1614 }
1615}

Referenced by dump_extension().

◆ dump_extension()

static void dump_extension ( const CERT_EXTENSION ext)
static

Definition at line 1643 of file chain.c.

1644{
1645 TRACE_(chain)("%s (%scritical)\n", debugstr_a(ext->pszObjId),
1646 ext->fCritical ? "" : "not ");
1647 if (!strcmp(ext->pszObjId, szOID_SUBJECT_ALT_NAME))
1648 dump_alt_name("subject alt name", ext);
1649 else if (!strcmp(ext->pszObjId, szOID_ISSUER_ALT_NAME))
1650 dump_alt_name("issuer alt name", ext);
1651 else if (!strcmp(ext->pszObjId, szOID_BASIC_CONSTRAINTS))
1653 else if (!strcmp(ext->pszObjId, szOID_KEY_USAGE))
1655 else if (!strcmp(ext->pszObjId, szOID_SUBJECT_ALT_NAME2))
1656 dump_alt_name("subject alt name 2", ext);
1657 else if (!strcmp(ext->pszObjId, szOID_ISSUER_ALT_NAME2))
1658 dump_alt_name("issuer alt name 2", ext);
1659 else if (!strcmp(ext->pszObjId, szOID_BASIC_CONSTRAINTS2))
1661 else if (!strcmp(ext->pszObjId, szOID_NAME_CONSTRAINTS))
1663 else if (!strcmp(ext->pszObjId, szOID_CERT_POLICIES))
1665 else if (!strcmp(ext->pszObjId, szOID_ENHANCED_KEY_USAGE))
1667 else if (!strcmp(ext->pszObjId, szOID_NETSCAPE_CERT_TYPE))
1669}
static void dump_netscape_cert_type(const CERT_EXTENSION *ext)
Definition: chain.c:1617
static void dump_basic_constraints(const CERT_EXTENSION *ext)
Definition: chain.c:1480
static void dump_key_usage(const CERT_EXTENSION *ext)
Definition: chain.c:1514
static void dump_enhanced_key_usage(const CERT_EXTENSION *ext)
Definition: chain.c:1599
static void dump_basic_constraints2(const CERT_EXTENSION *ext)
Definition: chain.c:1497
static void dump_alt_name(LPCSTR type, const CERT_EXTENSION *ext)
Definition: chain.c:1461
static void dump_name_constraints(const CERT_EXTENSION *ext)
Definition: chain.c:1548
static void dump_cert_policies(const CERT_EXTENSION *ext)
Definition: chain.c:1572
#define szOID_ISSUER_ALT_NAME2
Definition: wincrypt.h:3344
#define szOID_NETSCAPE_CERT_TYPE
Definition: wincrypt.h:3496
#define szOID_ISSUER_ALT_NAME
Definition: wincrypt.h:3337

Referenced by dump_element().

◆ dump_general_subtree()

static void dump_general_subtree ( const CERT_GENERAL_SUBTREE subtree)
static

Definition at line 1541 of file chain.c.

1542{
1543 dump_alt_name_entry(&subtree->Base);
1544 TRACE_(chain)("dwMinimum = %ld, fMaximum = %d, dwMaximum = %ld\n",
1545 subtree->dwMinimum, subtree->fMaximum, subtree->dwMaximum);
1546}

Referenced by dump_name_constraints().

◆ dump_key_usage()

static void dump_key_usage ( const CERT_EXTENSION ext)
static

Definition at line 1514 of file chain.c.

1515{
1517 DWORD size = sizeof(usage);
1518
1520 ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL, &usage, &size))
1521 {
1522#define trace_usage_bit(bits, bit) \
1523 if ((bits) & (bit)) TRACE_(chain)("%s\n", #bit)
1524 if (usage.cbData)
1525 {
1534 }
1535#undef trace_usage_bit
1536 if (usage.cbData > 1 && usage.pbData[1] & CERT_DECIPHER_ONLY_KEY_USAGE)
1537 TRACE_(chain)("CERT_DECIPHER_ONLY_KEY_USAGE\n");
1538 }
1539}
#define trace_usage_bit(bits, bit)
#define CERT_KEY_ENCIPHERMENT_KEY_USAGE
Definition: wincrypt.h:315
#define CERT_NON_REPUDIATION_KEY_USAGE
Definition: wincrypt.h:314
#define CERT_CRL_SIGN_KEY_USAGE
Definition: wincrypt.h:320
#define CERT_DIGITAL_SIGNATURE_KEY_USAGE
Definition: wincrypt.h:313
#define CERT_ENCIPHER_ONLY_KEY_USAGE
Definition: wincrypt.h:321
#define CERT_DECIPHER_ONLY_KEY_USAGE
Definition: wincrypt.h:323
#define CERT_KEY_AGREEMENT_KEY_USAGE
Definition: wincrypt.h:317
#define CERT_DATA_ENCIPHERMENT_KEY_USAGE
Definition: wincrypt.h:316

Referenced by dump_extension().

◆ dump_name_constraints()

static void dump_name_constraints ( const CERT_EXTENSION ext)
static

Definition at line 1548 of file chain.c.

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

Referenced by dump_extension().

◆ dump_netscape_cert_type()

static void dump_netscape_cert_type ( const CERT_EXTENSION ext)
static

Definition at line 1617 of file chain.c.

1618{
1620 DWORD size = sizeof(usage);
1621
1623 ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL, &usage, &size))
1624 {
1625#define trace_cert_type_bit(bits, bit) \
1626 if ((bits) & (bit)) TRACE_(chain)("%s\n", #bit)
1627 if (usage.cbData)
1628 {
1629 trace_cert_type_bit(usage.pbData[0],
1631 trace_cert_type_bit(usage.pbData[0],
1638 }
1639#undef trace_cert_type_bit
1640 }
1641}
#define trace_cert_type_bit(bits, bit)
#define NETSCAPE_SSL_CA_CERT_TYPE
Definition: wincrypt.h:3512
#define NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE
Definition: wincrypt.h:3509
#define NETSCAPE_SIGN_CERT_TYPE
Definition: wincrypt.h:3511
#define NETSCAPE_SIGN_CA_CERT_TYPE
Definition: wincrypt.h:3514
#define NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE
Definition: wincrypt.h:3508
#define NETSCAPE_SMIME_CERT_TYPE
Definition: wincrypt.h:3510
#define NETSCAPE_SMIME_CA_CERT_TYPE
Definition: wincrypt.h:3513

Referenced by dump_extension().

◆ dump_policy_para()

static void dump_policy_para ( PCERT_CHAIN_POLICY_PARA  para)
static

Definition at line 3796 of file chain.c.

3797{
3798 if (para)
3799 {
3800 TRACE_(chain)("cbSize = %ld\n", para->cbSize);
3801 TRACE_(chain)("dwFlags = %08lx\n", para->dwFlags);
3802 TRACE_(chain)("pvExtraPolicyPara = %p\n", para->pvExtraPolicyPara);
3803 }
3804}

Referenced by CertVerifyCertificateChainPolicy().

◆ dump_ssl_extra_chain_policy_para()

static void dump_ssl_extra_chain_policy_para ( HTTPSPolicyCallbackData sslPara)
static

Definition at line 3438 of file chain.c.

3439{
3440 if (sslPara)
3441 {
3442 TRACE_(chain)("cbSize = %ld\n", sslPara->cbSize);
3443 TRACE_(chain)("dwAuthType = %ld\n", sslPara->dwAuthType);
3444 TRACE_(chain)("fdwChecks = %08lx\n", sslPara->fdwChecks);
3445 TRACE_(chain)("pwszServerName = %s\n",
3446 debugstr_w(sslPara->pwszServerName));
3447 }
3448}

Referenced by verify_ssl_policy().

◆ dump_usage_match()

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

Definition at line 2847 of file chain.c.

2848{
2849 if (usageMatch->Usage.cUsageIdentifier)
2850 {
2851 DWORD i;
2852
2853 TRACE_(chain)("%s: %s\n", name,
2854 usageMatch->dwType == USAGE_MATCH_TYPE_AND ? "AND" : "OR");
2855 for (i = 0; i < usageMatch->Usage.cUsageIdentifier; i++)
2856 TRACE_(chain)("%s\n", usageMatch->Usage.rgpszUsageIdentifier[i]);
2857 }
2858}

Referenced by dump_chain_para().

◆ filetime_to_str()

static LPCSTR filetime_to_str ( const FILETIME time)
static

Definition at line 1671 of file chain.c.

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

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 2978 of file chain.c.

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

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,
const WCHAR component,
size_t  len 
)
static

Definition at line 3213 of file chain.c.

3215{
3216 DWORD i, j;
3217
3218 for (i = 0; i < name->cRDN; i++)
3219 for (j = 0; j < name->rgRDN[i].cRDNAttr; j++)
3221 name->rgRDN[i].rgRDNAttr[j].pszObjId))
3222 {
3223 const CERT_RDN_ATTR *attr;
3224
3225 attr = &name->rgRDN[i].rgRDNAttr[j];
3226 /* Compare with wcsnicmp rather than wcsicmp in order to avoid
3227 * a match with a string with an embedded NULL. The component
3228 * must match one domain component attribute's entire string
3229 * value with a case-insensitive match.
3230 */
3231 if ((len == attr->Value.cbData / sizeof(WCHAR)) &&
3232 !wcsnicmp(component, (LPCWSTR)attr->Value.pbData, len))
3233 return TRUE;
3234 }
3235 return FALSE;
3236}
#define wcsnicmp
Definition: compat.h:14
Definition: cookie.c:202
#define szOID_DOMAIN_COMPONENT
Definition: wincrypt.h:3361

Referenced by match_dns_to_subject_dn().

◆ free_chain_engine()

static void free_chain_engine ( CertificateChainEngine engine)
static

Definition at line 197 of file chain.c.

198{
199 if(!engine || InterlockedDecrement(&engine->ref))
200 return;
201
202 CertCloseStore(engine->hWorld, 0);
203 CertCloseStore(engine->hRoot, 0);
204 CryptMemFree(engine);
205}

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 162 of file chain.c.

163{
164 const CERT_CHAIN_ENGINE_CONFIG config = { sizeof(config) };
165
167 if(!allow_default)
168 return NULL;
169
170 if(!default_cu_engine) {
175 }
176
177 return default_cu_engine;
178 }
179
181 if(!allow_default)
182 return NULL;
183
184 if(!default_lm_engine) {
189 }
190
191 return default_lm_engine;
192 }
193
195}
struct config_s config
void WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine)
Definition: chain.c:245
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
#define HCCE_CURRENT_USER
Definition: wincrypt.h:3773
#define HCCE_LOCAL_MACHINE
Definition: wincrypt.h:3774
#define CERT_SYSTEM_STORE_LOCAL_MACHINE
Definition: wincrypt.h:2530

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 951 of file chain.c.

952{
954
956 cert->cExtension, cert->rgExtension);
957 if (!ext)
959 cert->cExtension, cert->rgExtension);
960 return ext;
961}

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 816 of file chain.c.

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

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

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 3145 of file chain.c.

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

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 3375 of file chain.c.

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

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 3238 of file chain.c.

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

Referenced by match_common_name().

◆ name_value_to_str()

static LPWSTR name_value_to_str ( const CERT_NAME_BLOB name)
static

Definition at line 1406 of file chain.c.

1407{
1410 LPWSTR str = NULL;
1411
1412 if (len)
1413 {
1414 str = CryptMemAlloc(len * sizeof(WCHAR));
1415 if (str)
1418 }
1419 return str;
1420}
DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indent, const CERT_NAME_BLOB *pName, DWORD dwStrType, LPWSTR psz, DWORD csz)
Definition: str.c:336
#define CERT_SIMPLE_NAME_STR
Definition: wincrypt.h:3642

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 1013 of file chain.c.

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

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 1031 of file chain.c.

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

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 747 of file chain.c.

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

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 678 of file chain.c.

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

3089{
3090 BOOL ret = verify_base_policy(szPolicyOID, pChainContext, pPolicyPara,
3091 pPolicyStatus);
3093
3094 if (pPolicyPara)
3095 extraPara = pPolicyPara->pvExtraPolicyPara;
3096 if (TRACE_ON(chain))
3098 if (ret && pPolicyStatus->dwError == CERT_E_UNTRUSTEDROOT)
3099 {
3100 CERT_PUBLIC_KEY_INFO msPubKey = { { 0 } };
3101 BOOL isMSTestRoot = FALSE;
3102 PCCERT_CONTEXT failingCert =
3103 pChainContext->rgpChain[pPolicyStatus->lChainIndex]->
3104 rgpElement[pPolicyStatus->lElementIndex]->pCertContext;
3105 DWORD i;
3106 CRYPT_DATA_BLOB keyBlobs[] = {
3107 { sizeof(msTestPubKey1), msTestPubKey1 },
3108 { sizeof(msTestPubKey2), msTestPubKey2 },
3109 };
3110
3111 /* Check whether the root is an MS test root */
3112 for (i = 0; !isMSTestRoot && i < ARRAY_SIZE(keyBlobs); i++)
3113 {
3114 msPubKey.PublicKey.cbData = keyBlobs[i].cbData;
3115 msPubKey.PublicKey.pbData = keyBlobs[i].pbData;
3118 &failingCert->pCertInfo->SubjectPublicKeyInfo, &msPubKey))
3119 isMSTestRoot = TRUE;
3120 }
3121 if (isMSTestRoot)
3122 pPolicyStatus->dwError = CERT_E_UNTRUSTEDTESTROOT;
3123 }
3124 return ret;
3125}
BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pPublicKey1, PCERT_PUBLIC_KEY_INFO pPublicKey2)
Definition: cert.c:1314
static BYTE msTestPubKey2[]
Definition: chain.c:3067
static void dump_authenticode_extra_chain_policy_para(AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA *extraPara)
Definition: chain.c:3074
static BYTE msTestPubKey1[]
Definition: chain.c:3061
CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo
Definition: wincrypt.h:257
CRYPT_BIT_BLOB PublicKey
Definition: wincrypt.h:235
BYTE * pbData
Definition: wincrypt.h:206
#define PKCS_7_ASN_ENCODING
Definition: wincrypt.h:2503
#define CERT_E_UNTRUSTEDROOT
Definition: winerror.h:4639
#define CERT_E_UNTRUSTEDTESTROOT
Definition: winerror.h:4643

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 2994 of file chain.c.

2997{
2998 DWORD checks = 0;
2999
3000 if (pPolicyPara)
3001 checks = pPolicyPara->dwFlags;
3002 pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = -1;
3003 pPolicyStatus->dwError = NO_ERROR;
3004 if (pChainContext->TrustStatus.dwErrorStatus &
3006 {
3007 pPolicyStatus->dwError = TRUST_E_CERT_SIGNATURE;
3008 find_element_with_error(pChainContext,
3010 &pPolicyStatus->lElementIndex);
3011 }
3012 else if (pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_CYCLIC)
3013 {
3014 pPolicyStatus->dwError = CERT_E_CHAINING;
3016 &pPolicyStatus->lChainIndex, &pPolicyStatus->lElementIndex);
3017 /* For a cyclic chain, which element is a cycle isn't meaningful */
3018 pPolicyStatus->lElementIndex = -1;
3019 }
3020 if (!pPolicyStatus->dwError &&
3023 {
3024 pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT;
3025 find_element_with_error(pChainContext,
3027 &pPolicyStatus->lElementIndex);
3028 }
3029 if (!pPolicyStatus->dwError &&
3032 {
3033 pPolicyStatus->dwError = CERT_E_EXPIRED;
3034 find_element_with_error(pChainContext,
3036 &pPolicyStatus->lElementIndex);
3037 }
3038 if (!pPolicyStatus->dwError &&
3039 pChainContext->TrustStatus.dwErrorStatus &
3042 {
3043 pPolicyStatus->dwError = CERT_E_WRONG_USAGE;
3044 find_element_with_error(pChainContext,
3046 &pPolicyStatus->lElementIndex);
3047 }
3048 if (!pPolicyStatus->dwError &&
3049 pChainContext->TrustStatus.dwErrorStatus &
3052 {
3053 pPolicyStatus->dwError = CERT_E_CRITICAL;
3054 find_element_with_error(pChainContext,
3056 &pPolicyStatus->lElementIndex);
3057 }
3058 return TRUE;
3059}
#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:2978
#define CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG
Definition: wincrypt.h:1092
#define CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG
Definition: wincrypt.h:1093
#define CERT_CHAIN_POLICY_IGNORE_NOT_SUPPORTED_CRITICAL_EXT_FLAG
Definition: wincrypt.h:1109
#define CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG
Definition: wincrypt.h:1082
#define CERT_E_CHAINING
Definition: winerror.h:4640
#define CERT_E_WRONG_USAGE
Definition: winerror.h:4646
#define TRUST_E_CERT_SIGNATURE
Definition: winerror.h:4588
#define CERT_E_CRITICAL
Definition: winerror.h:4635
#define CERT_E_EXPIRED
Definition: winerror.h:4631

Referenced by CertVerifyCertificateChainPolicy(), and verify_authenticode_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 3127 of file chain.c.

3130{
3131 pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = -1;
3132 if (pChainContext->TrustStatus.dwErrorStatus &
3134 {
3135 pPolicyStatus->dwError = TRUST_E_BASIC_CONSTRAINTS;
3136 find_element_with_error(pChainContext,
3138 &pPolicyStatus->lElementIndex);
3139 }
3140 else
3141 pPolicyStatus->dwError = NO_ERROR;
3142 return TRUE;
3143}
#define TRUST_E_BASIC_CONSTRAINTS
Definition: winerror.h:4592

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 3738 of file chain.c.

3741{
3742 BOOL isMSRoot = FALSE;
3743
3744 CERT_PUBLIC_KEY_INFO msPubKey = { { 0 } };
3745 DWORD i;
3746 static const CRYPT_DATA_BLOB keyBlobs[] = {
3747 { sizeof(msPubKey1), msPubKey1 },
3748 { sizeof(msPubKey2), msPubKey2 },
3749 { sizeof(msPubKey3), msPubKey3 },
3750 { sizeof(msPubKey4), msPubKey4 },
3751 };
3752 static const CRYPT_DATA_BLOB keyBlobs_approot[] = {
3753 { sizeof(msPubKey5), msPubKey5 },
3754 };
3755 PCERT_SIMPLE_CHAIN rootChain =
3756 pChainContext->rgpChain[pChainContext->cChain - 1];
3758 rootChain->rgpElement[rootChain->cElement - 1]->pCertContext;
3759
3760 const CRYPT_DATA_BLOB *keys;
3761 unsigned int key_count;
3762
3764 {
3765 keys = keyBlobs_approot;
3766 key_count = ARRAY_SIZE(keyBlobs_approot);
3767 }
3768 else
3769 {
3770 keys = keyBlobs;
3771 key_count = ARRAY_SIZE(keyBlobs);
3772 }
3773
3774 for (i = 0; !isMSRoot && i < key_count; i++)
3775 {
3776 msPubKey.PublicKey.cbData = keys[i].cbData;
3777 msPubKey.PublicKey.pbData = keys[i].pbData;
3779 &root->pCertInfo->SubjectPublicKeyInfo, &msPubKey)) isMSRoot = TRUE;
3780 }
3781
3782 pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = 0;
3783
3784 if (isMSRoot)
3785 pPolicyStatus->dwError = 0;
3786 else
3787 pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT;
3788
3789 return TRUE;
3790}
static BYTE msPubKey3[]
Definition: chain.c:3624
static BYTE msPubKey4[]
Definition: chain.c:3662
static BYTE msPubKey5[]
Definition: chain.c:3700
static BYTE msPubKey2[]
Definition: chain.c:3605
static BYTE msPubKey1[]
Definition: chain.c:3586
const UINT * keys
Definition: locale.c:418
PCERT_CHAIN_ELEMENT * rgpElement
Definition: wincrypt.h:1040
#define MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG
Definition: wincrypt.h:1113

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 3450 of file chain.c.

3453{
3454 HTTPSPolicyCallbackData *sslPara = NULL;
3455 DWORD checks = 0, baseChecks = 0;
3456
3457 if (pPolicyPara)
3458 {
3459 baseChecks = pPolicyPara->dwFlags;
3460 sslPara = pPolicyPara->pvExtraPolicyPara;
3461 }
3462 if (TRACE_ON(chain))
3464 if (sslPara && sslPara->cbSize >= sizeof(HTTPSPolicyCallbackData))
3465 checks = sslPara->fdwChecks;
3466 pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = -1;
3467 if (pChainContext->TrustStatus.dwErrorStatus &
3469 {
3470 pPolicyStatus->dwError = TRUST_E_CERT_SIGNATURE;
3471 find_element_with_error(pChainContext,
3473 &pPolicyStatus->lElementIndex);
3474 }
3475 else if (pChainContext->TrustStatus.dwErrorStatus &
3477 !(checks & SECURITY_FLAG_IGNORE_UNKNOWN_CA) &&
3479 {
3480 pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT;
3481 find_element_with_error(pChainContext,
3483 &pPolicyStatus->lElementIndex);
3484 }
3485 else if (pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_CYCLIC)
3486 {
3487 pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT;
3488 find_element_with_error(pChainContext,
3489 CERT_TRUST_IS_CYCLIC, &pPolicyStatus->lChainIndex,
3490 &pPolicyStatus->lElementIndex);
3491 /* For a cyclic chain, which element is a cycle isn't meaningful */
3492 pPolicyStatus->lElementIndex = -1;
3493 }
3494 else if (pChainContext->TrustStatus.dwErrorStatus &
3498 {
3499 pPolicyStatus->dwError = CERT_E_EXPIRED;
3500 find_element_with_error(pChainContext,
3502 &pPolicyStatus->lElementIndex);
3503 }
3504 else if (pChainContext->TrustStatus.dwErrorStatus &
3507 {
3508 pPolicyStatus->dwError = CERT_E_WRONG_USAGE;
3509 find_element_with_error(pChainContext,
3511 &pPolicyStatus->lElementIndex);
3512 }
3513 else if (pChainContext->TrustStatus.dwErrorStatus &
3515 {
3516 pPolicyStatus->dwError = CERT_E_REVOKED;
3517 find_element_with_error(pChainContext,
3518 CERT_TRUST_IS_REVOKED, &pPolicyStatus->lChainIndex,
3519 &pPolicyStatus->lElementIndex);
3520 }
3521 else if (pChainContext->TrustStatus.dwErrorStatus &
3524 {
3525 pPolicyStatus->dwError = CERT_E_REVOCATION_FAILURE;
3526 find_element_with_error(pChainContext,
3528 &pPolicyStatus->lElementIndex);
3529 }
3530 else if (pChainContext->TrustStatus.dwErrorStatus &
3532 {
3533 pPolicyStatus->dwError = CERT_E_CRITICAL;
3534 find_element_with_error(pChainContext,
3536 &pPolicyStatus->lElementIndex);
3537 }
3538 else
3539 pPolicyStatus->dwError = NO_ERROR;
3540 /* We only need bother checking whether the name in the end certificate
3541 * matches if the chain is otherwise okay.
3542 */
3543 if (!pPolicyStatus->dwError && pPolicyPara &&
3544 pPolicyPara->cbSize >= sizeof(CERT_CHAIN_POLICY_PARA))
3545 {
3546 if (sslPara && sslPara->cbSize >= sizeof(HTTPSPolicyCallbackData))
3547 {
3548 if (sslPara->dwAuthType == AUTHTYPE_SERVER &&
3549 sslPara->pwszServerName &&
3551 {
3553 PCERT_EXTENSION altNameExt;
3554 BOOL matches;
3555
3556 cert = pChainContext->rgpChain[0]->rgpElement[0]->pCertContext;
3557 altNameExt = get_subject_alt_name_ext(cert->pCertInfo);
3558 /* If the alternate name extension exists, the name it contains
3559 * is bound to the certificate, so make sure the name matches
3560 * it. Otherwise, look for the server name in the subject
3561 * distinguished name. RFC5280, section 4.2.1.6:
3562 * "Whenever such identities are to be bound into a
3563 * certificate, the subject alternative name (or issuer
3564 * alternative name) extension MUST be used; however, a DNS
3565 * name MAY also be represented in the subject field using the
3566 * domainComponent attribute."
3567 */
3568 if (altNameExt)
3570 sslPara->pwszServerName);
3571 else
3573 sslPara->pwszServerName);
3574 if (!matches)
3575 {
3576 pPolicyStatus->dwError = CERT_E_CN_NO_MATCH;
3577 pPolicyStatus->lChainIndex = 0;
3578 pPolicyStatus->lElementIndex = 0;
3579 }
3580 }
3581 }
3582 }
3583 return TRUE;
3584}
static BOOL match_dns_to_subject_alt_name(const CERT_EXTENSION *ext, LPCWSTR server_name)
Definition: chain.c:3145
static void dump_ssl_extra_chain_policy_para(HTTPSPolicyCallbackData *sslPara)
Definition: chain.c:3438
static BOOL match_dns_to_subject_dn(PCCERT_CONTEXT cert, LPCWSTR server_name)
Definition: chain.c:3375
#define AUTHTYPE_SERVER
Definition: wincrypt.h:1148
#define CERT_E_REVOCATION_FAILURE
Definition: winerror.h:4644
#define CERT_E_REVOKED
Definition: winerror.h:4642
#define CERT_E_CN_NO_MATCH
Definition: winerror.h:4645
#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
Definition: winhttp.h:344
#define SECURITY_FLAG_IGNORE_UNKNOWN_CA
Definition: winhttp.h:343
#define SECURITY_FLAG_IGNORE_CERT_CN_INVALID
Definition: winhttp.h:345
#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 160 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 160 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 3586 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 3605 of file chain.c.

Referenced by verify_ms_root_policy().

◆ msPubKey3

BYTE msPubKey3[]
static

Definition at line 3624 of file chain.c.

Referenced by verify_ms_root_policy().

◆ msPubKey4

BYTE msPubKey4[]
static

Definition at line 3662 of file chain.c.

Referenced by verify_ms_root_policy().

◆ msPubKey5

BYTE msPubKey5[]
static

Definition at line 3700 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 3061 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 3067 of file chain.c.

Referenced by verify_authenticode_policy().