diff --git a/src/utils/cryptopro.c b/src/utils/cryptopro.c index 11f667d..6e99b07 100644 --- a/src/utils/cryptopro.c +++ b/src/utils/cryptopro.c @@ -79,6 +79,18 @@ error: return -1; } +static void +free_cert_chain(PCCERT_CHAIN_CONTEXT chain_ctx) +{ + LOG_TRACE("free_cert_chain enter"); + + if (chain_ctx) { + cp_function_list.CertFreeCertificateChain(chain_ctx); + } + + LOG_TRACE("free_cert_chain exit"); +} + static PCCERT_CHAIN_CONTEXT get_cert_chain(PCCERT_CONTEXT certificate) { @@ -95,16 +107,27 @@ get_cert_chain(PCCERT_CONTEXT certificate) NULL, NULL, &chain_para, - (CERT_CHAIN_CACHE_END_CERT | CERT_CHAIN_REVOCATION_CHECK_END_CERT), + (CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT), NULL, &chain_ctx)) { LOG_ERROR("CertGetCertificateChain() failed"); - LOG_ERROR("get_cert_chain exit with error"); - return NULL; + goto error; + } + LOG_DEBUG("Trust error status: '0x%08x'", chain_ctx->TrustStatus.dwErrorStatus); + LOG_DEBUG("Trust info status: '0x%08x'", chain_ctx->TrustStatus.dwInfoStatus); + if (chain_ctx->TrustStatus.dwErrorStatus) { + LOG_WARN("The certificate is not trusted. CERT_TRUST_STATUS: '0x%08x'", + chain_ctx->TrustStatus.dwErrorStatus); + goto error; } LOG_TRACE("get_cert_chain exit"); return chain_ctx; + +error: + free_cert_chain(chain_ctx); + LOG_ERROR("get_cert_chain exit with error"); + return NULL; } static const char* @@ -127,6 +150,8 @@ check_cert_chain_policy(PCCERT_CHAIN_CONTEXT chain_ctx) { LOG_TRACE("check_cert_chain_policy enter"); + bool is_valid = false; + CERT_CHAIN_POLICY_PARA policy_para = {0}; policy_para.cbSize = sizeof(policy_para); @@ -144,33 +169,30 @@ check_cert_chain_policy(PCCERT_CHAIN_CONTEXT chain_ctx) chain_ctx, &policy_para, &status)) { - LOG_ERROR("CertVerifyCertificateChainPolicy() failed"); - LOG_ERROR("check_cert_chain_policy exit with error"); - return false; + LOG_ERROR("CertVerifyCertificateChainPolicy() failed. Error code: 0x%08x", + cp_function_list.GetLastError()); + goto exit; } if (status.dwError != 0) { LOG_WARN("The certificate chain cannot be validated. " "CertVerifyCertificateChainPolicy status: %s('0x%08x')", get_cert_chain_policy_status_error_desc(status.dwError), status.dwError); - LOG_TRACE("check_cert_chain_policy exit"); - return false; + goto exit; } + if (extraStatus.dwError != 0) { + LOG_WARN("The certificate chain cannot be validated. " + "CertVerifyCertificateChainPolicy extra status: %s('0x%08x')", + get_cert_chain_policy_status_error_desc(status.dwError), status.dwError); + goto exit; + } + + is_valid = true; + +exit: LOG_TRACE("check_cert_chain_policy exit"); - return true; -} - -static void -free_cert_chain(PCCERT_CHAIN_CONTEXT chain_ctx) -{ - LOG_TRACE("free_cert_chain enter"); - - if (chain_ctx) { - cp_function_list.CertFreeCertificateChain(chain_ctx); - } - - LOG_TRACE("free_cert_chain exit"); + return is_valid; } static bool